gtkstyle.c 137 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GTK - The GIMP Toolkit
Elliot Lee's avatar
Elliot Lee committed
2
3
4
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
Elliot Lee's avatar
Elliot Lee committed
6
7
8
9
10
11
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
Elliot Lee's avatar
Elliot Lee committed
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
Javier Jardón's avatar
Javier Jardón committed
15
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
Elliot Lee's avatar
Elliot Lee committed
16
 */
17
18

/*
19
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
20
21
22
23
24
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

25
#include "config.h"
26
27
28

#define GDK_DISABLE_DEPRECATION_WARNINGS

Elliot Lee's avatar
Elliot Lee committed
29
#include <math.h>
30
#include <stdlib.h>
31
#include <string.h>
32
#include <gobject/gvaluecollector.h>
33
#include "gtkmarshalers.h"
34
#include "gtkpango.h"
35
#include "gtkrc.h"
36
#include "gtkspinbutton.h"
Elliot Lee's avatar
Elliot Lee committed
37
#include "gtkstyle.h"
38
#include "gtkstylecontextprivate.h"
39
#include "gtkwidget.h"
40
#include "gtkwidgetprivate.h"
41
#include "gtkiconfactory.h"
Matthias Clasen's avatar
Matthias Clasen committed
42
#include "gtkintl.h"
Matthias Clasen's avatar
Matthias Clasen committed
43
#include "gtkdebug.h"
44
#include "gtkrender.h"
Matthias Clasen's avatar
Matthias Clasen committed
45
#include "gtkborder.h"
46
#include "gtkwidgetpath.h"
Elliot Lee's avatar
Elliot Lee committed
47

48
49
/**
 * SECTION:gtkstyle
Matthias Clasen's avatar
Matthias Clasen committed
50
51
 * @Short_description: Deprecated object that holds style information
 *     for widgets
52
53
54
 * @Title: GtkStyle
 *
 * A #GtkStyle object encapsulates the information that provides the look and
Matthias Clasen's avatar
Matthias Clasen committed
55
 * feel for a widget.
Matthias Clasen's avatar
Matthias Clasen committed
56
 *
William Jon McCann's avatar
William Jon McCann committed
57
58
 * > In GTK+ 3.0, GtkStyle has been deprecated and replaced by
 * > #GtkStyleContext.
Matthias Clasen's avatar
Matthias Clasen committed
59
60
61
62
63
64
65
66
67
68
69
 *
 * Each #GtkWidget has an associated #GtkStyle object that is used when
 * rendering that widget. Also, a #GtkStyle holds information for the five
 * possible widget states though not every widget supports all five
 * states; see #GtkStateType.
 *
 * Usually the #GtkStyle for a widget is the same as the default style that
 * is set by GTK+ and modified the theme engine.
 *
 * Usually applications should not need to use or modify the #GtkStyle of
 * their widgets.
70
71
72
 */


Elliot Lee's avatar
Elliot Lee committed
73
74
75
#define LIGHTNESS_MULT  1.3
#define DARKNESS_MULT   0.7

76
77
78
79
80
81
82
/* --- typedefs & structures --- */
typedef struct {
  GType       widget_type;
  GParamSpec *pspec;
  GValue      value;
} PropertyValue;

83
typedef struct {
84
  GtkStyleContext *context;
85
  gulong context_changed_id;
86
87
88
} GtkStylePrivate;

#define GTK_STYLE_GET_PRIVATE(obj) ((GtkStylePrivate *) gtk_style_get_instance_private ((GtkStyle *) (obj)))
89
90
91
92

enum {
  PROP_0,
  PROP_CONTEXT
93
94
};

95
96
/* --- prototypes --- */
static void	 gtk_style_finalize		(GObject	*object);
97
98
99
100
101
static void	 gtk_style_constructed		(GObject	*object);
static void      gtk_style_set_property         (GObject        *object,
                                                 guint           prop_id,
                                                 const GValue   *value,
                                                 GParamSpec     *pspec);
102
103
104
105
static void      gtk_style_get_property         (GObject        *object,
                                                 guint           prop_id,
                                                 GValue         *value,
                                                 GParamSpec     *pspec);
106

107
108
109
110
111
112
113
114
115
116
static void      gtk_style_real_realize        (GtkStyle	*style);
static void      gtk_style_real_unrealize      (GtkStyle	*style);
static void      gtk_style_real_copy           (GtkStyle	*style,
						GtkStyle	*src);
static void      gtk_style_real_set_background (GtkStyle	*style,
						GdkWindow	*window,
						GtkStateType	 state_type);
static GtkStyle *gtk_style_real_clone          (GtkStyle	*style);
static void      gtk_style_real_init_from_rc   (GtkStyle	*style,
                                                GtkRcStyle	*rc_style);
117
118
119
120
static GdkPixbuf *gtk_default_render_icon      (GtkStyle            *style,
                                                const GtkIconSource *source,
                                                GtkTextDirection     direction,
                                                GtkStateType         state,
121
                                                GtkIconSize          size,
122
123
                                                GtkWidget           *widget,
                                                const gchar         *detail);
124
static void gtk_default_draw_hline      (GtkStyle        *style,
125
					 cairo_t         *cr,
126
127
128
129
130
131
132
					 GtkStateType     state_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x1,
					 gint             x2,
					 gint             y);
static void gtk_default_draw_vline      (GtkStyle        *style,
133
					 cairo_t         *cr,
134
135
136
137
138
139
140
					 GtkStateType     state_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             y1,
					 gint             y2,
					 gint             x);
static void gtk_default_draw_shadow     (GtkStyle        *style,
141
					 cairo_t         *cr,
142
143
144
145
146
147
148
149
150
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height);
static void gtk_default_draw_arrow      (GtkStyle        *style,
151
					 cairo_t         *cr,
152
153
154
155
156
157
158
159
160
161
162
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 GtkArrowType     arrow_type,
					 gboolean         fill,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height);
static void gtk_default_draw_diamond    (GtkStyle        *style,
163
					 cairo_t         *cr,
164
165
166
167
168
169
170
171
172
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height);
static void gtk_default_draw_box        (GtkStyle        *style,
173
					 cairo_t         *cr,
174
175
176
177
178
179
180
181
182
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height);
static void gtk_default_draw_flat_box   (GtkStyle        *style,
183
					 cairo_t         *cr,
184
185
186
187
188
189
190
191
192
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height);
static void gtk_default_draw_check      (GtkStyle        *style,
193
					 cairo_t         *cr,
194
195
196
197
198
199
200
201
202
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height);
static void gtk_default_draw_option     (GtkStyle        *style,
203
					 cairo_t         *cr,
204
205
206
207
208
209
210
211
212
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height);
static void gtk_default_draw_tab        (GtkStyle        *style,
213
					 cairo_t         *cr,
214
215
216
217
218
219
220
221
222
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height);
static void gtk_default_draw_shadow_gap (GtkStyle        *style,
223
					 cairo_t         *cr,
224
225
226
227
228
229
230
231
232
233
234
235
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height,
					 GtkPositionType  gap_side,
					 gint             gap_x,
					 gint             gap_width);
static void gtk_default_draw_box_gap    (GtkStyle        *style,
236
					 cairo_t         *cr,
237
238
239
240
241
242
243
244
245
246
247
248
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height,
					 GtkPositionType  gap_side,
					 gint             gap_x,
					 gint             gap_width);
static void gtk_default_draw_extension  (GtkStyle        *style,
249
					 cairo_t         *cr,
250
251
252
253
254
255
256
257
258
259
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height,
					 GtkPositionType  gap_side);
static void gtk_default_draw_focus      (GtkStyle        *style,
260
					 cairo_t         *cr,
261
					 GtkStateType     state_type,
262
263
264
265
266
267
268
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height);
static void gtk_default_draw_slider     (GtkStyle        *style,
269
					 cairo_t         *cr,
270
271
272
273
274
275
276
277
278
279
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height,
					 GtkOrientation   orientation);
static void gtk_default_draw_handle     (GtkStyle        *style,
280
					 cairo_t         *cr,
281
282
283
284
285
286
287
288
289
					 GtkStateType     state_type,
					 GtkShadowType    shadow_type,
					 GtkWidget       *widget,
					 const gchar     *detail,
					 gint             x,
					 gint             y,
					 gint             width,
					 gint             height,
					 GtkOrientation   orientation);
290
static void gtk_default_draw_expander   (GtkStyle        *style,
291
                                         cairo_t         *cr,
292
293
294
295
296
                                         GtkStateType     state_type,
                                         GtkWidget       *widget,
                                         const gchar     *detail,
                                         gint             x,
                                         gint             y,
297
					 GtkExpanderStyle expander_style);
298
static void gtk_default_draw_layout     (GtkStyle        *style,
299
                                         cairo_t         *cr,
300
                                         GtkStateType     state_type,
301
					 gboolean         use_text,
302
303
304
305
306
                                         GtkWidget       *widget,
                                         const gchar     *detail,
                                         gint             x,
                                         gint             y,
                                         PangoLayout     *layout);
Owen Taylor's avatar
Owen Taylor committed
307
static void gtk_default_draw_resize_grip (GtkStyle       *style,
308
                                          cairo_t        *cr,
Owen Taylor's avatar
Owen Taylor committed
309
310
311
312
313
314
315
316
                                          GtkStateType    state_type,
                                          GtkWidget      *widget,
                                          const gchar    *detail,
                                          GdkWindowEdge   edge,
                                          gint            x,
                                          gint            y,
                                          gint            width,
                                          gint            height);
317
static void gtk_default_draw_spinner     (GtkStyle       *style,
318
                                          cairo_t        *cr,
319
320
321
322
323
324
325
326
					  GtkStateType    state_type,
                                          GtkWidget      *widget,
                                          const gchar    *detail,
					  guint           step,
					  gint            x,
					  gint            y,
					  gint            width,
					  gint            height);
Owen Taylor's avatar
Owen Taylor committed
327

328
329
330
331
332
333
334
static void rgb_to_hls			(gdouble	 *r,
					 gdouble	 *g,
					 gdouble	 *b);
static void hls_to_rgb			(gdouble	 *h,
					 gdouble	 *l,
					 gdouble	 *s);

335
336
337
static void transform_detail_string (const gchar     *detail,
                                     GtkStyleContext *context);

338
339
340
341
/*
 * Data for default check and radio buttons
 */

342
343
static const GtkRequisition default_option_indicator_size = { 7, 13 };
static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
344

Soeren Sandmann's avatar
Soeren Sandmann committed
345
346
347
348
349
350
351
352
#define GTK_GRAY		0xdcdc, 0xdada, 0xd5d5
#define GTK_DARK_GRAY		0xc4c4, 0xc2c2, 0xbdbd
#define GTK_LIGHT_GRAY		0xeeee, 0xebeb, 0xe7e7
#define GTK_WHITE		0xffff, 0xffff, 0xffff
#define GTK_BLUE		0x4b4b, 0x6969, 0x8383
#define GTK_VERY_DARK_GRAY	0x9c9c, 0x9a9a, 0x9494
#define GTK_BLACK		0x0000, 0x0000, 0x0000
#define GTK_WEAK_GRAY		0x7530, 0x7530, 0x7530
353

354
/* --- variables --- */
Soeren Sandmann's avatar
Soeren Sandmann committed
355
356
357
358
359
static const GdkColor gtk_default_normal_fg =      { 0, GTK_BLACK };
static const GdkColor gtk_default_active_fg =      { 0, GTK_BLACK };
static const GdkColor gtk_default_prelight_fg =    { 0, GTK_BLACK };
static const GdkColor gtk_default_selected_fg =    { 0, GTK_WHITE };
static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
360

Soeren Sandmann's avatar
Soeren Sandmann committed
361
362
363
364
365
366
367
static const GdkColor gtk_default_normal_bg =      { 0, GTK_GRAY };
static const GdkColor gtk_default_active_bg =      { 0, GTK_DARK_GRAY };
static const GdkColor gtk_default_prelight_bg =    { 0, GTK_LIGHT_GRAY };
static const GdkColor gtk_default_selected_bg =    { 0, GTK_BLUE };
static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
static const GdkColor gtk_default_selected_base =  { 0, GTK_BLUE };
static const GdkColor gtk_default_active_base =    { 0, GTK_VERY_DARK_GRAY };
Elliot Lee's avatar
Elliot Lee committed
368

369
370
static GQuark quark_default_style;

371
372
373
/* --- signals --- */
static guint realize_signal = 0;
static guint unrealize_signal = 0;
374

375
G_DEFINE_TYPE_WITH_PRIVATE (GtkStyle, gtk_style, G_TYPE_OBJECT)
Matthias Clasen's avatar
Matthias Clasen committed
376

377
/* --- functions --- */
Elliot Lee's avatar
Elliot Lee committed
378

379
380
381
382
static void
gtk_style_init (GtkStyle *style)
{
  gint i;
383
384
385

  style->font_desc = pango_font_description_from_string ("Sans 10");

Elliot Lee's avatar
Elliot Lee committed
386
  style->attach_count = 0;
387
  
Elliot Lee's avatar
Elliot Lee committed
388
389
390
  style->black.red = 0;
  style->black.green = 0;
  style->black.blue = 0;
391
  
Elliot Lee's avatar
Elliot Lee committed
392
393
394
  style->white.red = 65535;
  style->white.green = 65535;
  style->white.blue = 65535;
395
  
Elliot Lee's avatar
Elliot Lee committed
396
397
398
399
400
  style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
  style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
  style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
  style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
  style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
401
  
Elliot Lee's avatar
Elliot Lee committed
402
403
404
405
406
  style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
  style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
  style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
  style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
  style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
407
  
408
  for (i = 0; i < 4; i++)
Elliot Lee's avatar
Elliot Lee committed
409
410
411
412
    {
      style->text[i] = style->fg[i];
      style->base[i] = style->white;
    }
Havoc Pennington's avatar
Havoc Pennington committed
413

414
  style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
415
  style->text[GTK_STATE_SELECTED] = style->white;
416
  style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
417
  style->text[GTK_STATE_ACTIVE] = style->white;
Owen Taylor's avatar
Owen Taylor committed
418
419
  style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
  style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
420
  
421
  style->rc_style = NULL;
422
  
423
424
  style->xthickness = 2;
  style->ythickness = 2;
425
426

  style->property_cache = NULL;
427
428
429
430
431
432
433
434
}

static void
gtk_style_class_init (GtkStyleClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  
  object_class->finalize = gtk_style_finalize;
435
  object_class->set_property = gtk_style_set_property;
436
  object_class->get_property = gtk_style_get_property;
437
  object_class->constructed = gtk_style_constructed;
438

439
440
441
442
443
444
  klass->clone = gtk_style_real_clone;
  klass->copy = gtk_style_real_copy;
  klass->init_from_rc = gtk_style_real_init_from_rc;
  klass->realize = gtk_style_real_realize;
  klass->unrealize = gtk_style_real_unrealize;
  klass->set_background = gtk_style_real_set_background;
445
446
  klass->render_icon = gtk_default_render_icon;

447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
  klass->draw_hline = gtk_default_draw_hline;
  klass->draw_vline = gtk_default_draw_vline;
  klass->draw_shadow = gtk_default_draw_shadow;
  klass->draw_arrow = gtk_default_draw_arrow;
  klass->draw_diamond = gtk_default_draw_diamond;
  klass->draw_box = gtk_default_draw_box;
  klass->draw_flat_box = gtk_default_draw_flat_box;
  klass->draw_check = gtk_default_draw_check;
  klass->draw_option = gtk_default_draw_option;
  klass->draw_tab = gtk_default_draw_tab;
  klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
  klass->draw_box_gap = gtk_default_draw_box_gap;
  klass->draw_extension = gtk_default_draw_extension;
  klass->draw_focus = gtk_default_draw_focus;
  klass->draw_slider = gtk_default_draw_slider;
  klass->draw_handle = gtk_default_draw_handle;
463
464
  klass->draw_expander = gtk_default_draw_expander;
  klass->draw_layout = gtk_default_draw_layout;
Owen Taylor's avatar
Owen Taylor committed
465
  klass->draw_resize_grip = gtk_default_draw_resize_grip;
466
  klass->draw_spinner = gtk_default_draw_spinner;
467

468
469
470
471
472
473
  g_object_class_install_property (object_class,
				   PROP_CONTEXT,
				   g_param_spec_object ("context",
 							P_("Style context"),
							P_("GtkStyleContext to get style from"),
                                                        GTK_TYPE_STYLE_CONTEXT,
474
                                                        G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
475

476
477
478
479
480
  /**
   * GtkStyle::realize:
   * @style: the object which received the signal
   *
   * Emitted when the style has been initialized for a particular
481
   * visual. Connecting to this signal is probably seldom
482
483
   * useful since most of the time applications and widgets only
   * deal with styles that have been already realized.
484
485
   *
   * Since: 2.4
486
   */
Matthias Clasen's avatar
Matthias Clasen committed
487
  realize_signal = g_signal_new (I_("realize"),
488
489
490
491
				 G_TYPE_FROM_CLASS (object_class),
				 G_SIGNAL_RUN_FIRST,
				 G_STRUCT_OFFSET (GtkStyleClass, realize),
				 NULL, NULL,
492
				 NULL,
493
494
495
496
497
				 G_TYPE_NONE, 0);
  /**
   * GtkStyle::unrealize:
   * @style: the object which received the signal
   *
498
   * Emitted when the aspects of the style specific to a particular visual
499
   * is being cleaned up. A connection to this signal can be useful
500
   * if a widget wants to cache objects as object data on #GtkStyle.
501
   * This signal provides a convenient place to free such cached objects.
502
503
   *
   * Since: 2.4
504
   */
Matthias Clasen's avatar
Matthias Clasen committed
505
  unrealize_signal = g_signal_new (I_("unrealize"),
506
507
508
509
				   G_TYPE_FROM_CLASS (object_class),
				   G_SIGNAL_RUN_FIRST,
				   G_STRUCT_OFFSET (GtkStyleClass, unrealize),
				   NULL, NULL,
510
				   NULL,
511
				   G_TYPE_NONE, 0);
512
513
}

514
515
516
517
static void
gtk_style_finalize (GObject *object)
{
  GtkStyle *style = GTK_STYLE (object);
518
  GtkStylePrivate *priv = GTK_STYLE_GET_PRIVATE (style);
519
  gint i;
520
521
522

  g_return_if_fail (style->attach_count == 0);

Matthias Clasen's avatar
Matthias Clasen committed
523
524
525
526
527
528
529
  /* All the styles in the list have the same 
   * style->styles pointer. If we delete the 
   * *first* style from the list, we need to update
   * the style->styles pointers from all the styles.
   * Otherwise we simply remove the node from
   * the list.
   */
530
531
532
  if (style->styles)
    {
      if (style->styles->data != style)
533
        style->styles = g_slist_remove (style->styles, style);
534
535
536
537
538
539
      else
        {
          GSList *tmp_list = style->styles->next;
	  
          while (tmp_list)
            {
540
              GTK_STYLE (tmp_list->data)->styles = style->styles->next;
541
542
543
544
545
              tmp_list = tmp_list->next;
            }
          g_slist_free_1 (style->styles);
        }
    }
546

Matthias Clasen's avatar
Matthias Clasen committed
547
  g_slist_free_full (style->icon_factories, g_object_unref);
548

549
  pango_font_description_free (style->font_desc);
550
551
552

  if (style->private_font_desc)
    pango_font_description_free (style->private_font_desc);
553

554
  if (style->rc_style)
555
556
    g_object_unref (style->rc_style);

557
  if (priv->context)
558
559
560
561
562
563
    {
      if (priv->context_changed_id)
        g_signal_handler_disconnect (priv->context, priv->context_changed_id);

      g_object_unref (priv->context);
    }
564

565
566
567
568
569
570
  for (i = 0; i < 5; i++)
    {
      if (style->background[i])
        cairo_pattern_destroy (style->background[i]);
    }

Matthias Clasen's avatar
Matthias Clasen committed
571
  G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
572
573
}

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
static void
gtk_style_set_property (GObject      *object,
                        guint         prop_id,
                        const GValue *value,
                        GParamSpec   *pspec)
{
  GtkStylePrivate *priv;

  priv = GTK_STYLE_GET_PRIVATE (object);

  switch (prop_id)
    {
    case PROP_CONTEXT:
      priv->context = g_value_dup_object (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
static void
gtk_style_get_property (GObject      *object,
                        guint         prop_id,
                        GValue       *value,
                        GParamSpec   *pspec)
{
  GtkStylePrivate *priv;

  priv = GTK_STYLE_GET_PRIVATE (object);

  switch (prop_id)
    {
    case PROP_CONTEXT:
      g_value_set_object (value, priv->context);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

616
617
618
619
620
static gboolean
set_color_from_context (GtkStyle *style,
                        GtkStateType state,
                        GtkStyleContext *context,
                        GtkRcFlags prop)
621
{
622
623
  GdkRGBA *color = NULL;
  GdkColor *dest = { 0 }; /* Shut up gcc */
624
625
626
  GtkStateFlags flags;

  flags = gtk_style_context_get_state (context);
627
628
629
630

  switch (prop)
    {
    case GTK_RC_BG:
Carlos Garnacho's avatar
Carlos Garnacho committed
631
      gtk_style_context_get (context, flags,
632
633
                             "background-color", &color,
                             NULL);
634
      dest = &style->bg[state];
635
636
      break;
    case GTK_RC_FG:
Carlos Garnacho's avatar
Carlos Garnacho committed
637
      gtk_style_context_get (context, flags,
Carlos Garnacho's avatar
Carlos Garnacho committed
638
                             "color", &color,
639
                             NULL);
640
      dest = &style->fg[state];
641
642
      break;
    case GTK_RC_TEXT:
Carlos Garnacho's avatar
Carlos Garnacho committed
643
      gtk_style_context_get (context, flags,
Carlos Garnacho's avatar
Carlos Garnacho committed
644
                             "color", &color,
645
                             NULL);
646
      dest = &style->text[state];
647
648
      break;
    case GTK_RC_BASE:
Carlos Garnacho's avatar
Carlos Garnacho committed
649
      gtk_style_context_get (context, flags,
Carlos Garnacho's avatar
Carlos Garnacho committed
650
                             "background-color", &color,
651
                             NULL);
652
      dest = &style->base[state];
653
654
655
      break;
    }

Matthias Clasen's avatar
Matthias Clasen committed
656
  if (!color)
657
658
    return FALSE;

Matthias Clasen's avatar
Matthias Clasen committed
659
660
661
662
663
664
  if (!(color->alpha > 0.01))
    {
      gdk_rgba_free (color);
      return FALSE;
    }

665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
  dest->pixel = 0;
  dest->red = CLAMP ((guint) (color->red * 65535), 0, 65535);
  dest->green = CLAMP ((guint) (color->green * 65535), 0, 65535);
  dest->blue = CLAMP ((guint) (color->blue * 65535), 0, 65535);
  gdk_rgba_free (color);

  return TRUE;
}

static void
set_color (GtkStyle        *style,
           GtkStyleContext *context,
           GtkStateType     state,
           GtkRcFlags       prop)
{
  /* Try to fill in the values from the associated GtkStyleContext.
   * Since fully-transparent black is a very common default (e.g. for 
   * background-color properties), and we must store the result in a GdkColor
   * to retain API compatibility, in case the fetched color is fully transparent
   * we give themes a fallback style class they can style, before using the
   * hardcoded default values.
   */
687
  if (!set_color_from_context (style, state, context, prop))
688
    {
689
690
      gtk_style_context_save (context);
      gtk_style_context_add_class (context, "gtkstyle-fallback");
691
      set_color_from_context (style, state, context, prop);
692
      gtk_style_context_restore (context);
693
    }
694
695
696
697
698
699
700
}

static void
gtk_style_update_from_context (GtkStyle *style)
{
  GtkStylePrivate *priv;
  GtkStateType state;
701
  GtkStateFlags flags;
702
  GtkBorder padding;
703
  gint i;
704
705
706
707
708

  priv = GTK_STYLE_GET_PRIVATE (style);

  for (state = GTK_STATE_NORMAL; state <= GTK_STATE_INSENSITIVE; state++)
    {
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
      switch (state)
        {
        case GTK_STATE_ACTIVE:
          flags = GTK_STATE_FLAG_ACTIVE;
          break;
        case GTK_STATE_PRELIGHT:
          flags = GTK_STATE_FLAG_PRELIGHT;
          break;
        case GTK_STATE_SELECTED:
          flags = GTK_STATE_FLAG_SELECTED;
          break;
        case GTK_STATE_INSENSITIVE:
          flags = GTK_STATE_FLAG_INSENSITIVE;
          break;
        default:
          flags = 0;
        }

      gtk_style_context_save (priv->context);
      gtk_style_context_set_state (priv->context, flags);

Carlos Garnacho's avatar
Carlos Garnacho committed
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
      if (gtk_style_context_has_class (priv->context, "entry"))
        {
          gtk_style_context_save (priv->context);
          gtk_style_context_remove_class (priv->context, "entry");
          set_color (style, priv->context, state, GTK_RC_BG);
          set_color (style, priv->context, state, GTK_RC_FG);
          gtk_style_context_restore (priv->context);

          set_color (style, priv->context, state, GTK_RC_BASE);
          set_color (style, priv->context, state, GTK_RC_TEXT);
        }
      else
        {
          gtk_style_context_save (priv->context);
          gtk_style_context_add_class (priv->context, "entry");
          set_color (style, priv->context, state, GTK_RC_BASE);
          set_color (style, priv->context, state, GTK_RC_TEXT);
          gtk_style_context_restore (priv->context);

          set_color (style, priv->context, state, GTK_RC_BG);
          set_color (style, priv->context, state, GTK_RC_FG);
        }
752
753

      gtk_style_context_restore (priv->context);
754
755
    }

756
757
758
  if (style->font_desc)
    pango_font_description_free (style->font_desc);

759
760
  flags = gtk_style_context_get_state (priv->context);
  gtk_style_context_get (priv->context, flags,
761
762
                         "font", &style->font_desc,
                         NULL);
763
  gtk_style_context_get_padding (priv->context, flags, &padding);
764

765
766
  style->xthickness = padding.left;
  style->ythickness = padding.top;
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790

  for (i = 0; i < 5; i++)
    {
      _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
      _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);

      style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
      style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
      style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;

      style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
      style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
      style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
    }

  style->black.red = 0x0000;
  style->black.green = 0x0000;
  style->black.blue = 0x0000;

  style->white.red = 0xffff;
  style->white.green = 0xffff;
  style->white.blue = 0xffff;

  for (i = 0; i < 5; i++)
Carlos Garnacho's avatar
Carlos Garnacho committed
791
792
793
794
795
796
797
798
    {
      if (style->background[i])
        cairo_pattern_destroy (style->background[i]);

      style->background[i] = cairo_pattern_create_rgb (style->bg[i].red / 65535.0,
                                                       style->bg[i].green / 65535.0,
                                                       style->bg[i].blue / 65535.0);
    }
799
800
}

801
802
803
804
805
806
807
static void
style_context_changed (GtkStyleContext *context,
                       gpointer         user_data)
{
  gtk_style_update_from_context (GTK_STYLE (user_data));
}

808
809
810
811
812
813
814
815
816
817
818
static void
gtk_style_constructed (GObject *object)
{
  GtkStylePrivate *priv;

  priv = GTK_STYLE_GET_PRIVATE (object);

  if (priv->context)
    {
      gtk_style_update_from_context (GTK_STYLE (object));

819
820
      priv->context_changed_id = g_signal_connect (priv->context, "changed",
                                                   G_CALLBACK (style_context_changed), object);
821
822
    }
}
823

Matthias Clasen's avatar
Matthias Clasen committed
824
825
826
827
828
829
/**
 * gtk_style_copy:
 * @style: a #GtkStyle
 *
 * Creates a copy of the passed in #GtkStyle object.
 *
Matthias Clasen's avatar
Matthias Clasen committed
830
 * Returns: (transfer full): a copy of @style
831
832
 *
 * Deprecated:3.0: Use #GtkStyleContext instead
Matthias Clasen's avatar
Matthias Clasen committed
833
 */
834
835
836
837
838
GtkStyle*
gtk_style_copy (GtkStyle *style)
{
  GtkStyle *new_style;
  
839
  g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
840
  
841
842
  new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
  GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
843
844
845
846

  return new_style;
}

847
848
GtkStyle*
_gtk_style_new_for_path (GdkScreen     *screen,
849
                         GtkWidgetPath *path)
850
851
852
853
854
{
  GtkStyleContext *context;
  GtkStyle *style;

  context = gtk_style_context_new ();
855
856
857

  if (screen)
    gtk_style_context_set_screen (context, screen);
858

859
860
861
862
863
864
865
866
867
868
869
  gtk_style_context_set_path (context, path);

  style = g_object_new (GTK_TYPE_STYLE,
                        "context", context,
                        NULL);

  g_object_unref (context);

  return style;
}

Matthias Clasen's avatar
Matthias Clasen committed
870
871
872
873
/**
 * gtk_style_new:
 *
 * Creates a new #GtkStyle.
874
 *
Matthias Clasen's avatar
Matthias Clasen committed
875
876
 * Returns: a new #GtkStyle.
 *
877
 * Deprecated: 3.0: Use #GtkStyleContext
Matthias Clasen's avatar
Matthias Clasen committed
878
 */
879
880
881
GtkStyle*
gtk_style_new (void)
{
882
  GtkWidgetPath *path;
883
  GtkStyle *style;
884
885
886
887

  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_WIDGET);

888
  style = _gtk_style_new_for_path (gdk_screen_get_default (), path);
889
890
891

  gtk_widget_path_free (path);

Elliot Lee's avatar
Elliot Lee committed
892
893
894
  return style;
}

895
896
897
898
899
900
901
902
903
904
/**
 * gtk_style_has_context:
 * @style: a #GtkStyle
 *
 * Returns whether @style has an associated #GtkStyleContext.
 *
 * Returns: %TRUE if @style has a #GtkStyleContext
 *
 * Since: 3.0
 */
905
906
907
908
909
910
911
912
913
914
gboolean
gtk_style_has_context (GtkStyle *style)
{
  GtkStylePrivate *priv;

  priv = GTK_STYLE_GET_PRIVATE (style);

  return priv->context != NULL;
}

Matthias Clasen's avatar
Matthias Clasen committed
915
/**
916
 * gtk_style_attach: (skip)
Matthias Clasen's avatar
Matthias Clasen committed
917
 * @style: a #GtkStyle.
918
 * @window: a #GdkWindow.
919
 *
Matthias Clasen's avatar
Matthias Clasen committed
920
 * Attaches a style to a window; this process allocates the
921
 * colors and creates the GC’s for the style - it specializes
922
923
924
 * it to a particular visual. The process may involve the creation
 * of a new style if the style has already been attached to a
 * window with a different style and visual.
925
 *
Matthias Clasen's avatar
Matthias Clasen committed
926
927
 * Since this function may return a new object, you have to use it
 * in the following way:
928
 * `style = gtk_style_attach (style, window)`
929
930
931
932
933
 *
 * Returns: Either @style, or a newly-created #GtkStyle.
 *   If the style is newly created, the style parameter
 *   will be unref'ed, and the new style will have
 *   a reference count belonging to the caller.
934
935
 *
 * Deprecated:3.0: Use gtk_widget_style_attach() instead
936
 */
937
GtkStyle*
Elliot Lee's avatar
Elliot Lee committed
938
gtk_style_attach (GtkStyle  *style,
939
                  GdkWindow *window)
Elliot Lee's avatar
Elliot Lee committed
940
{
941
  g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
Elliot Lee's avatar
Elliot Lee committed
942
  g_return_val_if_fail (window != NULL, NULL);
Matthias Clasen's avatar
Matthias Clasen committed
943

944
  return style;
Elliot Lee's avatar
Elliot Lee committed
945
946
}

947
948
949
950
951
952
/**
 * gtk_style_detach:
 * @style: a #GtkStyle
 *
 * Detaches a style from a window. If the style is not attached
 * to any windows anymore, it is unrealized. See gtk_style_attach().
953
954
 *
 * Deprecated:3.0: Use #GtkStyleContext instead
955
 */
Elliot Lee's avatar
Elliot Lee committed
956
957
958
void
gtk_style_detach (GtkStyle *style)
{
959
  g_return_if_fail (GTK_IS_STYLE (style));
960
961
}

Matthias Clasen's avatar
Matthias Clasen committed
962
963
964
965
966
967
968
969
970
/**
 * gtk_style_lookup_icon_set:
 * @style: a #GtkStyle
 * @stock_id: an icon name
 *
 * Looks up @stock_id in the icon factories associated with @style
 * and the default icon factory, returning an icon set if found,
 * otherwise %NULL.
 *
971
 * Returns: (transfer none): icon set of @stock_id
972
973
 *
 * Deprecated:3.0: Use gtk_style_context_lookup_icon_set() instead
Matthias Clasen's avatar
Matthias Clasen committed
974
 */
975
976
977
978
GtkIconSet*
gtk_style_lookup_icon_set (GtkStyle   *style,
                           const char *stock_id)
{
979
  GtkStylePrivate *priv;
980
981
982
983

  g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
  g_return_val_if_fail (stock_id != NULL, NULL);

984
985
  priv = GTK_STYLE_GET_PRIVATE (style);

986
987
988
989
  if (priv->context)
    return gtk_style_context_lookup_icon_set (priv->context, stock_id);

  return gtk_icon_factory_lookup_default (stock_id);
990
991
}

992
993
994
995
/**
 * gtk_style_lookup_color:
 * @style: a #GtkStyle
 * @color_name: the name of the logical color to look up
996
 * @color: (out): the #GdkColor to fill in
997
 *
998
 * Looks up @color_name in the style’s logical color mappings,
999
1000
1001
1002
1003
 * filling in @color and returning %TRUE if found, otherwise
 * returning %FALSE. Do not cache the found mapping, because
 * it depends on the #GtkStyle and might change when a theme
 * switch occurs.
 *
1004
 * Returns: %TRUE if the mapping was found.
1005
1006
 *
 * Since: 2.10
1007
1008
 *
 * Deprecated:3.0: Use gtk_style_context_lookup_color() instead
1009
1010
1011
1012
1013
1014
1015
 **/
gboolean
gtk_style_lookup_color (GtkStyle   *style,
                        const char *color_name,
                        GdkColor   *color)
{
  GtkStylePrivate *priv;
1016
1017
  gboolean result;
  GdkRGBA rgba;
1018
1019
1020
1021
1022
1023
1024

  g_return_val_if_fail (GTK_IS_STYLE (style), FALSE);
  g_return_val_if_fail (color_name != NULL, FALSE);
  g_return_val_if_fail (color != NULL, FALSE);

  priv = GTK_STYLE_GET_PRIVATE (style);

1025
1026
  if (!priv->context)
    return FALSE;
1027

1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
  result = gtk_style_context_lookup_color (priv->context, color_name, &rgba);

  if (color)
    {
      color->red = (guint16) (rgba.red * 65535);
      color->green = (guint16) (rgba.green * 65535);
      color->blue = (guint16) (rgba.blue * 65535);
      color->pixel = 0;
    }

  return result;
1039
1040
}

Matthias Clasen's avatar
Matthias Clasen committed
1041
1042
1043
1044
1045
1046
1047
1048
/**
 * gtk_style_set_background:
 * @style: a #GtkStyle
 * @window: a #GdkWindow
 * @state_type: a state
 * 
 * Sets the background of @window to the background color or pixmap
 * specified by @style for the given state.
1049
1050
 *
 * Deprecated:3.0: Use gtk_style_context_set_background() instead
Matthias Clasen's avatar
Matthias Clasen committed
1051
 */
1052
void
1053
1054
1055
gtk_style_set_background (GtkStyle    *style,
                          GdkWindow   *window,
                          GtkStateType state_type)
1056
{
1057
  g_return_if_fail (GTK_IS_STYLE (style));
1058
1059
  g_return_if_fail (window != NULL);
  
1060
1061
1062
1063
1064
1065
1066
  GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
}

/* Default functions */
static GtkStyle *
gtk_style_real_clone (GtkStyle *style)
{
1067
1068
1069
1070
1071
1072
1073
  GtkStylePrivate *priv;

  priv = GTK_STYLE_GET_PRIVATE (style);

  return g_object_new (G_OBJECT_TYPE (style),
                       "context", priv->context,
                       NULL);
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
}

static void
gtk_style_real_copy (GtkStyle *style,
		     GtkStyle *src)
{
  gint i;
  
  for (i = 0; i < 5; i++)
    {
      style->fg[i] = src->fg[i];
      style->bg[i] = src->bg[i];
      style->text[i] = src->text[i];
      style->base[i] = src->base[i];
Matthias Clasen's avatar
Matthias Clasen committed
1088

1089
1090
1091
1092
1093
      if (style->background[i])
	cairo_pattern_destroy (style->background[i]),
      style->background[i] = src->background[i];
      if (style->background[i])
	cairo_pattern_reference (style->background[i]);
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
    }

  if (style->font_desc)
    pango_font_description_free (style->font_desc);
  if (src->font_desc)
    style->font_desc = pango_font_description_copy (src->font_desc);
  else
    style->font_desc = NULL;
  
  style->xthickness = src->xthickness;
  style->ythickness = src->ythickness;

  if (style->rc_style)
1107
    g_object_unref (style->rc_style);
1108
1109
  style->rc_style = src->rc_style;
  if (src->rc_style)
1110
    g_object_ref (src->rc_style);
1111

Matthias Clasen's avatar
Matthias Clasen committed
1112
  g_slist_free_full (style->icon_factories, g_object_unref);
1113
1114
  style->icon_factories = g_slist_copy (src->icon_factories);
  g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
1115
1116
1117
1118
1119
1120
}

static void
gtk_style_real_init_from_rc (GtkStyle   *style,
			     GtkRcStyle *rc_style)
{
1121
1122
}

1123
/**
1124
 * gtk_style_get_style_property:
1125
1126
1127
 * @style: a #GtkStyle
 * @widget_type: the #GType of a descendant of #GtkWidget
 * @property_name: the name of the style property to get
1128
 * @value: (out): a #GValue where the value of the property being
1129
1130
1131
1132
1133
1134
1135
1136
 *     queried will be stored
 *
 * Queries the value of a style property corresponding to a
 * widget class is in the given style.
 *
 * Since: 2.16
 */
void 
1137
1138
1139
1140
gtk_style_get_style_property (GtkStyle     *style,
                              GType        widget_type,
                              const gchar *property_name,
                              GValue      *value)
1141
{
1142
  GtkStylePrivate *priv;
1143
1144
1145
1146
  GtkWidgetClass *klass;
  GParamSpec *pspec;
  const GValue *peek_value;

1147
  klass = g_type_class_ref (widget_type);
1148
  pspec = gtk_widget_class_find_style_property (klass, property_name);
1149
  g_type_class_unref (klass);
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159

  if (!pspec)
    {
      g_warning ("%s: widget class `%s' has no property named `%s'",
                 G_STRLOC,
                 g_type_name (widget_type),
                 property_name);
      return;
    }

1160
1161
1162
  priv = GTK_STYLE_GET_PRIVATE (style);
  peek_value = _gtk_style_context_peek_style_property (priv->context,
                                                       widget_type,
1163
                                                       pspec);
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180

  if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
    g_value_copy (peek_value, value);
  else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
    g_value_transform (peek_value, value);
  else
    g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
               pspec->name,
               g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
               G_VALUE_TYPE_NAME (value));
}

/**
 * gtk_style_get_valist:
 * @style: a #GtkStyle
 * @widget_type: the #GType of a descendant of #GtkWidget
 * @first_property_name: the name of the first style property to get
1181
 * @var_args: a va_list of pairs of property names and
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
 *     locations to return the property values, starting with the
 *     location for @first_property_name.
 *
 * Non-vararg variant of gtk_style_get().
 * Used primarily by language bindings.
 *
 * Since: 2.16
 */
void 
gtk_style_get_valist (GtkStyle    *style,
                      GType        widget_type,
                      const gchar *first_property_name,
                      va_list      var_args)
{
1196
  GtkStylePrivate *priv;
1197
1198
1199
1200
1201
1202
1203
  const char *property_name;
  GtkWidgetClass *klass;

  g_return_if_fail (GTK_IS_STYLE (style));

  klass = g_type_class_ref (widget_type);

1204
  priv = GTK_STYLE_GET_PRIVATE (style);
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
  property_name = first_property_name;
  while (property_name)
    {
      GParamSpec *pspec;
      const GValue *peek_value;
      gchar *error;

      pspec = gtk_widget_class_find_style_property (klass, property_name);

      if (!pspec)
        {
          g_warning ("%s: widget class `%s' has no property named `%s'",
                     G_STRLOC,
                     g_type_name (widget_type),
                     property_name);
          break;
        }

1223
      peek_value = _gtk_style_context_peek_style_property (priv->context, widget_type,
1224
                                                           pspec);
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
      G_VALUE_LCOPY (peek_value, var_args, 0, &error);
      if (error)
        {
          g_warning ("%s: %s", G_STRLOC, error);
          g_free (error);
          break;
        }

      property_name = va_arg (var_args, gchar*);
    }

  g_type_class_unref (klass);
}

/**
 * gtk_style_get:
 * @style: a #GtkStyle
 * @widget_type: the #GType of a descendant of #GtkWidget
 * @first_property_name: the name of the first style property to get
Matthias Clasen's avatar
Matthias Clasen committed
1244
 * @...: pairs of property names and locations to
1245
1246
1247
1248
1249
 *   return the property values, starting with the location for
 *   @first_property_name, terminated by %NULL.
 *
 * Gets the values of a multiple style properties for @widget_type
 * from @style.
1250
1251
 *
 * Since: 2.16
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
 */
void
gtk_style_get (GtkStyle    *style,
               GType        widget_type,
               const gchar *first_property_name,
               ...)
{
  va_list var_args;

  va_start (var_args, first_property_name);
  gtk_style_get_valist (style, widget_type, first_property_name, var_args);
  va_end (var_args);
}

1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
static void
gtk_style_real_realize (GtkStyle *style)
{
}

static void
gtk_style_real_unrealize (GtkStyle *style)
{
}

static void
gtk_style_real_set_background (GtkStyle    *style,
			       GdkWindow   *window,
			       GtkStateType state_type)
{
1281
  gdk_window_set_background_pattern (window, style->background[state_type]);
1282
1283
}

Matthias Clasen's avatar
Matthias Clasen committed
1284
1285
1286
1287
1288
1289
/**
 * gtk_style_render_icon:
 * @style: a #GtkStyle
 * @source: the #GtkIconSource specifying the icon to render
 * @direction: a text direction
 * @state: a state