1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
32 #include "gtkmarshalers.h"
34 #include "gtkspinbutton.h"
36 #include "gtkwidget.h"
37 #include "gtkthemes.h"
38 #include "gtkiconfactory.h"
39 #include "gtksettings.h" /* _gtk_settings_parse_convert() */
41 #define LIGHTNESS_MULT 1.3
42 #define DARKNESS_MULT 0.7
44 /* --- typedefs & structures --- */
51 /* --- prototypes --- */
52 static void gtk_style_init (GtkStyle *style);
53 static void gtk_style_class_init (GtkStyleClass *klass);
54 static void gtk_style_finalize (GObject *object);
55 static void gtk_style_realize (GtkStyle *style,
56 GdkColormap *colormap);
57 static void gtk_style_real_realize (GtkStyle *style);
58 static void gtk_style_real_unrealize (GtkStyle *style);
59 static void gtk_style_real_copy (GtkStyle *style,
61 static void gtk_style_real_set_background (GtkStyle *style,
63 GtkStateType state_type);
64 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
65 static void gtk_style_real_init_from_rc (GtkStyle *style,
66 GtkRcStyle *rc_style);
67 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
68 const GtkIconSource *source,
69 GtkTextDirection direction,
74 static void gtk_default_draw_hline (GtkStyle *style,
76 GtkStateType state_type,
83 static void gtk_default_draw_vline (GtkStyle *style,
85 GtkStateType state_type,
92 static void gtk_default_draw_shadow (GtkStyle *style,
94 GtkStateType state_type,
95 GtkShadowType shadow_type,
103 static void gtk_default_draw_polygon (GtkStyle *style,
105 GtkStateType state_type,
106 GtkShadowType shadow_type,
113 static void gtk_default_draw_arrow (GtkStyle *style,
115 GtkStateType state_type,
116 GtkShadowType shadow_type,
120 GtkArrowType arrow_type,
126 static void gtk_default_draw_diamond (GtkStyle *style,
128 GtkStateType state_type,
129 GtkShadowType shadow_type,
137 static void gtk_default_draw_string (GtkStyle *style,
139 GtkStateType state_type,
145 const gchar *string);
146 static void gtk_default_draw_box (GtkStyle *style,
148 GtkStateType state_type,
149 GtkShadowType shadow_type,
157 static void gtk_default_draw_flat_box (GtkStyle *style,
159 GtkStateType state_type,
160 GtkShadowType shadow_type,
168 static void gtk_default_draw_check (GtkStyle *style,
170 GtkStateType state_type,
171 GtkShadowType shadow_type,
179 static void gtk_default_draw_option (GtkStyle *style,
181 GtkStateType state_type,
182 GtkShadowType shadow_type,
190 static void gtk_default_draw_tab (GtkStyle *style,
192 GtkStateType state_type,
193 GtkShadowType shadow_type,
201 static void gtk_default_draw_shadow_gap (GtkStyle *style,
203 GtkStateType state_type,
204 GtkShadowType shadow_type,
212 GtkPositionType gap_side,
215 static void gtk_default_draw_box_gap (GtkStyle *style,
217 GtkStateType state_type,
218 GtkShadowType shadow_type,
226 GtkPositionType gap_side,
229 static void gtk_default_draw_extension (GtkStyle *style,
231 GtkStateType state_type,
232 GtkShadowType shadow_type,
240 GtkPositionType gap_side);
241 static void gtk_default_draw_focus (GtkStyle *style,
243 GtkStateType state_type,
251 static void gtk_default_draw_slider (GtkStyle *style,
253 GtkStateType state_type,
254 GtkShadowType shadow_type,
262 GtkOrientation orientation);
263 static void gtk_default_draw_handle (GtkStyle *style,
265 GtkStateType state_type,
266 GtkShadowType shadow_type,
274 GtkOrientation orientation);
275 static void gtk_default_draw_expander (GtkStyle *style,
277 GtkStateType state_type,
283 GtkExpanderStyle expander_style);
284 static void gtk_default_draw_layout (GtkStyle *style,
286 GtkStateType state_type,
293 PangoLayout *layout);
294 static void gtk_default_draw_resize_grip (GtkStyle *style,
296 GtkStateType state_type,
306 static void gtk_style_shade (GdkColor *a,
309 static void rgb_to_hls (gdouble *r,
312 static void hls_to_rgb (gdouble *h,
316 static void style_unrealize_cursor_gcs (GtkStyle *style);
318 static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
321 * Data for default check and radio buttons
324 static const GtkRequisition default_option_indicator_size = { 7, 13 };
325 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
327 #define INDICATOR_PART_SIZE 13
337 CHECK_INCONSISTENT_TEXT,
344 RADIO_INCONSISTENT_AA,
345 RADIO_INCONSISTENT_TEXT
349 * Extracted from check-13.png, width=13, height=13
351 static const guchar check_black_bits[] = {
352 0x00,0x00,0xfe,0x0f,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
353 0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00};
354 static const guchar check_dark_bits[] = {
355 0xff,0x1f,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
356 0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00};
357 static const guchar check_mid_bits[] = {
358 0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
359 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0xfc,0x0f,0x00,0x00,0x00,0x00};
360 static const guchar check_light_bits[] = {
361 0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
362 0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0xfe,0x1f,0x00,0x00};
363 static const guchar check_text_bits[] = {
364 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x80,0x01,0x80,0x00,0x58,
365 0x00,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
366 static const guchar check_aa_bits[] = {
367 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x58,0x00,0xa0,
368 0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
369 static const guchar check_base_bits[] = {
370 0x00,0x00,0x00,0x00,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
371 0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0x00,0x00,0x00,0x00,0x00,0x00};
374 * Extracted from check-13-inconsistent.png, width=13, height=13
376 static const guchar check_inconsistent_text_bits[] = {
377 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0xf8,
378 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
381 * check_inconsistent_aa_bits is currently not used, since it is all zeros.
383 static const guchar check_inconsistent_aa_bits[] = {
384 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
385 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
389 * Extracted from radio-13.png, width=13, height=13
391 static const guchar radio_black_bits[] = {
392 0x00,0x00,0xf0,0x01,0x0c,0x02,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
393 0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x08};
394 static const guchar radio_dark_bits[] = {
395 0xf0,0x00,0x0c,0x02,0x02,0x04,0x02,0x04,0x01,0x08,0x01,0x08,0x01,0x08,0x01,
396 0x08,0x00,0x08,0x02,0x04,0x0c,0x06,0xf0,0x01,0x00,0x00,0x00,0x00};
397 static const guchar radio_mid_bits[] = {
398 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
399 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
400 static const guchar radio_light_bits[] = {
401 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,
402 0x10,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x06,0xe0,0x01,0x00,0x00};
403 static const guchar radio_text_bits[] = {
404 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0xf0,0x01,0xf0,0x01,0xf0,
405 0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
408 * radio_aa_bits is currently not used, since it is all zeros.
410 static const guchar radio_aa_bits[] = {
411 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
412 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
414 static const guchar radio_base_bits[] = {
415 0x00,0x00,0x00,0x00,0xf0,0x01,0xf8,0x03,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
416 0x07,0xfc,0x07,0xf8,0x03,0xf0,0x01,0x00,0x00,0x00,0x00,0x00,0x00};
419 * Extracted from radio-13.png, width=13, height=13
421 static const guchar radio_inconsistent_text_bits[] = {
422 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00,
423 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
424 static const guchar radio_inconsistent_aa_bits[] = {
425 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00,0x00,0xf8,
426 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
430 GList *bmap_list; /* list of GdkBitmap */
431 } indicator_parts[] = {
432 { check_aa_bits, NULL },
433 { check_base_bits, NULL },
434 { check_black_bits, NULL },
435 { check_dark_bits, NULL },
436 { check_light_bits, NULL },
437 { check_mid_bits, NULL },
438 { check_text_bits, NULL },
439 { check_inconsistent_text_bits, NULL },
440 { radio_base_bits, NULL },
441 { radio_black_bits, NULL },
442 { radio_dark_bits, NULL },
443 { radio_light_bits, NULL },
444 { radio_mid_bits, NULL },
445 { radio_text_bits, NULL },
446 { radio_inconsistent_aa_bits, NULL },
447 { radio_inconsistent_text_bits, NULL },
450 /* --- variables --- */
451 static const GdkColor gtk_default_normal_fg = { 0, 0, 0, 0 };
452 static const GdkColor gtk_default_active_fg = { 0, 0, 0, 0 };
453 static const GdkColor gtk_default_prelight_fg = { 0, 0, 0, 0 };
454 static const GdkColor gtk_default_selected_fg = { 0, 0xffff, 0xffff, 0xffff };
455 static const GdkColor gtk_default_insensitive_fg = { 0, 0x7530, 0x7530, 0x7530 };
457 static const GdkColor gtk_default_normal_bg = { 0, 0xdcdc, 0xdada, 0xd5d5 };
458 static const GdkColor gtk_default_active_bg = { 0, 0xbaba, 0xb5b5, 0xabab };
459 static const GdkColor gtk_default_prelight_bg = { 0, 0xeeee, 0xebeb, 0xe7e7 };
460 static const GdkColor gtk_default_selected_bg = { 0, 0x4b4b, 0x6969, 0x8383 };
461 static const GdkColor gtk_default_insensitive_bg = { 0, 0xdcdc, 0xdada, 0xd5d5 };
462 static const GdkColor gtk_default_selected_base = { 0, 0x4b4b, 0x6969, 0x8383 };
463 static const GdkColor gtk_default_active_base = { 0, 0x8080, 0x7d7d, 0x7474 };
465 static gpointer parent_class = NULL;
467 /* --- signals --- */
468 static guint realize_signal = 0;
469 static guint unrealize_signal = 0;
471 /* --- functions --- */
473 gtk_style_get_type (void)
475 static GType style_type = 0;
479 static const GTypeInfo style_info =
481 sizeof (GtkStyleClass),
482 (GBaseInitFunc) NULL,
483 (GBaseFinalizeFunc) NULL,
484 (GClassInitFunc) gtk_style_class_init,
485 NULL, /* class_finalize */
486 NULL, /* class_data */
489 (GInstanceInitFunc) gtk_style_init,
492 style_type = g_type_register_static (G_TYPE_OBJECT, "GtkStyle",
500 * _gtk_style_init_for_settings:
501 * @style: a #GtkStyle
502 * @settings: a #GtkSettings
504 * Initializes the font description in @style accoridng to the default
505 * font name of @settings. This is called for gtk_style_new() with
506 * the settings for the default screen (if any); if we are creating
507 * a style for a particular screen, we then call it again in a
508 * location where we know the correct settings.
509 * The reason for this is that gtk_rc_style_create_style() doesn't
510 * take the screen for an argument.
513 _gtk_style_init_for_settings (GtkStyle *style,
514 GtkSettings *settings)
516 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
518 if (style->font_desc)
519 pango_font_description_free (style->font_desc);
521 style->font_desc = pango_font_description_from_string (font_name);
523 if (!pango_font_description_get_family (style->font_desc))
525 g_warning ("Default font does not have a family set");
526 pango_font_description_set_family (style->font_desc, "Sans");
528 if (pango_font_description_get_size (style->font_desc) <= 0)
530 g_warning ("Default font does not have a positive size");
531 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
536 gtk_style_init (GtkStyle *style)
540 GtkSettings *settings = gtk_settings_get_default ();
543 _gtk_style_init_for_settings (style, settings);
545 style->font_desc = pango_font_description_from_string ("Sans 10");
547 style->attach_count = 0;
548 style->colormap = NULL;
551 style->black.red = 0;
552 style->black.green = 0;
553 style->black.blue = 0;
555 style->white.red = 65535;
556 style->white.green = 65535;
557 style->white.blue = 65535;
559 style->black_gc = NULL;
560 style->white_gc = NULL;
562 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
563 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
564 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
565 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
566 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
568 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
569 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
570 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
571 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
572 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
574 for (i = 0; i < 4; i++)
576 style->text[i] = style->fg[i];
577 style->base[i] = style->white;
580 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
581 style->text[GTK_STATE_SELECTED] = style->white;
582 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
583 style->text[GTK_STATE_ACTIVE] = style->white;
584 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
585 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
587 for (i = 0; i < 5; i++)
588 style->bg_pixmap[i] = NULL;
590 style->rc_style = NULL;
592 for (i = 0; i < 5; i++)
594 style->fg_gc[i] = NULL;
595 style->bg_gc[i] = NULL;
596 style->light_gc[i] = NULL;
597 style->dark_gc[i] = NULL;
598 style->mid_gc[i] = NULL;
599 style->text_gc[i] = NULL;
600 style->base_gc[i] = NULL;
601 style->text_aa_gc[i] = NULL;
604 style->xthickness = 2;
605 style->ythickness = 2;
607 style->property_cache = NULL;
611 gtk_style_class_init (GtkStyleClass *klass)
613 GObjectClass *object_class = G_OBJECT_CLASS (klass);
615 parent_class = g_type_class_peek_parent (klass);
617 object_class->finalize = gtk_style_finalize;
619 klass->clone = gtk_style_real_clone;
620 klass->copy = gtk_style_real_copy;
621 klass->init_from_rc = gtk_style_real_init_from_rc;
622 klass->realize = gtk_style_real_realize;
623 klass->unrealize = gtk_style_real_unrealize;
624 klass->set_background = gtk_style_real_set_background;
625 klass->render_icon = gtk_default_render_icon;
627 klass->draw_hline = gtk_default_draw_hline;
628 klass->draw_vline = gtk_default_draw_vline;
629 klass->draw_shadow = gtk_default_draw_shadow;
630 klass->draw_polygon = gtk_default_draw_polygon;
631 klass->draw_arrow = gtk_default_draw_arrow;
632 klass->draw_diamond = gtk_default_draw_diamond;
633 klass->draw_string = gtk_default_draw_string;
634 klass->draw_box = gtk_default_draw_box;
635 klass->draw_flat_box = gtk_default_draw_flat_box;
636 klass->draw_check = gtk_default_draw_check;
637 klass->draw_option = gtk_default_draw_option;
638 klass->draw_tab = gtk_default_draw_tab;
639 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
640 klass->draw_box_gap = gtk_default_draw_box_gap;
641 klass->draw_extension = gtk_default_draw_extension;
642 klass->draw_focus = gtk_default_draw_focus;
643 klass->draw_slider = gtk_default_draw_slider;
644 klass->draw_handle = gtk_default_draw_handle;
645 klass->draw_expander = gtk_default_draw_expander;
646 klass->draw_layout = gtk_default_draw_layout;
647 klass->draw_resize_grip = gtk_default_draw_resize_grip;
652 * @style: the object which received the signal
654 * Emitted when the style has been initialized for a particular
655 * colormap and depth. Connecting to this signal is probably seldom
656 * useful since most of the time applications and widgets only
657 * deal with styles that have been already realized.
661 realize_signal = g_signal_new ("realize",
662 G_TYPE_FROM_CLASS (object_class),
664 G_STRUCT_OFFSET (GtkStyleClass, realize),
666 _gtk_marshal_VOID__VOID,
669 * GtkStyle::unrealize:
670 * @style: the object which received the signal
672 * Emitted when the aspects of the style specific to a particular colormap
673 * and depth are being cleaned up. A connection to this signal can be useful
674 * if a widget wants to cache objects like a #GdkGC as object data on #GtkStyle.
675 * This signal provides a convenient place to free such cached objects.
679 unrealize_signal = g_signal_new ("unrealize",
680 G_TYPE_FROM_CLASS (object_class),
682 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
684 _gtk_marshal_VOID__VOID,
689 clear_property_cache (GtkStyle *style)
691 if (style->property_cache)
695 for (i = 0; i < style->property_cache->len; i++)
697 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
699 g_param_spec_unref (node->pspec);
700 g_value_unset (&node->value);
702 g_array_free (style->property_cache, TRUE);
703 style->property_cache = NULL;
708 gtk_style_finalize (GObject *object)
710 GtkStyle *style = GTK_STYLE (object);
712 g_return_if_fail (style->attach_count == 0);
714 clear_property_cache (style);
718 if (style->styles->data != style)
719 g_slist_remove (style->styles, style);
722 GSList *tmp_list = style->styles->next;
726 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
727 tmp_list = tmp_list->next;
729 g_slist_free_1 (style->styles);
733 if (style->icon_factories)
735 GSList *tmp_list = style->icon_factories;
739 g_object_unref (tmp_list->data);
740 tmp_list = tmp_list->next;
743 g_slist_free (style->icon_factories);
746 pango_font_description_free (style->font_desc);
748 if (style->private_font)
749 gdk_font_unref (style->private_font);
751 if (style->private_font_desc)
752 pango_font_description_free (style->private_font_desc);
755 gtk_rc_style_unref (style->rc_style);
757 G_OBJECT_CLASS (parent_class)->finalize (object);
762 gtk_style_copy (GtkStyle *style)
766 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
768 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
769 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
775 gtk_style_duplicate (GtkStyle *style)
779 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
781 new_style = gtk_style_copy (style);
783 style->styles = g_slist_append (style->styles, new_style);
784 new_style->styles = style->styles;
791 * @returns: a new #GtkStyle.
793 * Creates a new #GtkStyle.
800 style = g_object_new (GTK_TYPE_STYLE, NULL);
807 * @style: a #GtkStyle.
808 * @window: a #GdkWindow.
809 * @returns: Either @style, or a newly-created #GtkStyle.
810 * If the style is newly created, the style parameter
811 * will be dereferenced, and the new style will have
812 * a reference count belonging to the caller.
814 * Attaches a style to a window; this process allocates the
815 * colors and creates the GC's for the style - it specializes
816 * it to a particular visual and colormap. The process may
817 * involve the creation of a new style if the style has already
818 * been attached to a window with a different style and colormap.
821 * FIXME: The sequence -
822 * create a style => s1
823 * attach s1 to v1, c1 => s1
824 * attach s1 to v2, c2 => s2
825 * detach s1 from v1, c1
826 * attach s1 to v2, c2 => s3
827 * results in two separate, unlinked styles s2 and s3 which
828 * are identical and could be shared. To fix this, we would
829 * want to never remove a style from the list of linked
830 * styles as long as as it has a reference count. However, the
831 * disadvantage of doing it this way means that we would need two
832 * passes through the linked list when attaching (one to check for
833 * matching styles, one to look for empty unattached styles - but
834 * it will almost never be longer than 2 elements.
837 gtk_style_attach (GtkStyle *style,
841 GtkStyle *new_style = NULL;
842 GdkColormap *colormap;
844 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
845 g_return_val_if_fail (window != NULL, NULL);
847 colormap = gdk_drawable_get_colormap (window);
850 style->styles = g_slist_append (NULL, style);
852 styles = style->styles;
855 new_style = styles->data;
857 if (new_style->attach_count == 0)
859 gtk_style_realize (new_style, colormap);
862 else if (new_style->colormap == colormap)
866 styles = styles->next;
871 new_style = gtk_style_duplicate (style);
872 if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
873 new_style->private_font)
875 gdk_font_unref (new_style->private_font);
876 new_style->private_font = NULL;
878 gtk_style_realize (new_style, colormap);
881 /* A style gets a refcount from being attached */
882 if (new_style->attach_count == 0)
883 g_object_ref (new_style);
885 /* Another refcount belongs to the parent */
886 if (style != new_style)
888 g_object_unref (style);
889 g_object_ref (new_style);
892 new_style->attach_count++;
898 gtk_style_detach (GtkStyle *style)
900 g_return_if_fail (GTK_IS_STYLE (style));
902 style->attach_count -= 1;
903 if (style->attach_count == 0)
905 g_signal_emit (style, unrealize_signal, 0);
907 g_object_unref (style->colormap);
908 style->colormap = NULL;
910 if (style->private_font_desc)
912 if (style->private_font)
914 gdk_font_unref (style->private_font);
915 style->private_font = NULL;
918 pango_font_description_free (style->private_font_desc);
919 style->private_font_desc = NULL;
922 g_object_unref (style);
928 * @style: a #GtkStyle.
931 * Deprecated equivalent of g_object_ref().
934 gtk_style_ref (GtkStyle *style)
936 return (GtkStyle *) g_object_ref (style);
941 * @style: a #GtkStyle.
943 * Deprecated equivalent of g_object_unref().
946 gtk_style_unref (GtkStyle *style)
948 g_object_unref (style);
952 gtk_style_realize (GtkStyle *style,
953 GdkColormap *colormap)
955 g_return_if_fail (GTK_IS_STYLE (style));
956 g_return_if_fail (GDK_IS_COLORMAP (colormap));
958 style->colormap = g_object_ref (colormap);
959 style->depth = gdk_colormap_get_visual (colormap)->depth;
961 g_signal_emit (style, realize_signal, 0);
965 gtk_style_lookup_icon_set (GtkStyle *style,
966 const char *stock_id)
970 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
971 g_return_val_if_fail (stock_id != NULL, NULL);
973 iter = style->icon_factories;
976 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
981 iter = g_slist_next (iter);
984 return gtk_icon_factory_lookup_default (stock_id);
989 * @style: a #GtkStyle
990 * @window: a #GdkWindow
991 * @state_type: a state
992 * @x1: the starting x coordinate
993 * @x2: the ending x coordinate
994 * @y: the y coordinate
996 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
997 * using the given style and state.
999 * Deprecated: Use gtk_paint_hline() instead.
1002 gtk_draw_hline (GtkStyle *style,
1004 GtkStateType state_type,
1009 g_return_if_fail (GTK_IS_STYLE (style));
1010 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
1012 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
1018 * @style: a #GtkStyle
1019 * @window: a #GdkWindow
1020 * @state_type: a state
1021 * @y1_: the starting y coordinate
1022 * @y2_: the ending y coordinate
1023 * @x: the x coordinate
1025 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
1026 * using the given style and state.
1028 * Deprecated: Use gtk_paint_vline() instead.
1031 gtk_draw_vline (GtkStyle *style,
1033 GtkStateType state_type,
1038 g_return_if_fail (GTK_IS_STYLE (style));
1039 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
1041 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1_, y2_, x);
1046 * @style: a #GtkStyle
1047 * @window: a #GdkWindow
1048 * @state_type: a state
1049 * @shadow_type: type of shadow to draw
1050 * @x: x origin of the rectangle
1051 * @y: y origin of the rectangle
1052 * @width: width of the rectangle
1053 * @height: width of the rectangle
1055 * Draws a shadow around the given rectangle in @window
1056 * using the given style and state and shadow type.
1058 * Deprecated: Use gtk_paint_shadow() instead.
1061 gtk_draw_shadow (GtkStyle *style,
1063 GtkStateType state_type,
1064 GtkShadowType shadow_type,
1070 g_return_if_fail (GTK_IS_STYLE (style));
1071 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
1073 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1078 * @style: a #GtkStyle
1079 * @window: a #GdkWindow
1080 * @state_type: a state
1081 * @shadow_type: type of shadow to draw
1082 * @points: an array of #GdkPoint<!-- -->s
1083 * @npoints: length of @points
1084 * @fill: %TRUE if the polygon should be filled
1086 * Draws a polygon on @window with the given parameters.
1088 * Deprecated: Use gtk_paint_polygon() instead.
1091 gtk_draw_polygon (GtkStyle *style,
1093 GtkStateType state_type,
1094 GtkShadowType shadow_type,
1099 g_return_if_fail (GTK_IS_STYLE (style));
1100 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
1102 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
1107 * @style: a #GtkStyle
1108 * @window: a #GdkWindow
1109 * @state_type: a state
1110 * @shadow_type: the type of shadow to draw
1111 * @arrow_type: the type of arrow to draw
1112 * @fill: %TRUE if the arrow tip should be filled
1113 * @x: x origin of the rectangle to draw the arrow in
1114 * @y: y origin of the rectangle to draw the arrow in
1115 * @width: width of the rectangle to draw the arrow in
1116 * @height: height of the rectangle to draw the arrow in
1118 * Draws an arrow in the given rectangle on @window using the given
1119 * parameters. @arrow_type determines the direction of the arrow.
1121 * Deprecated: Use gtk_paint_arrow() instead.
1124 gtk_draw_arrow (GtkStyle *style,
1126 GtkStateType state_type,
1127 GtkShadowType shadow_type,
1128 GtkArrowType arrow_type,
1135 g_return_if_fail (GTK_IS_STYLE (style));
1136 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
1138 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
1143 * @style: a #GtkStyle
1144 * @window: a #GdkWindow
1145 * @state_type: a state
1146 * @shadow_type: the type of shadow to draw
1147 * @x: x origin of the rectangle to draw the diamond in
1148 * @y: y origin of the rectangle to draw the diamond in
1149 * @width: width of the rectangle to draw the diamond in
1150 * @height: height of the rectangle to draw the diamond in
1152 * Draws a diamond in the given rectangle on @window using the given
1155 * Deprecated: Use gtk_paint_diamond() instead.
1158 gtk_draw_diamond (GtkStyle *style,
1160 GtkStateType state_type,
1161 GtkShadowType shadow_type,
1167 g_return_if_fail (GTK_IS_STYLE (style));
1168 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
1170 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1175 * @style: a #GtkStyle
1176 * @window: a #GdkWindow
1177 * @state_type: a state
1180 * @string: the string to draw
1182 * Draws a text string on @window with the given parameters.
1184 * Deprecated: Use gtk_paint_layout() instead.
1187 gtk_draw_string (GtkStyle *style,
1189 GtkStateType state_type,
1192 const gchar *string)
1194 g_return_if_fail (GTK_IS_STYLE (style));
1195 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
1197 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
1202 * @style: a #GtkStyle
1203 * @window: a #GdkWindow
1204 * @state_type: a state
1205 * @shadow_type: the type of shadow to draw
1206 * @x: x origin of the box
1207 * @y: y origin of the box
1208 * @width: the width of the box
1209 * @height: the height of the box
1211 * Draws a box on @window with the given parameters.
1213 * Deprecated: Use gtk_paint_box() instead.
1216 gtk_draw_box (GtkStyle *style,
1218 GtkStateType state_type,
1219 GtkShadowType shadow_type,
1225 g_return_if_fail (GTK_IS_STYLE (style));
1226 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
1228 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1232 * gtk_draw_flat_box:
1233 * @style: a #GtkStyle
1234 * @window: a #GdkWindow
1235 * @state_type: a state
1236 * @shadow_type: the type of shadow to draw
1237 * @x: x origin of the box
1238 * @y: y origin of the box
1239 * @width: the width of the box
1240 * @height: the height of the box
1242 * Draws a flat box on @window with the given parameters.
1244 * Deprecated: Use gtk_paint_flat_box() instead.
1247 gtk_draw_flat_box (GtkStyle *style,
1249 GtkStateType state_type,
1250 GtkShadowType shadow_type,
1256 g_return_if_fail (GTK_IS_STYLE (style));
1257 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
1259 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1264 * @style: a #GtkStyle
1265 * @window: a #GdkWindow
1266 * @state_type: a state
1267 * @shadow_type: the type of shadow to draw
1268 * @x: x origin of the rectangle to draw the check in
1269 * @y: y origin of the rectangle to draw the check in
1270 * @width: the width of the rectangle to draw the check in
1271 * @height: the height of the rectangle to draw the check in
1273 * Draws a check button indicator in the given rectangle on @window with
1274 * the given parameters.
1276 * Deprecated: Use gtk_paint_check() instead.
1279 gtk_draw_check (GtkStyle *style,
1281 GtkStateType state_type,
1282 GtkShadowType shadow_type,
1288 g_return_if_fail (GTK_IS_STYLE (style));
1289 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
1291 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1296 * @style: a #GtkStyle
1297 * @window: a #GdkWindow
1298 * @state_type: a state
1299 * @shadow_type: the type of shadow to draw
1300 * @x: x origin of the rectangle to draw the option in
1301 * @y: y origin of the rectangle to draw the option in
1302 * @width: the width of the rectangle to draw the option in
1303 * @height: the height of the rectangle to draw the option in
1305 * Draws a radio button indicator in the given rectangle on @window with
1306 * the given parameters.
1308 * Deprecated: Use gtk_paint_option() instead.
1311 gtk_draw_option (GtkStyle *style,
1313 GtkStateType state_type,
1314 GtkShadowType shadow_type,
1320 g_return_if_fail (GTK_IS_STYLE (style));
1321 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
1323 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1328 * @style: a #GtkStyle
1329 * @window: a #GdkWindow
1330 * @state_type: a state
1331 * @shadow_type: the type of shadow to draw
1332 * @x: x origin of the rectangle to draw the tab in
1333 * @y: y origin of the rectangle to draw the tab in
1334 * @width: the width of the rectangle to draw the tab in
1335 * @height: the height of the rectangle to draw the tab in
1337 * Draws an option menu tab (i.e. the up and down pointing arrows)
1338 * in the given rectangle on @window using the given parameters.
1340 * Deprecated: Use gtk_paint_tab() instead.
1343 gtk_draw_tab (GtkStyle *style,
1345 GtkStateType state_type,
1346 GtkShadowType shadow_type,
1352 g_return_if_fail (GTK_IS_STYLE (style));
1353 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
1355 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1359 * gtk_draw_shadow_gap:
1360 * @style: a #GtkStyle
1361 * @window: a #GdkWindow
1362 * @state_type: a state
1363 * @shadow_type: type of shadow to draw
1364 * @x: x origin of the rectangle
1365 * @y: y origin of the rectangle
1366 * @width: width of the rectangle
1367 * @height: width of the rectangle
1368 * @gap_side: side in which to leave the gap
1369 * @gap_x: starting position of the gap
1370 * @gap_width: width of the gap
1372 * Draws a shadow around the given rectangle in @window
1373 * using the given style and state and shadow type, leaving a
1376 * Deprecated: Use gtk_paint_shadow_gap() instead.
1379 gtk_draw_shadow_gap (GtkStyle *style,
1381 GtkStateType state_type,
1382 GtkShadowType shadow_type,
1387 GtkPositionType gap_side,
1391 g_return_if_fail (GTK_IS_STYLE (style));
1392 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
1394 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side, gap_x, gap_width);
1399 * @style: a #GtkStyle
1400 * @window: a #GdkWindow
1401 * @state_type: a state
1402 * @shadow_type: type of shadow to draw
1403 * @x: x origin of the rectangle
1404 * @y: y origin of the rectangle
1405 * @width: width of the rectangle
1406 * @height: width of the rectangle
1407 * @gap_side: side in which to leave the gap
1408 * @gap_x: starting position of the gap
1409 * @gap_width: width of the gap
1411 * Draws a box in @window using the given style and state and shadow type,
1412 * leaving a gap in one side.
1414 * Deprecated: Use gtk_paint_box_gap() instead.
1417 gtk_draw_box_gap (GtkStyle *style,
1419 GtkStateType state_type,
1420 GtkShadowType shadow_type,
1425 GtkPositionType gap_side,
1429 g_return_if_fail (GTK_IS_STYLE (style));
1430 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
1432 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side, gap_x, gap_width);
1436 * gtk_draw_extension:
1437 * @style: a #GtkStyle
1438 * @window: a #GdkWindow
1439 * @state_type: a state
1440 * @shadow_type: type of shadow to draw
1441 * @x: x origin of the extension
1442 * @y: y origin of the extension
1443 * @width: width of the extension
1444 * @height: width of the extension
1445 * @gap_side: the side on to which the extension is attached
1447 * Draws an extension, i.e. a notebook tab.
1449 * Deprecated: Use gtk_paint_extension() instead.
1452 gtk_draw_extension (GtkStyle *style,
1454 GtkStateType state_type,
1455 GtkShadowType shadow_type,
1460 GtkPositionType gap_side)
1462 g_return_if_fail (GTK_IS_STYLE (style));
1463 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
1465 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
1470 * @style: a #GtkStyle
1471 * @window: a #GdkWindow
1472 * @x: the x origin of the rectangle around which to draw a focus indicator
1473 * @y: the y origin of the rectangle around which to draw a focus indicator
1474 * @width: the width of the rectangle around which to draw a focus indicator
1475 * @height: the height of the rectangle around which to draw a focus indicator
1477 * Draws a focus indicator around the given rectangle on @window using the
1480 * Deprecated: Use gtk_paint_focus() instead.
1483 gtk_draw_focus (GtkStyle *style,
1490 g_return_if_fail (GTK_IS_STYLE (style));
1491 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
1493 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, width, height);
1497 gtk_draw_slider (GtkStyle *style,
1499 GtkStateType state_type,
1500 GtkShadowType shadow_type,
1505 GtkOrientation orientation)
1507 g_return_if_fail (GTK_IS_STYLE (style));
1508 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
1510 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1515 * @style: a #GtkStyle
1516 * @window: a #GdkWindow
1517 * @state_type: a state
1518 * @shadow_type: type of shadow to draw
1519 * @x: x origin of the handle
1520 * @y: y origin of the handle
1521 * @width: with of the handle
1522 * @height: height of the handle
1523 * @orientation: the orientation of the handle
1525 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
1527 * Deprecated: Use gtk_paint_handle() instead.
1530 gtk_draw_handle (GtkStyle *style,
1532 GtkStateType state_type,
1533 GtkShadowType shadow_type,
1538 GtkOrientation orientation)
1540 g_return_if_fail (GTK_IS_STYLE (style));
1541 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
1543 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1547 * gtk_draw_expander:
1548 * @style: a #GtkStyle
1549 * @window: a #GdkWindow
1550 * @state_type: a state
1551 * @x: the x position to draw the expander at
1552 * @y: the y position to draw the expander at
1553 * @expander_style: the style to draw the expander in
1555 * Draws an expander as used in #GtkTreeView.
1557 * Deprecated: Use gtk_paint_expander() instead.
1560 gtk_draw_expander (GtkStyle *style,
1562 GtkStateType state_type,
1565 GtkExpanderStyle expander_style)
1567 g_return_if_fail (GTK_IS_STYLE (style));
1568 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
1570 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
1572 x, y, expander_style);
1576 gtk_draw_layout (GtkStyle *style,
1578 GtkStateType state_type,
1582 PangoLayout *layout)
1584 g_return_if_fail (GTK_IS_STYLE (style));
1585 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
1587 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
1593 * gtk_draw_resize_grip:
1594 * @style: a #GtkStyle
1595 * @window: a #GdkWindow
1596 * @state_type: a state
1597 * @edge: the edge in which to draw the resize grip
1598 * @x: the x origin of the rectangle in which to draw the resize grip
1599 * @y: the y origin of the rectangle in which to draw the resize grip
1600 * @width: the width of the rectangle in which to draw the resize grip
1601 * @height: the height of the rectangle in which to draw the resize grip
1603 * Draws a resize grip in the given rectangle on @window using the given
1606 * Deprecated: Use gtk_paint_resize_grip() instead.
1609 gtk_draw_resize_grip (GtkStyle *style,
1611 GtkStateType state_type,
1618 g_return_if_fail (GTK_IS_STYLE (style));
1619 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
1621 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
1624 x, y, width, height);
1629 * gtk_style_set_background:
1630 * @style: a #GtkStyle
1631 * @window: a #GdkWindow
1632 * @state_type: a state
1634 * Sets the background of @window to the background color or pixmap
1635 * specified by @style for the given state.
1638 gtk_style_set_background (GtkStyle *style,
1640 GtkStateType state_type)
1642 g_return_if_fail (GTK_IS_STYLE (style));
1643 g_return_if_fail (window != NULL);
1645 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1648 /* Default functions */
1650 gtk_style_real_clone (GtkStyle *style)
1652 return GTK_STYLE (g_object_new (G_OBJECT_TYPE (style), NULL));
1656 gtk_style_real_copy (GtkStyle *style,
1661 for (i = 0; i < 5; i++)
1663 style->fg[i] = src->fg[i];
1664 style->bg[i] = src->bg[i];
1665 style->text[i] = src->text[i];
1666 style->base[i] = src->base[i];
1668 style->bg_pixmap[i] = src->bg_pixmap[i];
1671 if (style->private_font)
1672 gdk_font_unref (style->private_font);
1673 style->private_font = src->private_font;
1674 if (style->private_font)
1675 gdk_font_ref (style->private_font);
1677 if (style->font_desc)
1678 pango_font_description_free (style->font_desc);
1680 style->font_desc = pango_font_description_copy (src->font_desc);
1682 style->font_desc = NULL;
1684 style->xthickness = src->xthickness;
1685 style->ythickness = src->ythickness;
1687 if (style->rc_style)
1688 gtk_rc_style_unref (style->rc_style);
1689 style->rc_style = src->rc_style;
1691 gtk_rc_style_ref (src->rc_style);
1693 /* don't copy, just clear cache */
1694 clear_property_cache (style);
1698 gtk_style_real_init_from_rc (GtkStyle *style,
1699 GtkRcStyle *rc_style)
1703 /* cache _should_ be still empty */
1704 clear_property_cache (style);
1706 if (rc_style->font_desc)
1707 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1709 for (i = 0; i < 5; i++)
1711 if (rc_style->color_flags[i] & GTK_RC_FG)
1712 style->fg[i] = rc_style->fg[i];
1713 if (rc_style->color_flags[i] & GTK_RC_BG)
1714 style->bg[i] = rc_style->bg[i];
1715 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1716 style->text[i] = rc_style->text[i];
1717 if (rc_style->color_flags[i] & GTK_RC_BASE)
1718 style->base[i] = rc_style->base[i];
1721 if (rc_style->xthickness >= 0)
1722 style->xthickness = rc_style->xthickness;
1723 if (rc_style->ythickness >= 0)
1724 style->ythickness = rc_style->ythickness;
1726 if (rc_style->icon_factories)
1730 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1732 iter = style->icon_factories;
1733 while (iter != NULL)
1735 g_object_ref (iter->data);
1736 iter = g_slist_next (iter);
1742 style_property_values_cmp (gconstpointer bsearch_node1,
1743 gconstpointer bsearch_node2)
1745 const PropertyValue *val1 = bsearch_node1;
1746 const PropertyValue *val2 = bsearch_node2;
1748 if (val1->widget_type == val2->widget_type)
1749 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1751 return val1->widget_type < val2->widget_type ? -1 : 1;
1755 _gtk_style_peek_property_value (GtkStyle *style,
1758 GtkRcPropertyParser parser)
1760 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1761 const GtkRcProperty *rcprop = NULL;
1764 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1765 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1766 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1767 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1769 key.widget_type = widget_type;
1772 /* need value cache array */
1773 if (!style->property_cache)
1774 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1777 pcache = bsearch (&key,
1778 style->property_cache->data, style->property_cache->len,
1779 sizeof (PropertyValue), style_property_values_cmp);
1781 return &pcache->value;
1785 while (i < style->property_cache->len &&
1786 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1789 g_array_insert_val (style->property_cache, i, key);
1790 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1792 /* cache miss, initialize value type, then set contents */
1793 g_param_spec_ref (pcache->pspec);
1794 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1796 /* value provided by rc style? */
1797 if (style->rc_style)
1799 GQuark prop_quark = g_quark_from_string (pspec->name);
1803 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1804 g_type_qname (widget_type),
1808 widget_type = g_type_parent (widget_type);
1810 while (g_type_is_a (widget_type, pspec->owner_type));
1813 /* when supplied by rc style, we need to convert */
1814 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1815 pspec, &pcache->value))
1817 gchar *contents = g_strdup_value_contents (&rcprop->value);
1819 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1821 g_type_name (pspec->owner_type), pspec->name,
1822 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1824 G_VALUE_TYPE_NAME (&rcprop->value));
1826 rcprop = NULL; /* needs default */
1829 /* not supplied by rc style (or conversion failed), revert to default */
1831 g_param_value_set_default (pspec, &pcache->value);
1833 return &pcache->value;
1837 load_bg_image (GdkColormap *colormap,
1839 const gchar *filename)
1841 if (strcmp (filename, "<parent>") == 0)
1842 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1845 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1852 gtk_style_real_realize (GtkStyle *style)
1854 GdkGCValues gc_values;
1855 GdkGCValuesMask gc_values_mask;
1859 for (i = 0; i < 5; i++)
1861 gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1862 gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1864 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1865 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1866 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1868 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1869 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1870 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1873 style->black.red = 0x0000;
1874 style->black.green = 0x0000;
1875 style->black.blue = 0x0000;
1876 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
1878 style->white.red = 0xffff;
1879 style->white.green = 0xffff;
1880 style->white.blue = 0xffff;
1881 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
1883 gc_values_mask = GDK_GC_FOREGROUND;
1885 gc_values.foreground = style->black;
1886 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1888 gc_values.foreground = style->white;
1889 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1891 for (i = 0; i < 5; i++)
1893 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1894 style->bg_pixmap[i] = load_bg_image (style->colormap,
1896 style->rc_style->bg_pixmap_name[i]);
1898 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
1899 g_warning ("unable to allocate color: ( %d %d %d )",
1900 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
1901 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
1902 g_warning ("unable to allocate color: ( %d %d %d )",
1903 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
1904 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
1905 g_warning ("unable to allocate color: ( %d %d %d )",
1906 style->light[i].red, style->light[i].green, style->light[i].blue);
1907 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
1908 g_warning ("unable to allocate color: ( %d %d %d )",
1909 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
1910 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
1911 g_warning ("unable to allocate color: ( %d %d %d )",
1912 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
1913 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
1914 g_warning ("unable to allocate color: ( %d %d %d )",
1915 style->text[i].red, style->text[i].green, style->text[i].blue);
1916 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
1917 g_warning ("unable to allocate color: ( %d %d %d )",
1918 style->base[i].red, style->base[i].green, style->base[i].blue);
1919 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
1920 g_warning ("unable to allocate color: ( %d %d %d )",
1921 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
1923 gc_values.foreground = style->fg[i];
1924 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1926 gc_values.foreground = style->bg[i];
1927 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1929 gc_values.foreground = style->light[i];
1930 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1932 gc_values.foreground = style->dark[i];
1933 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1935 gc_values.foreground = style->mid[i];
1936 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1938 gc_values.foreground = style->text[i];
1939 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1941 gc_values.foreground = style->base[i];
1942 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1944 gc_values.foreground = style->text_aa[i];
1945 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1950 gtk_style_real_unrealize (GtkStyle *style)
1954 gtk_gc_release (style->black_gc);
1955 gtk_gc_release (style->white_gc);
1957 for (i = 0; i < 5; i++)
1959 gtk_gc_release (style->fg_gc[i]);
1960 gtk_gc_release (style->bg_gc[i]);
1961 gtk_gc_release (style->light_gc[i]);
1962 gtk_gc_release (style->dark_gc[i]);
1963 gtk_gc_release (style->mid_gc[i]);
1964 gtk_gc_release (style->text_gc[i]);
1965 gtk_gc_release (style->base_gc[i]);
1966 gtk_gc_release (style->text_aa_gc[i]);
1968 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1969 g_object_unref (style->bg_pixmap[i]);
1972 gdk_colormap_free_colors (style->colormap, style->fg, 5);
1973 gdk_colormap_free_colors (style->colormap, style->bg, 5);
1974 gdk_colormap_free_colors (style->colormap, style->light, 5);
1975 gdk_colormap_free_colors (style->colormap, style->dark, 5);
1976 gdk_colormap_free_colors (style->colormap, style->mid, 5);
1977 gdk_colormap_free_colors (style->colormap, style->text, 5);
1978 gdk_colormap_free_colors (style->colormap, style->base, 5);
1979 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
1981 style_unrealize_cursor_gcs (style);
1985 gtk_style_real_set_background (GtkStyle *style,
1987 GtkStateType state_type)
1990 gint parent_relative;
1992 if (style->bg_pixmap[state_type])
1994 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1997 parent_relative = TRUE;
2001 pixmap = style->bg_pixmap[state_type];
2002 parent_relative = FALSE;
2005 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
2008 gdk_window_set_background (window, &style->bg[state_type]);
2012 * gtk_style_render_icon:
2013 * @style: a #GtkStyle
2014 * @source: the #GtkIconSource specifying the icon to render
2015 * @direction: a text direction
2017 * @size: the size to render the icon at. A size of (GtkIconSize)-1
2018 * means render at the size of the source and don't scale.
2019 * @widget: the widget
2020 * @detail: a style detail
2021 * @returns: a newly-created #GdkPixbuf containing the rendered icon
2023 * Renders the icon specified by @source at the given @size
2024 * according to the given parameters and returns the result in a
2028 gtk_style_render_icon (GtkStyle *style,
2029 const GtkIconSource *source,
2030 GtkTextDirection direction,
2034 const gchar *detail)
2038 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
2039 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
2041 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
2042 size, widget, detail);
2044 g_return_val_if_fail (pixbuf != NULL, NULL);
2049 /* Default functions */
2051 gtk_style_apply_default_background (GtkStyle *style,
2054 GtkStateType state_type,
2061 GdkRectangle new_rect, old_rect;
2067 old_rect.width = width;
2068 old_rect.height = height;
2070 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
2077 new_rect.width = width;
2078 new_rect.height = height;
2081 if (!style->bg_pixmap[state_type] ||
2082 GDK_IS_PIXMAP (window) ||
2083 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
2085 GdkGC *gc = style->bg_gc[state_type];
2087 if (style->bg_pixmap[state_type])
2089 gdk_gc_set_fill (gc, GDK_TILED);
2090 gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
2093 gdk_draw_rectangle (window, gc, TRUE,
2094 new_rect.x, new_rect.y, new_rect.width, new_rect.height);
2095 if (style->bg_pixmap[state_type])
2096 gdk_gc_set_fill (gc, GDK_SOLID);
2102 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2103 gdk_window_set_back_pixmap (window, NULL, TRUE);
2105 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
2108 gdk_window_clear_area (window,
2109 new_rect.x, new_rect.y,
2110 new_rect.width, new_rect.height);
2115 scale_or_ref (GdkPixbuf *src,
2119 if (width == gdk_pixbuf_get_width (src) &&
2120 height == gdk_pixbuf_get_height (src))
2122 return g_object_ref (src);
2126 return gdk_pixbuf_scale_simple (src,
2128 GDK_INTERP_BILINEAR);
2133 gtk_default_render_icon (GtkStyle *style,
2134 const GtkIconSource *source,
2135 GtkTextDirection direction,
2139 const gchar *detail)
2145 GdkPixbuf *base_pixbuf;
2147 GtkSettings *settings;
2149 /* Oddly, style can be NULL in this function, because
2150 * GtkIconSet can be used without a style and if so
2151 * it uses this function.
2154 base_pixbuf = gtk_icon_source_get_pixbuf (source);
2156 g_return_val_if_fail (base_pixbuf != NULL, NULL);
2158 if (widget && gtk_widget_has_screen (widget))
2160 screen = gtk_widget_get_screen (widget);
2161 settings = gtk_settings_get_for_screen (screen);
2163 else if (style->colormap)
2165 screen = gdk_colormap_get_screen (style->colormap);
2166 settings = gtk_settings_get_for_screen (screen);
2170 settings = gtk_settings_get_default ();
2171 GTK_NOTE (MULTIHEAD,
2172 g_warning ("Using the default screen for gtk_default_render_icon()"));
2176 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
2178 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2182 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2185 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2186 scaled = scale_or_ref (base_pixbuf, width, height);
2188 scaled = g_object_ref (base_pixbuf);
2190 /* If the state was wildcarded, then generate a state. */
2191 if (gtk_icon_source_get_state_wildcarded (source))
2193 if (state == GTK_STATE_INSENSITIVE)
2195 stated = gdk_pixbuf_copy (scaled);
2197 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2200 g_object_unref (scaled);
2202 else if (state == GTK_STATE_PRELIGHT)
2204 stated = gdk_pixbuf_copy (scaled);
2206 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2209 g_object_unref (scaled);
2223 sanitize_size (GdkWindow *window,
2227 if ((*width == -1) && (*height == -1))
2228 gdk_drawable_get_size (window, width, height);
2229 else if (*width == -1)
2230 gdk_drawable_get_size (window, width, NULL);
2231 else if (*height == -1)
2232 gdk_drawable_get_size (window, NULL, height);
2236 get_indicator_for_screen (GdkDrawable *drawable,
2240 GdkScreen *screen = gdk_drawable_get_screen (drawable);
2244 tmp_list = indicator_parts[part].bmap_list;
2247 bitmap = tmp_list->data;
2249 if (gdk_drawable_get_screen (bitmap) == screen)
2252 tmp_list = tmp_list->next;
2255 bitmap = gdk_bitmap_create_from_data (drawable,
2256 (gchar *)indicator_parts[part].bits,
2257 INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
2258 indicator_parts[part].bmap_list = g_list_prepend (indicator_parts[part].bmap_list, bitmap);
2264 draw_part (GdkDrawable *drawable,
2272 gdk_gc_set_clip_rectangle (gc, area);
2274 gdk_gc_set_ts_origin (gc, x, y);
2275 gdk_gc_set_stipple (gc, get_indicator_for_screen (drawable, part));
2276 gdk_gc_set_fill (gc, GDK_STIPPLED);
2278 gdk_draw_rectangle (drawable, gc, TRUE, x, y, INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
2280 gdk_gc_set_fill (gc, GDK_SOLID);
2283 gdk_gc_set_clip_rectangle (gc, NULL);
2287 gtk_default_draw_hline (GtkStyle *style,
2289 GtkStateType state_type,
2292 const gchar *detail,
2297 gint thickness_light;
2298 gint thickness_dark;
2301 g_return_if_fail (GTK_IS_STYLE (style));
2302 g_return_if_fail (window != NULL);
2304 thickness_light = style->ythickness / 2;
2305 thickness_dark = style->ythickness - thickness_light;
2309 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2310 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2313 if (detail && !strcmp (detail, "label"))
2315 if (state_type == GTK_STATE_INSENSITIVE)
2316 gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
2317 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
2321 for (i = 0; i < thickness_dark; i++)
2323 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
2324 gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
2327 y += thickness_dark;
2328 for (i = 0; i < thickness_light; i++)
2330 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
2331 gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i, y + i, x2, y + i);
2337 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2338 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2344 gtk_default_draw_vline (GtkStyle *style,
2346 GtkStateType state_type,
2349 const gchar *detail,
2354 gint thickness_light;
2355 gint thickness_dark;
2358 g_return_if_fail (GTK_IS_STYLE (style));
2359 g_return_if_fail (window != NULL);
2361 thickness_light = style->xthickness / 2;
2362 thickness_dark = style->xthickness - thickness_light;
2366 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2367 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2369 for (i = 0; i < thickness_dark; i++)
2371 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
2372 gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
2375 x += thickness_dark;
2376 for (i = 0; i < thickness_light; i++)
2378 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i - 1);
2379 gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
2383 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2384 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2389 draw_thin_shadow (GtkStyle *style,
2400 sanitize_size (window, &width, &height);
2402 gc1 = style->light_gc[state];
2403 gc2 = style->dark_gc[state];
2407 gdk_gc_set_clip_rectangle (gc1, area);
2408 gdk_gc_set_clip_rectangle (gc2, area);
2411 gdk_draw_line (window, gc1,
2412 x, y + height - 1, x + width - 1, y + height - 1);
2413 gdk_draw_line (window, gc1,
2414 x + width - 1, y, x + width - 1, y + height - 1);
2416 gdk_draw_line (window, gc2,
2417 x, y, x + width - 2, y);
2418 gdk_draw_line (window, gc2,
2419 x, y, x, y + height - 2);
2423 gdk_gc_set_clip_rectangle (gc1, NULL);
2424 gdk_gc_set_clip_rectangle (gc2, NULL);
2429 draw_spinbutton_shadow (GtkStyle *style,
2432 GtkTextDirection direction,
2439 sanitize_size (window, &width, &height);
2443 gdk_gc_set_clip_rectangle (style->black_gc, area);
2444 gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
2445 gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
2446 gdk_gc_set_clip_rectangle (style->light_gc[state], area);
2449 if (direction == GTK_TEXT_DIR_LTR)
2451 gdk_draw_line (window, style->dark_gc[state],
2452 x, y, x + width - 1, y);
2453 gdk_draw_line (window, style->black_gc,
2454 x, y + 1, x + width - 2, y + 1);
2455 gdk_draw_line (window, style->black_gc,
2456 x + width - 2, y + 2, x + width - 2, y + height - 3);
2457 gdk_draw_line (window, style->light_gc[state],
2458 x + width - 1, y + 1, x + width - 1, y + height - 2);
2459 gdk_draw_line (window, style->light_gc[state],
2460 x, y + height - 1, x + width - 1, y + height - 1);
2461 gdk_draw_line (window, style->bg_gc[state],
2462 x, y + height - 2, x + width - 2, y + height - 2);
2463 gdk_draw_line (window, style->black_gc,
2464 x, y + 2, x, y + height - 3);
2468 gdk_draw_line (window, style->dark_gc[state],
2469 x, y, x + width - 1, y);
2470 gdk_draw_line (window, style->dark_gc[state],
2471 x, y + 1, x, y + height - 1);
2472 gdk_draw_line (window, style->black_gc,
2473 x + 1, y + 1, x + width - 1, y + 1);
2474 gdk_draw_line (window, style->black_gc,
2475 x + 1, y + 2, x + 1, y + height - 2);
2476 gdk_draw_line (window, style->black_gc,
2477 x + width - 1, y + 2, x + width - 1, y + height - 3);
2478 gdk_draw_line (window, style->light_gc[state],
2479 x + 1, y + height - 1, x + width - 1, y + height - 1);
2480 gdk_draw_line (window, style->bg_gc[state],
2481 x + 2, y + height - 2, x + width - 1, y + height - 2);
2486 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2487 gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
2488 gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
2489 gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
2494 draw_menu_shadow (GtkStyle *style,
2503 if (style->ythickness > 0)
2505 if (style->ythickness > 1)
2507 gdk_draw_line (window, style->dark_gc[state],
2508 x + 1, y + height - 2, x + width - 2, y + height - 2);
2509 gdk_draw_line (window, style->black_gc,
2510 x, y + height - 1, x + width - 1, y + height - 1);
2514 gdk_draw_line (window, style->dark_gc[state],
2515 x + 1, y + height - 1, x + width - 1, y + height - 1);
2519 if (style->xthickness > 0)
2521 if (style->xthickness > 1)
2523 gdk_draw_line (window, style->dark_gc[state],
2524 x + width - 2, y + 1, x + width - 2, y + height - 2);
2526 gdk_draw_line (window, style->black_gc,
2527 x + width - 1, y, x + width - 1, y + height - 1);
2531 gdk_draw_line (window, style->dark_gc[state],
2532 x + width - 1, y + 1, x + width - 1, y + height - 1);
2536 /* Light around top and left */
2538 if (style->ythickness > 0)
2539 gdk_draw_line (window, style->black_gc,
2540 x, y, x + width - 2, y);
2541 if (style->xthickness > 0)
2542 gdk_draw_line (window, style->black_gc,
2543 x, y, x, y + height - 2);
2545 if (style->ythickness > 1)
2546 gdk_draw_line (window, style->light_gc[state],
2547 x + 1, y + 1, x + width - 3, y + 1);
2548 if (style->xthickness > 1)
2549 gdk_draw_line (window, style->light_gc[state],
2550 x + 1, y + 1, x + 1, y + height - 3);
2554 gtk_default_draw_shadow (GtkStyle *style,
2556 GtkStateType state_type,
2557 GtkShadowType shadow_type,
2560 const gchar *detail,
2568 gint thickness_light;
2569 gint thickness_dark;
2572 g_return_if_fail (GTK_IS_STYLE (style));
2573 g_return_if_fail (window != NULL);
2575 if (shadow_type == GTK_SHADOW_IN)
2577 if (detail && (strcmp (detail, "buttondefault") == 0))
2579 sanitize_size (window, &width, &height);
2581 gdk_draw_rectangle (window, style->black_gc, FALSE,
2582 x, y, width - 1, height - 1);
2586 if (detail && strcmp (detail, "trough") == 0)
2588 draw_thin_shadow (style, window, state_type, area,
2589 x, y, width, height);
2592 if (widget && GTK_IS_SPIN_BUTTON (widget) &&
2593 detail && strcmp (detail, "spinbutton") == 0)
2595 draw_spinbutton_shadow (style, window, state_type,
2596 gtk_widget_get_direction (widget), area, x, y, width, height);
2602 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
2604 draw_menu_shadow (style, window, state_type, area, x, y, width, height);
2608 sanitize_size (window, &width, &height);
2610 switch (shadow_type)
2612 case GTK_SHADOW_NONE:
2615 case GTK_SHADOW_ETCHED_IN:
2616 gc1 = style->light_gc[state_type];
2617 gc2 = style->dark_gc[state_type];
2619 case GTK_SHADOW_OUT:
2620 case GTK_SHADOW_ETCHED_OUT:
2621 gc1 = style->dark_gc[state_type];
2622 gc2 = style->light_gc[state_type];
2628 gdk_gc_set_clip_rectangle (gc1, area);
2629 gdk_gc_set_clip_rectangle (gc2, area);
2630 if (shadow_type == GTK_SHADOW_IN ||
2631 shadow_type == GTK_SHADOW_OUT)
2633 gdk_gc_set_clip_rectangle (style->black_gc, area);
2634 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2638 switch (shadow_type)
2640 case GTK_SHADOW_NONE:
2644 /* Light around right and bottom edge */
2646 if (style->ythickness > 0)
2647 gdk_draw_line (window, gc1,
2648 x, y + height - 1, x + width - 1, y + height - 1);
2649 if (style->xthickness > 0)
2650 gdk_draw_line (window, gc1,
2651 x + width - 1, y, x + width - 1, y + height - 1);
2653 if (style->ythickness > 1)
2654 gdk_draw_line (window, style->bg_gc[state_type],
2655 x + 1, y + height - 2, x + width - 2, y + height - 2);
2656 if (style->xthickness > 1)
2657 gdk_draw_line (window, style->bg_gc[state_type],
2658 x + width - 2, y + 1, x + width - 2, y + height - 2);
2660 /* Dark around left and top */
2662 if (style->ythickness > 1)
2663 gdk_draw_line (window, style->black_gc,
2664 x + 1, y + 1, x + width - 2, y + 1);
2665 if (style->xthickness > 1)
2666 gdk_draw_line (window, style->black_gc,
2667 x + 1, y + 1, x + 1, y + height - 2);
2669 if (style->ythickness > 0)
2670 gdk_draw_line (window, gc2,
2671 x, y, x + width - 1, y);
2672 if (style->xthickness > 0)
2673 gdk_draw_line (window, gc2,
2674 x, y, x, y + height - 1);
2677 case GTK_SHADOW_OUT:
2678 /* Dark around right and bottom edge */
2680 if (style->ythickness > 0)
2682 if (style->ythickness > 1)
2684 gdk_draw_line (window, gc1,
2685 x + 1, y + height - 2, x + width - 2, y + height - 2);
2686 gdk_draw_line (window, style->black_gc,
2687 x, y + height - 1, x + width - 1, y + height - 1);
2691 gdk_draw_line (window, gc1,
2692 x + 1, y + height - 1, x + width - 1, y + height - 1);
2696 if (style->xthickness > 0)
2698 if (style->xthickness > 1)
2700 gdk_draw_line (window, gc1,
2701 x + width - 2, y + 1, x + width - 2, y + height - 2);
2703 gdk_draw_line (window, style->black_gc,
2704 x + width - 1, y, x + width - 1, y + height - 1);
2708 gdk_draw_line (window, gc1,
2709 x + width - 1, y + 1, x + width - 1, y + height - 1);
2713 /* Light around top and left */
2715 if (style->ythickness > 0)
2716 gdk_draw_line (window, gc2,
2717 x, y, x + width - 2, y);
2718 if (style->xthickness > 0)
2719 gdk_draw_line (window, gc2,
2720 x, y, x, y + height - 2);
2722 if (style->ythickness > 1)
2723 gdk_draw_line (window, style->bg_gc[state_type],
2724 x + 1, y + 1, x + width - 3, y + 1);
2725 if (style->xthickness > 1)
2726 gdk_draw_line (window, style->bg_gc[state_type],
2727 x + 1, y + 1, x + 1, y + height - 3);
2730 case GTK_SHADOW_ETCHED_IN:
2731 case GTK_SHADOW_ETCHED_OUT:
2732 if (style->xthickness > 0)
2734 if (style->xthickness > 1)
2736 thickness_light = 1;
2739 for (i = 0; i < thickness_dark; i++)
2741 gdk_draw_line (window, gc1,
2745 y + height - i - 1);
2746 gdk_draw_line (window, gc2,
2750 y + height - i - 2);
2753 for (i = 0; i < thickness_light; i++)
2755 gdk_draw_line (window, gc1,
2756 x + thickness_dark + i,
2757 y + thickness_dark + i,
2758 x + thickness_dark + i,
2759 y + height - thickness_dark - i - 1);
2760 gdk_draw_line (window, gc2,
2761 x + width - thickness_light - i - 1,
2762 y + thickness_dark + i,
2763 x + width - thickness_light - i - 1,
2764 y + height - thickness_light - 1);
2769 gdk_draw_line (window,
2770 style->dark_gc[state_type],
2771 x, y, x, y + height);
2772 gdk_draw_line (window,
2773 style->dark_gc[state_type],
2774 x + width, y, x + width, y + height);
2778 if (style->ythickness > 0)
2780 if (style->ythickness > 1)
2782 thickness_light = 1;
2785 for (i = 0; i < thickness_dark; i++)
2787 gdk_draw_line (window, gc1,
2791 y + height - i - 1);
2793 gdk_draw_line (window, gc2,
2800 for (i = 0; i < thickness_light; i++)
2802 gdk_draw_line (window, gc1,
2803 x + thickness_dark + i,
2804 y + thickness_dark + i,
2805 x + width - thickness_dark - i - 2,
2806 y + thickness_dark + i);
2808 gdk_draw_line (window, gc2,
2809 x + thickness_dark + i,
2810 y + height - thickness_light - i - 1,
2811 x + width - thickness_light - 1,
2812 y + height - thickness_light - i - 1);
2817 gdk_draw_line (window,
2818 style->dark_gc[state_type],
2819 x, y, x + width, y);
2820 gdk_draw_line (window,
2821 style->dark_gc[state_type],
2822 x, y + height, x + width, y + height);
2829 if (shadow_type == GTK_SHADOW_IN &&
2830 widget && GTK_IS_SPIN_BUTTON (widget) &&
2831 detail && strcmp (detail, "entry") == 0)
2833 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
2835 gdk_draw_line (window,
2836 style->base_gc[state_type],
2837 x + width - 1, y + 2,
2838 x + width - 1, y + height - 3);
2839 gdk_draw_line (window,
2840 style->base_gc[state_type],
2841 x + width - 2, y + 2,
2842 x + width - 2, y + height - 3);
2843 gdk_draw_point (window,
2845 x + width - 1, y + 1);
2846 gdk_draw_point (window,
2847 style->bg_gc[state_type],
2848 x + width - 1, y + height - 2);
2852 gdk_draw_line (window,
2853 style->base_gc[state_type],
2856 gdk_draw_line (window,
2857 style->base_gc[state_type],
2859 x + 1, y + height - 3);
2860 gdk_draw_point (window,
2863 gdk_draw_line (window,
2864 style->bg_gc[state_type],
2866 x + 1, y + height - 2);
2867 gdk_draw_point (window,
2868 style->light_gc[state_type],
2876 gdk_gc_set_clip_rectangle (gc1, NULL);
2877 gdk_gc_set_clip_rectangle (gc2, NULL);
2878 if (shadow_type == GTK_SHADOW_IN ||
2879 shadow_type == GTK_SHADOW_OUT)
2881 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2882 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2888 gtk_default_draw_polygon (GtkStyle *style,
2890 GtkStateType state_type,
2891 GtkShadowType shadow_type,
2894 const gchar *detail,
2899 static const gdouble pi_over_4 = G_PI_4;
2900 static const gdouble pi_3_over_4 = G_PI_4 * 3;
2910 g_return_if_fail (GTK_IS_STYLE (style));
2911 g_return_if_fail (window != NULL);
2912 g_return_if_fail (points != NULL);
2914 switch (shadow_type)
2917 gc1 = style->bg_gc[state_type];
2918 gc2 = style->dark_gc[state_type];
2919 gc3 = style->light_gc[state_type];
2920 gc4 = style->black_gc;
2922 case GTK_SHADOW_ETCHED_IN:
2923 gc1 = style->light_gc[state_type];
2924 gc2 = style->dark_gc[state_type];
2925 gc3 = style->dark_gc[state_type];
2926 gc4 = style->light_gc[state_type];
2928 case GTK_SHADOW_OUT:
2929 gc1 = style->dark_gc[state_type];
2930 gc2 = style->light_gc[state_type];
2931 gc3 = style->black_gc;
2932 gc4 = style->bg_gc[state_type];
2934 case GTK_SHADOW_ETCHED_OUT:
2935 gc1 = style->dark_gc[state_type];
2936 gc2 = style->light_gc[state_type];
2937 gc3 = style->light_gc[state_type];
2938 gc4 = style->dark_gc[state_type];
2946 gdk_gc_set_clip_rectangle (gc1, area);
2947 gdk_gc_set_clip_rectangle (gc2, area);
2948 gdk_gc_set_clip_rectangle (gc3, area);
2949 gdk_gc_set_clip_rectangle (gc4, area);
2953 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
2957 for (i = 0; i < npoints; i++)
2959 if ((points[i].x == points[i+1].x) &&
2960 (points[i].y == points[i+1].y))
2966 angle = atan2 (points[i+1].y - points[i].y,
2967 points[i+1].x - points[i].x);
2970 if ((angle > -pi_3_over_4) && (angle < pi_over_4))
2972 if (angle > -pi_over_4)
2983 gdk_draw_line (window, gc1,
2984 points[i].x-xadjust, points[i].y-yadjust,
2985 points[i+1].x-xadjust, points[i+1].y-yadjust);
2986 gdk_draw_line (window, gc3,
2987 points[i].x, points[i].y,
2988 points[i+1].x, points[i+1].y);
2992 if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
3003 gdk_draw_line (window, gc4,
3004 points[i].x+xadjust, points[i].y+yadjust,
3005 points[i+1].x+xadjust, points[i+1].y+yadjust);
3006 gdk_draw_line (window, gc2,
3007 points[i].x, points[i].y,
3008 points[i+1].x, points[i+1].y);
3014 gdk_gc_set_clip_rectangle (gc1, NULL);
3015 gdk_gc_set_clip_rectangle (gc2, NULL);
3016 gdk_gc_set_clip_rectangle (gc3, NULL);
3017 gdk_gc_set_clip_rectangle (gc4, NULL);
3022 draw_arrow (GdkWindow *window,
3025 GtkArrowType arrow_type,
3034 gdk_gc_set_clip_rectangle (gc, area);
3036 if (arrow_type == GTK_ARROW_DOWN)
3038 for (i = 0, j = 0; i < height; i++, j++)
3039 gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
3041 else if (arrow_type == GTK_ARROW_UP)
3043 for (i = height - 1, j = 0; i >= 0; i--, j++)
3044 gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
3046 else if (arrow_type == GTK_ARROW_LEFT)
3048 for (i = width - 1, j = 0; i >= 0; i--, j++)
3049 gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
3051 else if (arrow_type == GTK_ARROW_RIGHT)
3053 for (i = 0, j = 0; i < width; i++, j++)
3054 gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
3058 gdk_gc_set_clip_rectangle (gc, NULL);
3062 calculate_arrow_geometry (GtkArrowType arrow_type,
3074 case GTK_ARROW_DOWN:
3084 if (arrow_type == GTK_ARROW_DOWN)
3086 if (*height % 2 == 1 || h % 2 == 0)
3091 if (*height % 2 == 0 || h % 2 == 0)
3096 case GTK_ARROW_RIGHT:
3097 case GTK_ARROW_LEFT:
3107 if (arrow_type == GTK_ARROW_RIGHT)
3109 if (*width % 2 == 1 || w % 2 == 0)
3114 if (*width % 2 == 0 || w % 2 == 0)
3120 /* should not be reached */
3124 *x += (*width - w) / 2;
3125 *y += (*height - h) / 2;
3131 gtk_default_draw_arrow (GtkStyle *style,
3134 GtkShadowType shadow,
3137 const gchar *detail,
3138 GtkArrowType arrow_type,
3145 gint original_width, original_x;
3147 sanitize_size (window, &width, &height);
3149 original_width = width;
3152 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
3154 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
3157 if (state == GTK_STATE_INSENSITIVE)
3158 draw_arrow (window, style->white_gc, area, arrow_type,
3159 x + 1, y + 1, width, height);
3160 draw_arrow (window, style->fg_gc[state], area, arrow_type,
3161 x, y, width, height);
3165 gtk_default_draw_diamond (GtkStyle *style,
3167 GtkStateType state_type,
3168 GtkShadowType shadow_type,
3171 const gchar *detail,
3179 GdkGC *outer_nw = NULL;
3180 GdkGC *outer_ne = NULL;
3181 GdkGC *outer_sw = NULL;
3182 GdkGC *outer_se = NULL;
3183 GdkGC *middle_nw = NULL;
3184 GdkGC *middle_ne = NULL;
3185 GdkGC *middle_sw = NULL;
3186 GdkGC *middle_se = NULL;
3187 GdkGC *inner_nw = NULL;
3188 GdkGC *inner_ne = NULL;
3189 GdkGC *inner_sw = NULL;
3190 GdkGC *inner_se = NULL;
3192 g_return_if_fail (GTK_IS_STYLE (style));
3193 g_return_if_fail (window != NULL);
3195 sanitize_size (window, &width, &height);
3197 half_width = width / 2;
3198 half_height = height / 2;
3202 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3203 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
3204 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3205 gdk_gc_set_clip_rectangle (style->black_gc, area);
3208 switch (shadow_type)
3211 inner_sw = inner_se = style->bg_gc[state_type];
3212 middle_sw = middle_se = style->light_gc[state_type];
3213 outer_sw = outer_se = style->light_gc[state_type];
3214 inner_nw = inner_ne = style->black_gc;
3215 middle_nw = middle_ne = style->dark_gc[state_type];
3216 outer_nw = outer_ne = style->dark_gc[state_type];
3219 case GTK_SHADOW_OUT:
3220 inner_sw = inner_se = style->dark_gc[state_type];
3221 middle_sw = middle_se = style->dark_gc[state_type];
3222 outer_sw = outer_se = style->black_gc;
3223 inner_nw = inner_ne = style->bg_gc[state_type];
3224 middle_nw = middle_ne = style->light_gc[state_type];
3225 outer_nw = outer_ne = style->light_gc[state_type];
3228 case GTK_SHADOW_ETCHED_IN:
3229 inner_sw = inner_se = style->bg_gc[state_type];
3230 middle_sw = middle_se = style->dark_gc[state_type];
3231 outer_sw = outer_se = style->light_gc[state_type];
3232 inner_nw = inner_ne = style->bg_gc[state_type];
3233 middle_nw = middle_ne = style->light_gc[state_type];
3234 outer_nw = outer_ne = style->dark_gc[state_type];
3237 case GTK_SHADOW_ETCHED_OUT:
3238 inner_sw = inner_se = style->bg_gc[state_type];
3239 middle_sw = middle_se = style->light_gc[state_type];
3240 outer_sw = outer_se = style->dark_gc[state_type];
3241 inner_nw = inner_ne = style->bg_gc[state_type];
3242 middle_nw = middle_ne = style->dark_gc[state_type];
3243 outer_nw = outer_ne = style->light_gc[state_type];
3253 gdk_draw_line (window, inner_sw,
3254 x + 2, y + half_height,
3255 x + half_width, y + height - 2);
3256 gdk_draw_line (window, inner_se,
3257 x + half_width, y + height - 2,
3258 x + width - 2, y + half_height);
3259 gdk_draw_line (window, middle_sw,
3260 x + 1, y + half_height,
3261 x + half_width, y + height - 1);
3262 gdk_draw_line (window, middle_se,
3263 x + half_width, y + height - 1,
3264 x + width - 1, y + half_height);
3265 gdk_draw_line (window, outer_sw,
3267 x + half_width, y + height);
3268 gdk_draw_line (window, outer_se,
3269 x + half_width, y + height,
3270 x + width, y + half_height);
3272 gdk_draw_line (window, inner_nw,
3273 x + 2, y + half_height,
3274 x + half_width, y + 2);
3275 gdk_draw_line (window, inner_ne,
3276 x + half_width, y + 2,
3277 x + width - 2, y + half_height);
3278 gdk_draw_line (window, middle_nw,
3279 x + 1, y + half_height,
3280 x + half_width, y + 1);
3281 gdk_draw_line (window, middle_ne,
3282 x + half_width, y + 1,
3283 x + width - 1, y + half_height);
3284 gdk_draw_line (window, outer_nw,
3287 gdk_draw_line (window, outer_ne,
3289 x + width, y + half_height);
3294 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3295 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
3296 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3297 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3302 gtk_default_draw_string (GtkStyle *style,
3304 GtkStateType state_type,
3307 const gchar *detail,
3310 const gchar *string)
3312 GdkDisplay *display;
3314 g_return_if_fail (GTK_IS_STYLE (style));
3315 g_return_if_fail (window != NULL);
3317 display = gdk_drawable_get_display (window);
3321 gdk_gc_set_clip_rectangle (style->white_gc, area);
3322 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
3325 if (state_type == GTK_STATE_INSENSITIVE)
3326 gdk_draw_string (window,
3327 gtk_style_get_font_internal (style),
3328 style->white_gc, x + 1, y + 1, string);
3330 gdk_draw_string (window,
3331 gtk_style_get_font_internal (style),
3332 style->fg_gc[state_type], x, y, string);
3336 gdk_gc_set_clip_rectangle (style->white_gc, NULL);
3337 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
3342 option_menu_get_props (GtkWidget *widget,
3343 GtkRequisition *indicator_size,
3344 GtkBorder *indicator_spacing)
3346 GtkRequisition *tmp_size = NULL;
3347 GtkBorder *tmp_spacing = NULL;
3350 gtk_widget_style_get (widget,
3351 "indicator_size", &tmp_size,
3352 "indicator_spacing", &tmp_spacing,
3357 *indicator_size = *tmp_size;
3361 *indicator_size = default_option_indicator_size;
3365 *indicator_spacing = *tmp_spacing;
3366 g_free (tmp_spacing);
3369 *indicator_spacing = default_option_indicator_spacing;
3373 gtk_default_draw_box (GtkStyle *style,
3375 GtkStateType state_type,
3376 GtkShadowType shadow_type,
3379 const gchar *detail,
3385 gboolean is_spinbutton_box = FALSE;
3387 g_return_if_fail (GTK_IS_STYLE (style));
3388 g_return_if_fail (window != NULL);
3390 sanitize_size (window, &width, &height);
3392 if (widget && GTK_IS_SPIN_BUTTON (widget) && detail)
3394 if (strcmp (detail, "spinbutton_up") == 0)
3400 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
3405 is_spinbutton_box = TRUE;
3407 else if (strcmp (detail, "spinbutton_down") == 0)
3412 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
3417 is_spinbutton_box = TRUE;
3421 if (!style->bg_pixmap[state_type] ||
3422 GDK_IS_PIXMAP (window))
3424 GdkGC *gc = style->bg_gc[state_type];
3426 if (state_type == GTK_STATE_SELECTED && strcmp (detail, "paned") == 0)
3428 if (!GTK_WIDGET_HAS_FOCUS (widget))
3429 gc = style->base_gc[GTK_STATE_ACTIVE];
3433 gdk_gc_set_clip_rectangle (gc, area);
3435 gdk_draw_rectangle (window, gc, TRUE,
3436 x, y, width, height);
3438 gdk_gc_set_clip_rectangle (gc, NULL);
3441 gtk_style_apply_default_background (style, window,
3442 widget && !GTK_WIDGET_NO_WINDOW (widget),
3443 state_type, area, x, y, width, height);
3445 if (is_spinbutton_box)
3450 lower_gc = style->dark_gc[state_type];
3451 if (shadow_type == GTK_SHADOW_OUT)
3452 upper_gc = style->light_gc[state_type];
3454 upper_gc = style->dark_gc[state_type];
3458 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3459 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3462 gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
3463 gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
3467 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3468 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3473 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
3474 x, y, width, height);
3476 if (detail && strcmp (detail, "optionmenu") == 0)
3478 GtkRequisition indicator_size;
3479 GtkBorder indicator_spacing;
3482 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3484 sanitize_size (window, &width, &height);
3486 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
3487 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
3489 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
3491 gtk_paint_vline (style, window, state_type, area, widget,
3493 y + style->ythickness + 1,
3494 y + height - style->ythickness - 3,
3500 get_darkened_gc (GdkWindow *window,
3504 GdkColor src = *color;
3505 GdkColor shaded = *color;
3508 gc = gdk_gc_new (window);
3510 while (darken_count)
3512 gtk_style_shade (&src, &shaded, 0.93);
3517 gdk_gc_set_rgb_fg_color (gc, &shaded);
3523 gtk_default_draw_flat_box (GtkStyle *style,
3525 GtkStateType state_type,
3526 GtkShadowType shadow_type,
3529 const gchar *detail,
3536 GdkGC *freeme = NULL;
3538 g_return_if_fail (GTK_IS_STYLE (style));
3539 g_return_if_fail (window != NULL);
3541 sanitize_size (window, &width, &height);
3545 if (state_type == GTK_STATE_SELECTED)
3547 if (!strcmp ("text", detail))
3548 gc1 = style->bg_gc[GTK_STATE_SELECTED];
3549 else if (!strncmp ("cell_even", detail, strlen ("cell_even")) ||
3550 !strncmp ("cell_odd", detail, strlen ("cell_odd")))
3552 /* This has to be really broken; alex made me do it. -jrb */
3553 if (GTK_WIDGET_HAS_FOCUS (widget))
3554 gc1 = style->base_gc[state_type];
3556 gc1 = style->base_gc[GTK_STATE_ACTIVE];
3560 gc1 = style->bg_gc[state_type];
3565 if (!strcmp ("viewportbin", detail))
3566 gc1 = style->bg_gc[GTK_STATE_NORMAL];
3567 else if (!strcmp ("entry_bg", detail))
3568 gc1 = style->base_gc[state_type];
3570 /* For trees: even rows are base color, odd rows are a shade of
3571 * the base color, the sort column is a shade of the original color
3575 else if (!strcmp ("cell_even", detail) ||
3576 !strcmp ("cell_odd", detail) ||
3577 !strcmp ("cell_even_ruled", detail))
3579 GdkColor *color = NULL;
3581 gtk_widget_style_get (widget,
3582 "even_row_color", &color,
3587 freeme = get_darkened_gc (window, color, 0);
3590 gdk_color_free (color);
3593 gc1 = style->base_gc[state_type];
3595 else if (!strcmp ("cell_odd_ruled", detail))
3599 gtk_widget_style_get (widget,
3600 "odd_row_color", &color,
3605 freeme = get_darkened_gc (window, color, 0);
3608 gdk_color_free (color);
3612 gtk_widget_style_get (widget,
3613 "even_row_color", &color,
3618 freeme = get_darkened_gc (window, color, 1);
3619 gdk_color_free (color);
3622 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3626 else if (!strcmp ("cell_even_sorted", detail) ||
3627 !strcmp ("cell_odd_sorted", detail) ||
3628 !strcmp ("cell_even_ruled_sorted", detail))
3630 GdkColor *color = NULL;
3632 if (!strcmp ("cell_odd_sorted", detail))
3633 gtk_widget_style_get (widget,
3634 "odd_row_color", &color,
3637 gtk_widget_style_get (widget,
3638 "even_row_color", &color,
3643 freeme = get_darkened_gc (window, color, 1);
3646 gdk_color_free (color);
3650 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3654 else if (!strcmp ("cell_odd_ruled_sorted", detail))
3656 GdkColor *color = NULL;
3658 gtk_widget_style_get (widget,
3659 "odd_row_color", &color,
3664 freeme = get_darkened_gc (window, color, 1);
3667 gdk_color_free (color);
3671 gtk_widget_style_get (widget,
3672 "even_row_color", &color,
3677 freeme = get_darkened_gc (window, color, 2);
3678 gdk_color_free (color);
3681 freeme = get_darkened_gc (window, &style->base[state_type], 2);
3686 gc1 = style->bg_gc[state_type];
3690 gc1 = style->bg_gc[state_type];
3692 if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
3693 GDK_IS_PIXMAP (window))
3696 gdk_gc_set_clip_rectangle (gc1, area);
3698 gdk_draw_rectangle (window, gc1, TRUE,
3699 x, y, width, height);
3701 if (detail && !strcmp ("tooltip", detail))
3702 gdk_draw_rectangle (window, style->black_gc, FALSE,
3703 x, y, width - 1, height - 1);
3706 gdk_gc_set_clip_rectangle (gc1, NULL);
3709 gtk_style_apply_default_background (style, window,
3710 widget && !GTK_WIDGET_NO_WINDOW (widget),
3711 state_type, area, x, y, width, height);
3715 g_object_unref (freeme);
3719 create_aa_gc (GdkWindow *window, GtkStyle *style, GtkStateType state_type)
3722 GdkGC *gc = gdk_gc_new (window);
3724 aa_color.red = (style->fg[state_type].red + style->bg[state_type].red) / 2;
3725 aa_color.green = (style->fg[state_type].green + style->bg[state_type].green) / 2;
3726 aa_color.blue = (style->fg[state_type].blue + style->bg[state_type].blue) / 2;
3728 gdk_gc_set_rgb_fg_color (gc, &aa_color);
3734 gtk_default_draw_check (GtkStyle *style,
3736 GtkStateType state_type,
3737 GtkShadowType shadow_type,
3740 const gchar *detail,
3746 if (detail && strcmp (detail, "cellcheck") == 0)
3749 gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], area);
3750 gdk_draw_rectangle (window,
3751 widget->style->base_gc[state_type],
3757 gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], NULL);
3758 gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], area);
3760 gdk_draw_rectangle (window,
3761 widget->style->text_gc[state_type],
3766 gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], NULL);
3768 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3769 y -= (((1 + INDICATOR_PART_SIZE - height) / 2) - 1);
3770 if (shadow_type == GTK_SHADOW_IN)
3772 draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT);
3773 draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA);
3775 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3777 draw_part (window, style->text_gc[state_type], area, x, y, CHECK_INCONSISTENT_TEXT);
3782 GdkGC *free_me = NULL;
3788 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3789 y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3791 if (strcmp (detail, "check") == 0) /* Menu item */
3793 text_gc = style->fg_gc[state_type];
3794 base_gc = style->bg_gc[state_type];
3795 aa_gc = free_me = create_aa_gc (window, style, state_type);
3799 if (state_type == GTK_STATE_ACTIVE)
3801 text_gc = style->fg_gc[state_type];
3802 base_gc = style->bg_gc[state_type];
3803 aa_gc = free_me = create_aa_gc (window, style, state_type);
3807 text_gc = style->text_gc[state_type];
3808 base_gc = style->base_gc[state_type];
3809 aa_gc = style->text_aa_gc[state_type];
3812 draw_part (window, base_gc, area, x, y, CHECK_BASE);
3813 draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
3814 draw_part (window, style->dark_gc[state_type], area, x, y, CHECK_DARK);
3815 draw_part (window, style->mid_gc[state_type], area, x, y, CHECK_MID);
3816 draw_part (window, style->light_gc[state_type], area, x, y, CHECK_LIGHT);
3819 if (shadow_type == GTK_SHADOW_IN)
3821 draw_part (window, text_gc, area, x, y, CHECK_TEXT);
3822 draw_part (window, aa_gc, area, x, y, CHECK_AA);
3824 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3826 draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT);
3830 g_object_unref (free_me);
3835 gtk_default_draw_option (GtkStyle *style,
3837 GtkStateType state_type,
3838 GtkShadowType shadow_type,
3841 const gchar *detail,
3847 if (detail && strcmp (detail, "cellradio") == 0)
3850 gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], area);
3851 gdk_draw_arc (window,
3852 widget->style->fg_gc[state_type],
3859 if (shadow_type == GTK_SHADOW_IN)
3861 gdk_draw_arc (window,
3862 widget->style->fg_gc[state_type],
3870 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3872 draw_part (window, widget->style->fg_gc[state_type],
3873 area, x, y, CHECK_INCONSISTENT_TEXT);
3876 gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], NULL);
3880 GdkGC *free_me = NULL;
3886 x -= (1 + INDICATOR_PART_SIZE - width) / 2;
3887 y -= (1 + INDICATOR_PART_SIZE - height) / 2;
3889 if (strcmp (detail, "option") == 0) /* Menu item */
3891 text_gc = style->fg_gc[state_type];
3892 base_gc = style->bg_gc[state_type];
3893 aa_gc = free_me = create_aa_gc (window, style, state_type);
3897 if (state_type == GTK_STATE_ACTIVE)
3899 text_gc = style->fg_gc[state_type];
3900 base_gc = style->bg_gc[state_type];
3901 aa_gc = free_me = create_aa_gc (window, style, state_type);
3905 text_gc = style->text_gc[state_type];
3906 base_gc = style->base_gc[state_type];
3907 aa_gc = style->text_aa_gc[state_type];
3910 draw_part (window, base_gc, area, x, y, RADIO_BASE);
3911 draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
3912 draw_part (window, style->dark_gc[state_type], area, x, y, RADIO_DARK);
3913 draw_part (window, style->mid_gc[state_type], area, x, y, RADIO_MID);
3914 draw_part (window, style->light_gc[state_type], area, x, y, RADIO_LIGHT);
3917 if (shadow_type == GTK_SHADOW_IN)
3919 draw_part (window, text_gc, area, x, y, RADIO_TEXT);
3921 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3923 if (strcmp (detail, "option") == 0) /* Menu item */
3925 draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT);
3929 draw_part (window, text_gc, area, x, y, RADIO_INCONSISTENT_TEXT);
3930 draw_part (window, aa_gc, area, x, y, RADIO_INCONSISTENT_AA);
3935 g_object_unref (free_me);
3940 gtk_default_draw_tab (GtkStyle *style,
3942 GtkStateType state_type,
3943 GtkShadowType shadow_type,
3946 const gchar *detail,
3952 #define ARROW_SPACE 4
3954 GtkRequisition indicator_size;
3955 GtkBorder indicator_spacing;
3958 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3960 indicator_size.width += (indicator_size.width % 2) - 1;
3961 arrow_height = indicator_size.width / 2 + 1;
3963 x += (width - indicator_size.width) / 2;
3964 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
3966 if (state_type == GTK_STATE_INSENSITIVE)
3968 draw_arrow (window, style->white_gc, area,
3969 GTK_ARROW_UP, x + 1, y + 1,
3970 indicator_size.width, arrow_height);
3972 draw_arrow (window, style->white_gc, area,
3973 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3974 indicator_size.width, arrow_height);
3977 draw_arrow (window, style->fg_gc[state_type], area,
3979 indicator_size.width, arrow_height);
3982 draw_arrow (window, style->fg_gc[state_type], area,
3983 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3984 indicator_size.width, arrow_height);
3988 gtk_default_draw_shadow_gap (GtkStyle *style,
3990 GtkStateType state_type,
3991 GtkShadowType shadow_type,
3994 const gchar *detail,
3999 GtkPositionType gap_side,
4008 g_return_if_fail (GTK_IS_STYLE (style));
4009 g_return_if_fail (window != NULL);
4011 sanitize_size (window, &width, &height);
4013 switch (shadow_type)
4015 case GTK_SHADOW_NONE:
4018 gc1 = style->dark_gc[state_type];
4019 gc2 = style->black_gc;
4020 gc3 = style->bg_gc[state_type];
4021 gc4 = style->light_gc[state_type];
4023 case GTK_SHADOW_ETCHED_IN:
4024 gc1 = style->dark_gc[state_type];
4025 gc2 = style->light_gc[state_type];
4026 gc3 = style->dark_gc[state_type];
4027 gc4 = style->light_gc[state_type];
4029 case GTK_SHADOW_OUT:
4030 gc1 = style->light_gc[state_type];
4031 gc2 = style->bg_gc[state_type];
4032 gc3 = style->dark_gc[state_type];
4033 gc4 = style->black_gc;
4035 case GTK_SHADOW_ETCHED_OUT:
4036 gc1 = style->light_gc[state_type];
4037 gc2 = style->dark_gc[state_type];
4038 gc3 = style->light_gc[state_type];
4039 gc4 = style->dark_gc[state_type];
4044 gdk_gc_set_clip_rectangle (gc1, area);
4045 gdk_gc_set_clip_rectangle (gc2, area);
4046 gdk_gc_set_clip_rectangle (gc3, area);
4047 gdk_gc_set_clip_rectangle (gc4, area);
4050 switch (shadow_type)
4052 case GTK_SHADOW_NONE:
4054 case GTK_SHADOW_OUT:
4055 case GTK_SHADOW_ETCHED_IN:
4056 case GTK_SHADOW_ETCHED_OUT:
4060 gdk_draw_line (window, gc1,
4061 x, y, x, y + height - 1);
4062 gdk_draw_line (window, gc2,
4063 x + 1, y, x + 1, y + height - 2);
4065 gdk_draw_line (window, gc3,
4066 x + 1, y + height - 2, x + width - 2, y + height - 2);
4067 gdk_draw_line (window, gc3,
4068 x + width - 2, y, x + width - 2, y + height - 2);
4069 gdk_draw_line (window, gc4,
4070 x, y + height - 1, x + width - 1, y + height - 1);
4071 gdk_draw_line (window, gc4,
4072 x + width - 1, y, x + width - 1, y + height - 1);
4075 gdk_draw_line (window, gc1,
4076 x, y, x + gap_x - 1, y);
4077 gdk_draw_line (window, gc2,
4078 x + 1, y + 1, x + gap_x - 1, y + 1);
4079 gdk_draw_line (window, gc2,
4080 x + gap_x, y, x + gap_x, y);
4082 if ((width - (gap_x + gap_width)) > 0)
4084 gdk_draw_line (window, gc1,
4085 x + gap_x + gap_width, y, x + width - 2, y);
4086 gdk_draw_line (window, gc2,
4087 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
4088 gdk_draw_line (window, gc2,
4089 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4092 case GTK_POS_BOTTOM:
4093 gdk_draw_line (window, gc1,
4094 x, y, x + width - 1, y);
4095 gdk_draw_line (window, gc1,
4096 x, y, x, y + height - 1);
4097 gdk_draw_line (window, gc2,
4098 x + 1, y + 1, x + width - 2, y + 1);
4099 gdk_draw_line (window, gc2,
4100 x + 1, y + 1, x + 1, y + height - 1);
4102 gdk_draw_line (window, gc3,
4103 x + width - 2, y + 1, x + width - 2, y + height - 1);
4104 gdk_draw_line (window, gc4,
4105 x + width - 1, y, x + width - 1, y + height - 1);
4108 gdk_draw_line (window, gc4,
4109 x, y + height - 1, x + gap_x - 1, y + height - 1);
4110 gdk_draw_line (window, gc3,
4111 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4112 gdk_draw_line (window, gc3,
4113 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4115 if ((width - (gap_x + gap_width)) > 0)
4117 gdk_draw_line (window, gc4,
4118 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4119 gdk_draw_line (window, gc3,
4120 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4121 gdk_draw_line (window, gc3,
4122 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4126 gdk_draw_line (window, gc1,
4127 x, y, x + width - 1, y);
4128 gdk_draw_line (window, gc2,
4129 x, y + 1, x + width - 2, y + 1);
4131 gdk_draw_line (window, gc3,
4132 x, y + height - 2, x + width - 2, y + height - 2);
4133 gdk_draw_line (window, gc3,
4134 x + width - 2, y + 1, x + width - 2, y + height - 2);
4135 gdk_draw_line (window, gc4,
4136 x, y + height - 1, x + width - 1, y + height - 1);
4137 gdk_draw_line (window, gc4,
4138 x + width - 1, y, x + width - 1, y + height - 1);
4141 gdk_draw_line (window, gc1,
4142 x, y, x, y + gap_x - 1);
4143 gdk_draw_line (window, gc2,
4144 x + 1, y + 1, x + 1, y + gap_x - 1);
4145 gdk_draw_line (window, gc2,
4146 x, y + gap_x, x, y + gap_x);
4148 if ((width - (gap_x + gap_width)) > 0)
4150 gdk_draw_line (window, gc1,
4151 x, y + gap_x + gap_width, x, y + height - 2);
4152 gdk_draw_line (window, gc2,
4153 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4154 gdk_draw_line (window, gc2,
4155 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4159 gdk_draw_line (window, gc1,
4160 x, y, x + width - 1, y);
4161 gdk_draw_line (window, gc1,
4162 x, y, x, y + height - 1);
4163 gdk_draw_line (window, gc2,
4164 x + 1, y + 1, x + width - 1, y + 1);
4165 gdk_draw_line (window, gc2,
4166 x + 1, y + 1, x + 1, y + height - 2);
4168 gdk_draw_line (window, gc3,
4169 x + 1, y + height - 2, x + width - 1, y + height - 2);
4170 gdk_draw_line (window, gc4,
4171 x, y + height - 1, x + width - 1, y + height - 1);
4174 gdk_draw_line (window, gc4,
4175 x + width - 1, y, x + width - 1, y + gap_x - 1);
4176 gdk_draw_line (window, gc3,
4177 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4178 gdk_draw_line (window, gc3,
4179 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4181 if ((width - (gap_x + gap_width)) > 0)
4183 gdk_draw_line (window, gc4,
4184 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4185 gdk_draw_line (window, gc3,
4186 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4187 gdk_draw_line (window, gc3,
4188 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4196 gdk_gc_set_clip_rectangle (gc1, NULL);
4197 gdk_gc_set_clip_rectangle (gc2, NULL);
4198 gdk_gc_set_clip_rectangle (gc3, NULL);
4199 gdk_gc_set_clip_rectangle (gc4, NULL);
4204 gtk_default_draw_box_gap (GtkStyle *style,
4206 GtkStateType state_type,
4207 GtkShadowType shadow_type,
4210 const gchar *detail,
4215 GtkPositionType gap_side,
4224 g_return_if_fail (GTK_IS_STYLE (style));
4225 g_return_if_fail (window != NULL);
4227 gtk_style_apply_default_background (style, window,
4228 widget && !GTK_WIDGET_NO_WINDOW (widget),
4229 state_type, area, x, y, width, height);
4231 sanitize_size (window, &width, &height);
4233 switch (shadow_type)
4235 case GTK_SHADOW_NONE:
4238 gc1 = style->dark_gc[state_type];
4239 gc2 = style->black_gc;
4240 gc3 = style->bg_gc[state_type];
4241 gc4 = style->light_gc[state_type];
4243 case GTK_SHADOW_ETCHED_IN:
4244 gc1 = style->dark_gc[state_type];
4245 gc2 = style->light_gc[state_type];
4246 gc3 = style->dark_gc[state_type];
4247 gc4 = style->light_gc[state_type];
4249 case GTK_SHADOW_OUT:
4250 gc1 = style->light_gc[state_type];
4251 gc2 = style->bg_gc[state_type];
4252 gc3 = style->dark_gc[state_type];
4253 gc4 = style->black_gc;
4255 case GTK_SHADOW_ETCHED_OUT:
4256 gc1 = style->light_gc[state_type];
4257 gc2 = style->dark_gc[state_type];
4258 gc3 = style->light_gc[state_type];
4259 gc4 = style->dark_gc[state_type];
4265 gdk_gc_set_clip_rectangle (gc1, area);
4266 gdk_gc_set_clip_rectangle (gc2, area);
4267 gdk_gc_set_clip_rectangle (gc3, area);
4268 gdk_gc_set_clip_rectangle (gc4, area);
4271 switch (shadow_type)
4273 case GTK_SHADOW_NONE:
4275 case GTK_SHADOW_OUT:
4276 case GTK_SHADOW_ETCHED_IN:
4277 case GTK_SHADOW_ETCHED_OUT:
4281 gdk_draw_line (window, gc1,
4282 x, y, x, y + height - 1);
4283 gdk_draw_line (window, gc2,
4284 x + 1, y, x + 1, y + height - 2);
4286 gdk_draw_line (window, gc3,
4287 x + 1, y + height - 2, x + width - 2, y + height - 2);
4288 gdk_draw_line (window, gc3,
4289 x + width - 2, y, x + width - 2, y + height - 2);
4290 gdk_draw_line (window, gc4,
4291 x, y + height - 1, x + width - 1, y + height - 1);
4292 gdk_draw_line (window, gc4,
4293 x + width - 1, y, x + width - 1, y + height - 1);
4296 gdk_draw_line (window, gc1,
4297 x, y, x + gap_x - 1, y);
4298 gdk_draw_line (window, gc2,
4299 x + 1, y + 1, x + gap_x - 1, y + 1);
4300 gdk_draw_line (window, gc2,
4301 x + gap_x, y, x + gap_x, y);
4303 if ((width - (gap_x + gap_width)) > 0)
4305 gdk_draw_line (window, gc1,
4306 x + gap_x + gap_width, y, x + width - 2, y);
4307 gdk_draw_line (window, gc2,
4308 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
4309 gdk_draw_line (window, gc2,
4310 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4313 case GTK_POS_BOTTOM:
4314 gdk_draw_line (window, gc1,
4315 x, y, x + width - 1, y);
4316 gdk_draw_line (window, gc1,
4317 x, y, x, y + height - 1);
4318 gdk_draw_line (window, gc2,
4319 x + 1, y + 1, x + width - 2, y + 1);
4320 gdk_draw_line (window, gc2,
4321 x + 1, y + 1, x + 1, y + height - 1);
4323 gdk_draw_line (window, gc3,
4324 x + width - 2, y + 1, x + width - 2, y + height - 1);
4325 gdk_draw_line (window, gc4,
4326 x + width - 1, y, x + width - 1, y + height - 1);
4329 gdk_draw_line (window, gc4,
4330 x, y + height - 1, x + gap_x - 1, y + height - 1);
4331 gdk_draw_line (window, gc3,
4332 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4333 gdk_draw_line (window, gc3,
4334 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4336 if ((width - (gap_x + gap_width)) > 0)
4338 gdk_draw_line (window, gc4,
4339 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4340 gdk_draw_line (window, gc3,
4341 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4342 gdk_draw_line (window, gc3,
4343 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4347 gdk_draw_line (window, gc1,
4348 x, y, x + width - 1, y);
4349 gdk_draw_line (window, gc2,
4350 x, y + 1, x + width - 2, y + 1);
4352 gdk_draw_line (window, gc3,
4353 x, y + height - 2, x + width - 2, y + height - 2);
4354 gdk_draw_line (window, gc3,
4355 x + width - 2, y + 1, x + width - 2, y + height - 2);
4356 gdk_draw_line (window, gc4,
4357 x, y + height - 1, x + width - 1, y + height - 1);
4358 gdk_draw_line (window, gc4,
4359 x + width - 1, y, x + width - 1, y + height - 1);
4362 gdk_draw_line (window, gc1,
4363 x, y, x, y + gap_x - 1);
4364 gdk_draw_line (window, gc2,
4365 x + 1, y + 1, x + 1, y + gap_x - 1);
4366 gdk_draw_line (window, gc2,
4367 x, y + gap_x, x, y + gap_x);
4369 if ((width - (gap_x + gap_width)) > 0)
4371 gdk_draw_line (window, gc1,
4372 x, y + gap_x + gap_width, x, y + height - 2);
4373 gdk_draw_line (window, gc2,
4374 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4375 gdk_draw_line (window, gc2,
4376 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4380 gdk_draw_line (window, gc1,
4381 x, y, x + width - 1, y);
4382 gdk_draw_line (window, gc1,
4383 x, y, x, y + height - 1);
4384 gdk_draw_line (window, gc2,
4385 x + 1, y + 1, x + width - 1, y + 1);
4386 gdk_draw_line (window, gc2,
4387 x + 1, y + 1, x + 1, y + height - 2);
4389 gdk_draw_line (window, gc3,
4390 x + 1, y + height - 2, x + width - 1, y + height - 2);
4391 gdk_draw_line (window, gc4,
4392 x, y + height - 1, x + width - 1, y + height - 1);
4395 gdk_draw_line (window, gc4,
4396 x + width - 1, y, x + width - 1, y + gap_x - 1);
4397 gdk_draw_line (window, gc3,
4398 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4399 gdk_draw_line (window, gc3,
4400 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4402 if ((width - (gap_x + gap_width)) > 0)
4404 gdk_draw_line (window, gc4,
4405 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4406 gdk_draw_line (window, gc3,
4407 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4408 gdk_draw_line (window, gc3,
4409 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4417 gdk_gc_set_clip_rectangle (gc1, NULL);
4418 gdk_gc_set_clip_rectangle (gc2, NULL);
4419 gdk_gc_set_clip_rectangle (gc3, NULL);
4420 gdk_gc_set_clip_rectangle (gc4, NULL);
4425 gtk_default_draw_extension (GtkStyle *style,
4427 GtkStateType state_type,
4428 GtkShadowType shadow_type,
4431 const gchar *detail,
4436 GtkPositionType gap_side)
4443 g_return_if_fail (GTK_IS_STYLE (style));
4444 g_return_if_fail (window != NULL);
4446 gtk_style_apply_default_background (style, window,
4447 widget && !GTK_WIDGET_NO_WINDOW (widget),
4448 GTK_STATE_NORMAL, area, x, y, width, height);
4450 sanitize_size (window, &width, &height);
4452 switch (shadow_type)
4454 case GTK_SHADOW_NONE:
4457 gc1 = style->dark_gc[state_type];
4458 gc2 = style->black_gc;
4459 gc3 = style->bg_gc[state_type];
4460 gc4 = style->light_gc[state_type];
4462 case GTK_SHADOW_ETCHED_IN:
4463 gc1 = style->dark_gc[state_type];
4464 gc2 = style->light_gc[state_type];
4465 gc3 = style->dark_gc[state_type];
4466 gc4 = style->light_gc[state_type];
4468 case GTK_SHADOW_OUT:
4469 gc1 = style->light_gc[state_type];
4470 gc2 = style->bg_gc[state_type];
4471 gc3 = style->dark_gc[state_type];
4472 gc4 = style->black_gc;
4474 case GTK_SHADOW_ETCHED_OUT:
4475 gc1 = style->light_gc[state_type];
4476 gc2 = style->dark_gc[state_type];
4477 gc3 = style->light_gc[state_type];
4478 gc4 = style->dark_gc[state_type];
4484 gdk_gc_set_clip_rectangle (gc1, area);
4485 gdk_gc_set_clip_rectangle (gc2, area);
4486 gdk_gc_set_clip_rectangle (gc3, area);
4487 gdk_gc_set_clip_rectangle (gc4, area);
4490 switch (shadow_type)
4492 case GTK_SHADOW_NONE:
4494 case GTK_SHADOW_OUT:
4495 case GTK_SHADOW_ETCHED_IN:
4496 case GTK_SHADOW_ETCHED_OUT:
4500 gtk_style_apply_default_background (style, window,
4501 widget && !GTK_WIDGET_NO_WINDOW (widget),
4503 x + style->xthickness,
4505 width - (2 * style->xthickness),
4506 height - (style->ythickness));
4507 gdk_draw_line (window, gc1,
4508 x, y, x, y + height - 2);
4509 gdk_draw_line (window, gc2,
4510 x + 1, y, x + 1, y + height - 2);
4512 gdk_draw_line (window, gc3,
4513 x + 2, y + height - 2, x + width - 2, y + height - 2);
4514 gdk_draw_line (window, gc3,
4515 x + width - 2, y, x + width - 2, y + height - 2);
4516 gdk_draw_line (window, gc4,
4517 x + 1, y + height - 1, x + width - 2, y + height - 1);
4518 gdk_draw_line (window, gc4,
4519 x + width - 1, y, x + width - 1, y + height - 2);
4521 case GTK_POS_BOTTOM:
4522 gtk_style_apply_default_background (style, window,
4523 widget && !GTK_WIDGET_NO_WINDOW (widget),
4525 x + style->xthickness,
4526 y + style->ythickness,
4527 width - (2 * style->xthickness),
4528 height - (style->ythickness));
4529 gdk_draw_line (window, gc1,
4530 x + 1, y, x + width - 2, y);
4531 gdk_draw_line (window, gc1,
4532 x, y + 1, x, y + height - 1);
4533 gdk_draw_line (window, gc2,
4534 x + 1, y + 1, x + width - 2, y + 1);
4535 gdk_draw_line (window, gc2,
4536 x + 1, y + 1, x + 1, y + height - 1);
4538 gdk_draw_line (window, gc3,
4539 x + width - 2, y + 2, x + width - 2, y + height - 1);
4540 gdk_draw_line (window, gc4,
4541 x + width - 1, y + 1, x + width - 1, y + height - 1);
4544 gtk_style_apply_default_background (style, window,
4545 widget && !GTK_WIDGET_NO_WINDOW (widget),
4548 y + style->ythickness,
4549 width - (style->xthickness),
4550 height - (2 * style->ythickness));
4551 gdk_draw_line (window, gc1,
4552 x, y, x + width - 2, y);
4553 gdk_draw_line (window, gc2,
4554 x + 1, y + 1, x + width - 2, y + 1);
4556 gdk_draw_line (window, gc3,
4557 x, y + height - 2, x + width - 2, y + height - 2);
4558 gdk_draw_line (window, gc3,
4559 x + width - 2, y + 2, x + width - 2, y + height - 2);
4560 gdk_draw_line (window, gc4,
4561 x, y + height - 1, x + width - 2, y + height - 1);
4562 gdk_draw_line (window, gc4,
4563 x + width - 1, y + 1, x + width - 1, y + height - 2);
4566 gtk_style_apply_default_background (style, window,
4567 widget && !GTK_WIDGET_NO_WINDOW (widget),
4569 x + style->xthickness,
4570 y + style->ythickness,
4571 width - (style->xthickness),
4572 height - (2 * style->ythickness));
4573 gdk_draw_line (window, gc1,
4574 x + 1, y, x + width - 1, y);
4575 gdk_draw_line (window, gc1,
4576 x, y + 1, x, y + height - 2);
4577 gdk_draw_line (window, gc2,
4578 x + 1, y + 1, x + width - 1, y + 1);
4579 gdk_draw_line (window, gc2,
4580 x + 1, y + 1, x + 1, y + height - 2);
4582 gdk_draw_line (window, gc3,
4583 x + 2, y + height - 2, x + width - 1, y + height - 2);
4584 gdk_draw_line (window, gc4,
4585 x + 1, y + height - 1, x + width - 1, y + height - 1);
4592 gdk_gc_set_clip_rectangle (gc1, NULL);
4593 gdk_gc_set_clip_rectangle (gc2, NULL);
4594 gdk_gc_set_clip_rectangle (gc3, NULL);
4595 gdk_gc_set_clip_rectangle (gc4, NULL);
4600 gtk_default_draw_focus (GtkStyle *style,
4602 GtkStateType state_type,
4605 const gchar *detail,
4613 gboolean free_dash_list = FALSE;
4614 gint line_width = 1;
4615 gint8 *dash_list = "\1\1";
4618 gc = style->fg_gc[state_type];
4622 gtk_widget_style_get (widget,
4623 "focus-line-width", &line_width,
4624 "focus-line-pattern", (gchar *)&dash_list,
4627 free_dash_list = TRUE;
4630 sanitize_size (window, &width, &height);
4633 gdk_gc_set_clip_rectangle (gc, area);
4635 gdk_gc_set_line_attributes (gc, line_width,
4636 dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
4637 GDK_CAP_BUTT, GDK_JOIN_MITER);
4640 if (detail && !strcmp (detail, "add-mode"))
4646 free_dash_list = FALSE;
4649 points[0].x = x + line_width / 2;
4650 points[0].y = y + line_width / 2;
4651 points[1].x = x + width - line_width + line_width / 2;
4652 points[1].y = y + line_width / 2;
4653 points[2].x = x + width - line_width + line_width / 2;
4654 points[2].y = y + height - line_width + line_width / 2;
4655 points[3].x = x + line_width / 2;
4656 points[3].y = y + height - line_width + line_width / 2;
4657 points[4] = points[0];
4661 gdk_draw_lines (window, gc, points, 5);
4665 /* We go through all the pain below because the X rasterization
4666 * rules don't really work right for dashed lines if you
4667 * want continuity in segments that go between top/right
4668 * and left/bottom. For instance, a top left corner
4669 * with a 1-1 dash is drawn as:
4676 * This is because pixels on the top and left boundaries
4677 * of polygons are drawn, but not on the bottom and right.
4678 * So, if you have a line going up that turns the corner
4679 * and goes right, there is a one pixel shift in the pattern.
4681 * So, to fix this, we drawn the top and right in one call,
4682 * then the left and bottom in another call, fixing up
4683 * the dash offset for the second call ourselves to get
4684 * continuity at the upper left.
4686 * It's not perfect since we really should have a join at
4687 * the upper left and lower right instead of two intersecting
4688 * lines but that's only really apparent for no-dashes,
4689 * which (for this reason) are done as one polygon and
4690 * don't to through this code path.
4693 dash_len = strlen (dash_list);
4696 gdk_gc_set_dashes (gc, 0, dash_list, dash_len);
4698 gdk_draw_lines (window, gc, points, 3);
4700 /* We draw this line one farther over than it is "supposed" to
4701 * because of another rasterization problem ... if two 1 pixel
4702 * unjoined lines meet at the lower right, there will be a missing
4709 gint dash_pixels = 0;
4712 /* Adjust the dash offset for the bottom and left so we
4713 * match up at the upper left.
4715 for (i = 0; i < dash_len; i++)
4716 dash_pixels += dash_list[i];
4718 if (dash_len % 2 == 1)
4721 gdk_gc_set_dashes (gc, dash_pixels - (width + height - 2 * line_width) % dash_pixels, dash_list, dash_len);
4724 gdk_draw_lines (window, gc, points + 2, 3);
4727 gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
4730 gdk_gc_set_clip_rectangle (gc, NULL);
4737 gtk_default_draw_slider (GtkStyle *style,
4739 GtkStateType state_type,
4740 GtkShadowType shadow_type,
4743 const gchar *detail,
4748 GtkOrientation orientation)
4750 g_return_if_fail (GTK_IS_STYLE (style));
4751 g_return_if_fail (window != NULL);
4753 sanitize_size (window, &width, &height);
4755 gtk_paint_box (style, window, state_type, shadow_type,
4756 area, widget, detail, x, y, width, height);
4759 (strcmp ("hscale", detail) == 0 ||
4760 strcmp ("vscale", detail) == 0))
4762 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4763 gtk_paint_vline (style, window, state_type, area, widget, detail,
4764 y + style->ythickness,
4765 y + height - style->ythickness - 1, x + width / 2);
4767 gtk_paint_hline (style, window, state_type, area, widget, detail,
4768 x + style->xthickness,
4769 x + width - style->xthickness - 1, y + height / 2);
4774 draw_dot (GdkWindow *window,
4782 size = CLAMP (size, 2, 3);
4786 gdk_draw_point (window, light_gc, x, y);
4787 gdk_draw_point (window, light_gc, x+1, y+1);
4789 else if (size == 3);
4791 gdk_draw_point (window, light_gc, x, y);
4792 gdk_draw_point (window, light_gc, x+1, y);
4793 gdk_draw_point (window, light_gc, x, y+1);
4794 gdk_draw_point (window, dark_gc, x+1, y+2);
4795 gdk_draw_point (window, dark_gc, x+2, y+1);
4796 gdk_draw_point (window, dark_gc, x+2, y+2);
4801 gtk_default_draw_handle (GtkStyle *style,
4803 GtkStateType state_type,
4804 GtkShadowType shadow_type,
4807 const gchar *detail,
4812 GtkOrientation orientation)
4815 gint xthick, ythick;
4816 GdkGC *light_gc, *dark_gc;
4817 GdkGC *free_me = NULL;
4822 g_return_if_fail (GTK_IS_STYLE (style));
4823 g_return_if_fail (window != NULL);
4825 sanitize_size (window, &width, &height);
4827 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
4828 detail, x, y, width, height);
4831 if (!strcmp (detail, "paned"))
4833 /* we want to ignore the shadow border in paned widgets */
4837 if (state_type == GTK_STATE_SELECTED && !GTK_WIDGET_HAS_FOCUS (widget))
4839 GdkColor unfocused_light;
4841 gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
4844 light_gc = free_me = gdk_gc_new (window);
4845 gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
4848 light_gc = style->light_gc[state_type];
4850 dark_gc = style->black_gc;
4854 xthick = style->xthickness;
4855 ythick = style->ythickness;
4857 light_gc = style->light_gc[state_type];
4858 dark_gc = style->dark_gc[state_type];
4861 rect.x = x + xthick;
4862 rect.y = y + ythick;
4863 rect.width = width - (xthick * 2);
4864 rect.height = height - (ythick * 2);
4867 intersect = gdk_rectangle_intersect (area, &rect, &dest);
4877 gdk_gc_set_clip_rectangle (light_gc, &dest);
4878 gdk_gc_set_clip_rectangle (dark_gc, &dest);
4880 if (!strcmp (detail, "paned"))
4882 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4883 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4884 draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
4886 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4887 draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
4891 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4892 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4894 draw_dot (window, light_gc, dark_gc, xx, yy, 2);
4895 draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
4899 gdk_gc_set_clip_rectangle (light_gc, NULL);
4900 gdk_gc_set_clip_rectangle (dark_gc, NULL);
4904 g_object_unref (G_OBJECT (free_me));
4908 create_expander_affine (gdouble affine[6],
4918 width = expander_size / 4.0;
4919 height = expander_size / 2.0;
4921 s = sin (degrees * G_PI / 180.0);
4922 c = cos (degrees * G_PI / 180.0);
4928 affine[4] = -width * c - height * -s + x;
4929 affine[5] = -width * s - height * c + y;
4933 apply_affine_on_point (double affine[6], GdkPoint *point)
4937 x = point->x * affine[0] + point->y * affine[2] + affine[4];
4938 y = point->x * affine[1] + point->y * affine[3] + affine[5];
4940 point->x = floor (x);
4941 point->y = floor (y);
4945 gtk_style_draw_polygon_with_gc (GdkWindow *window, GdkGC *gc, gint line_width,
4946 gboolean do_fill, GdkPoint *points, gint n_points)
4948 gdk_gc_set_line_attributes (gc, line_width,
4950 GDK_CAP_BUTT, GDK_JOIN_MITER);
4952 gdk_draw_polygon (window, gc, do_fill, points, n_points);
4953 gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
4957 gtk_default_draw_expander (GtkStyle *style,
4959 GtkStateType state_type,
4962 const gchar *detail,
4965 GtkExpanderStyle expander_style)
4974 gtk_widget_style_get (widget,
4975 "expander_size", &expander_size,
4977 line_width = MAX (1, expander_size/7);
4981 gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], area);
4982 gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], area);
4985 expander_size -= (line_width * 2 - 2);
4986 points[0].x = line_width / 2;
4987 points[0].y = line_width / 2;
4988 points[1].x = expander_size / 2 + line_width / 2;
4989 points[1].y = expander_size / 2 + line_width / 2;
4990 points[2].x = line_width / 2;
4991 points[2].y = expander_size + line_width / 2;
4993 switch (expander_style)
4995 case GTK_EXPANDER_COLLAPSED:
4996 degrees = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
4998 case GTK_EXPANDER_SEMI_COLLAPSED:
4999 degrees = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
5001 case GTK_EXPANDER_SEMI_EXPANDED:
5002 degrees = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
5004 case GTK_EXPANDER_EXPANDED:
5008 g_assert_not_reached ();
5011 create_expander_affine (affine, degrees, expander_size, x, y);
5013 for (i = 0; i < 3; i++)
5014 apply_affine_on_point (affine, &points[i]);
5016 if (state_type == GTK_STATE_PRELIGHT)
5018 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
5019 1, TRUE, points, 3);
5021 else if (state_type == GTK_STATE_ACTIVE)
5023 gtk_style_draw_polygon_with_gc (window, style->light_gc[GTK_STATE_ACTIVE],
5024 1, TRUE, points, 3);
5025 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
5026 line_width, FALSE, points, 3);
5030 gtk_style_draw_polygon_with_gc (window, style->base_gc[GTK_STATE_NORMAL],
5031 1, TRUE, points, 3);
5032 gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
5033 line_width, FALSE, points, 3);
5037 gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL);
5038 gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL);
5042 typedef struct _ByteRange ByteRange;
5051 range_new (guint start,
5054 ByteRange *br = g_new (ByteRange, 1);
5063 get_insensitive_layout (GdkDrawable *drawable,
5064 PangoLayout *layout)
5066 GSList *embossed_ranges = NULL;
5067 GSList *stippled_ranges = NULL;
5068 PangoLayoutIter *iter;
5069 GSList *tmp_list = NULL;
5070 PangoLayout *new_layout;
5071 PangoAttrList *attrs;
5072 GdkBitmap *stipple = NULL;
5074 iter = pango_layout_get_iter (layout);
5078 PangoLayoutRun *run;
5079 PangoAttribute *attr;
5080 gboolean need_stipple = FALSE;
5083 run = pango_layout_iter_get_run (iter);
5087 tmp_list = run->item->analysis.extra_attrs;
5089 while (tmp_list != NULL)
5091 attr = tmp_list->data;
5092 switch (attr->klass->type)
5094 case PANGO_ATTR_FOREGROUND:
5095 case PANGO_ATTR_BACKGROUND:
5096 need_stipple = TRUE;
5106 tmp_list = g_slist_next (tmp_list);
5109 br = range_new (run->item->offset, run->item->offset + run->item->length);
5112 stippled_ranges = g_slist_prepend (stippled_ranges, br);
5114 embossed_ranges = g_slist_prepend (embossed_ranges, br);
5117 while (pango_layout_iter_next_run (iter));
5119 pango_layout_iter_free (iter);
5121 new_layout = pango_layout_copy (layout);
5123 attrs = pango_layout_get_attributes (new_layout);
5127 /* Create attr list if there wasn't one */
5128 attrs = pango_attr_list_new ();
5129 pango_layout_set_attributes (new_layout, attrs);
5130 pango_attr_list_unref (attrs);
5133 tmp_list = embossed_ranges;
5134 while (tmp_list != NULL)
5136 PangoAttribute *attr;
5137 ByteRange *br = tmp_list->data;
5139 attr = gdk_pango_attr_embossed_new (TRUE);
5141 attr->start_index = br->start;
5142 attr->end_index = br->end;
5144 pango_attr_list_change (attrs, attr);
5148 tmp_list = g_slist_next (tmp_list);
5151 g_slist_free (embossed_ranges);
5153 tmp_list = stippled_ranges;
5154 while (tmp_list != NULL)
5156 PangoAttribute *attr;
5157 ByteRange *br = tmp_list->data;
5159 if (stipple == NULL)
5161 #define gray50_width 2
5162 #define gray50_height 2
5163 static const char gray50_bits[] = {
5167 stipple = gdk_bitmap_create_from_data (drawable,
5168 gray50_bits, gray50_width,
5172 attr = gdk_pango_attr_stipple_new (stipple);
5174 attr->start_index = br->start;
5175 attr->end_index = br->end;
5177 pango_attr_list_change (attrs, attr);
5181 tmp_list = g_slist_next (tmp_list);
5184 g_slist_free (stippled_ranges);
5187 g_object_unref (stipple);
5193 gtk_default_draw_layout (GtkStyle *style,
5195 GtkStateType state_type,
5199 const gchar *detail,
5202 PangoLayout *layout)
5206 g_return_if_fail (GTK_IS_STYLE (style));
5207 g_return_if_fail (window != NULL);
5209 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
5212 gdk_gc_set_clip_rectangle (gc, area);
5214 if (state_type == GTK_STATE_INSENSITIVE)
5218 ins = get_insensitive_layout (window, layout);
5220 gdk_draw_layout (window, gc, x, y, ins);
5222 g_object_unref (ins);
5226 gdk_draw_layout (window, gc, x, y, layout);
5230 gdk_gc_set_clip_rectangle (gc, NULL);
5234 gtk_default_draw_resize_grip (GtkStyle *style,
5236 GtkStateType state_type,
5239 const gchar *detail,
5246 g_return_if_fail (GTK_IS_STYLE (style));
5247 g_return_if_fail (window != NULL);
5251 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
5252 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
5253 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
5258 case GDK_WINDOW_EDGE_NORTH_WEST:
5259 /* make it square */
5264 else if (height < width)
5269 case GDK_WINDOW_EDGE_NORTH:
5275 case GDK_WINDOW_EDGE_NORTH_EAST:
5276 /* make it square, aligning to top right */
5281 else if (height < width)
5283 x += (width - height);
5287 case GDK_WINDOW_EDGE_WEST:
5293 case GDK_WINDOW_EDGE_EAST:
5294 /* aligning to right */
5297 x += (width - height);
5301 case GDK_WINDOW_EDGE_SOUTH_WEST:
5302 /* make it square, aligning to bottom left */
5305 y += (height - width);
5308 else if (height < width)
5313 case GDK_WINDOW_EDGE_SOUTH:
5314 /* align to bottom */
5317 y += (height - width);
5321 case GDK_WINDOW_EDGE_SOUTH_EAST:
5322 /* make it square, aligning to bottom right */
5325 y += (height - width);
5328 else if (height < width)
5330 x += (width - height);
5335 g_assert_not_reached ();
5337 /* Clear background */
5338 gtk_style_apply_default_background (style, window, FALSE,
5340 x, y, width, height);
5344 case GDK_WINDOW_EDGE_WEST:
5345 case GDK_WINDOW_EDGE_EAST:
5351 while (xi < x + width)
5353 gdk_draw_line (window,
5354 style->light_gc[state_type],
5359 gdk_draw_line (window,
5360 style->dark_gc[state_type],
5368 case GDK_WINDOW_EDGE_NORTH:
5369 case GDK_WINDOW_EDGE_SOUTH:
5375 while (yi < y + height)
5377 gdk_draw_line (window,
5378 style->light_gc[state_type],
5383 gdk_draw_line (window,
5384 style->dark_gc[state_type],
5392 case GDK_WINDOW_EDGE_NORTH_WEST:
5401 gdk_draw_line (window,
5402 style->dark_gc[state_type],
5409 gdk_draw_line (window,
5410 style->dark_gc[state_type],
5417 gdk_draw_line (window,
5418 style->light_gc[state_type],
5428 case GDK_WINDOW_EDGE_NORTH_EAST:
5435 while (xi < (x + width - 3))
5437 gdk_draw_line (window,
5438 style->light_gc[state_type],
5445 gdk_draw_line (window,
5446 style->dark_gc[state_type],
5453 gdk_draw_line (window,
5454 style->dark_gc[state_type],
5463 case GDK_WINDOW_EDGE_SOUTH_WEST:
5472 gdk_draw_line (window,
5473 style->dark_gc[state_type],
5480 gdk_draw_line (window,
5481 style->dark_gc[state_type],
5488 gdk_draw_line (window,
5489 style->light_gc[state_type],
5499 case GDK_WINDOW_EDGE_SOUTH_EAST:
5506 while (xi < (x + width - 3))
5508 gdk_draw_line (window,
5509 style->light_gc[state_type],
5516 gdk_draw_line (window,
5517 style->dark_gc[state_type],
5524 gdk_draw_line (window,
5525 style->dark_gc[state_type],
5535 g_assert_not_reached ();
5541 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
5542 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
5543 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
5548 gtk_style_shade (GdkColor *a,
5556 red = (gdouble) a->red / 65535.0;
5557 green = (gdouble) a->green / 65535.0;
5558 blue = (gdouble) a->blue / 65535.0;
5560 rgb_to_hls (&red, &green, &blue);
5565 else if (green < 0.0)
5571 else if (blue < 0.0)
5574 hls_to_rgb (&red, &green, &blue);
5576 b->red = red * 65535.0;
5577 b->green = green * 65535.0;
5578 b->blue = blue * 65535.0;
5582 rgb_to_hls (gdouble *r,
5623 l = (max + min) / 2;
5630 s = (max - min) / (max + min);
5632 s = (max - min) / (2 - max - min);
5636 h = (green - blue) / delta;
5637 else if (green == max)
5638 h = 2 + (blue - red) / delta;
5639 else if (blue == max)
5640 h = 4 + (red - green) / delta;
5653 hls_to_rgb (gdouble *h,
5666 if (lightness <= 0.5)
5667 m2 = lightness * (1 + saturation);
5669 m2 = lightness + saturation - lightness * saturation;
5670 m1 = 2 * lightness - m2;
5672 if (saturation == 0)
5687 r = m1 + (m2 - m1) * hue / 60;
5691 r = m1 + (m2 - m1) * (240 - hue) / 60;
5702 g = m1 + (m2 - m1) * hue / 60;
5706 g = m1 + (m2 - m1) * (240 - hue) / 60;
5717 b = m1 + (m2 - m1) * hue / 60;
5721 b = m1 + (m2 - m1) * (240 - hue) / 60;
5734 * @style: a #GtkStyle
5735 * @window: a #GdkWindow
5736 * @state_type: a state
5737 * @area: rectangle to which the output is clipped
5738 * @widget: the widget
5739 * @detail: a style detail
5740 * @x1: the starting x coordinate
5741 * @x2: the ending x coordinate
5742 * @y: the y coordinate
5744 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
5745 * using the given style and state.
5748 gtk_paint_hline (GtkStyle *style,
5750 GtkStateType state_type,
5753 const gchar *detail,
5758 g_return_if_fail (GTK_IS_STYLE (style));
5759 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
5761 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
5766 * @style: a #GtkStyle
5767 * @window: a #GdkWindow
5768 * @state_type: a state
5769 * @area: rectangle to which the output is clipped
5770 * @widget: the widget
5771 * @detail: a style detail
5772 * @y1_: the starting y coordinate
5773 * @y2_: the ending y coordinate
5774 * @x: the x coordinate
5776 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
5777 * using the given style and state.
5780 gtk_paint_vline (GtkStyle *style,
5782 GtkStateType state_type,
5785 const gchar *detail,
5790 g_return_if_fail (GTK_IS_STYLE (style));
5791 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
5793 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1_, y2_, x);
5798 * @style: a #GtkStyle
5799 * @window: a #GdkWindow
5800 * @state_type: a state
5801 * @shadow_type: type of shadow to draw
5802 * @area: clip rectangle
5803 * @widget: the widget
5804 * @detail: a style detail
5805 * @x: x origin of the rectangle
5806 * @y: y origin of the rectangle
5807 * @width: width of the rectangle
5808 * @height: width of the rectangle
5810 * Draws a shadow around the given rectangle in @window
5811 * using the given style and state and shadow type.
5814 gtk_paint_shadow (GtkStyle *style,
5816 GtkStateType state_type,
5817 GtkShadowType shadow_type,
5820 const gchar *detail,
5826 g_return_if_fail (GTK_IS_STYLE (style));
5827 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5829 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5833 * gtk_paint_polygon:
5834 * @style: a #GtkStyle
5835 * @window: a #GdkWindow
5836 * @state_type: a state
5837 * @shadow_type: type of shadow to draw
5838 * @area: clip rectangle
5839 * @widget: the widget
5840 * @detail: a style detail
5841 * @points: an array of #GdkPoint<!-- -->s
5842 * @npoints: length of @points
5843 * @fill: %TRUE if the polygon should be filled
5845 * Draws a polygon on @window with the given parameters.
5848 gtk_paint_polygon (GtkStyle *style,
5850 GtkStateType state_type,
5851 GtkShadowType shadow_type,
5854 const gchar *detail,
5859 g_return_if_fail (GTK_IS_STYLE (style));
5860 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5862 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
5867 * @style: a #GtkStyle
5868 * @window: a #GdkWindow
5869 * @state_type: a state
5870 * @shadow_type: the type of shadow to draw
5871 * @area: clip rectangle
5872 * @widget: the widget
5873 * @detail: a style detail
5874 * @arrow_type: the type of arrow to draw
5875 * @fill: %TRUE if the arrow tip should be filled
5876 * @x: x origin of the rectangle to draw the arrow in
5877 * @y: y origin of the rectangle to draw the arrow in
5878 * @width: width of the rectangle to draw the arrow in
5879 * @height: height of the rectangle to draw the arrow in
5881 * Draws an arrow in the given rectangle on @window using the given
5882 * parameters. @arrow_type determines the direction of the arrow.
5885 gtk_paint_arrow (GtkStyle *style,
5887 GtkStateType state_type,
5888 GtkShadowType shadow_type,
5891 const gchar *detail,
5892 GtkArrowType arrow_type,
5899 g_return_if_fail (GTK_IS_STYLE (style));
5900 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
5902 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
5906 * gtk_paint_diamond:
5907 * @style: a #GtkStyle
5908 * @window: a #GdkWindow
5909 * @state_type: a state
5910 * @shadow_type: the type of shadow to draw
5911 * @area: clip rectangle
5912 * @widget: the widget
5913 * @detail: a style detail
5914 * @x: x origin of the rectangle to draw the diamond in
5915 * @y: y origin of the rectangle to draw the diamond in
5916 * @width: width of the rectangle to draw the diamond in
5917 * @height: height of the rectangle to draw the diamond in
5919 * Draws a diamond in the given rectangle on @window using the given
5923 gtk_paint_diamond (GtkStyle *style,
5925 GtkStateType state_type,
5926 GtkShadowType shadow_type,
5929 const gchar *detail,
5935 g_return_if_fail (GTK_IS_STYLE (style));
5936 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
5938 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5943 * @style: a #GtkStyle
5944 * @window: a #GdkWindow
5945 * @state_type: a state
5946 * @area: clip rectangle
5947 * @widget: the widget
5948 * @detail: a style detail
5951 * @string: the string to draw
5953 * Draws a text string on @window with the given parameters.
5955 * Deprecated: Use gtk_paint_layout() instead.
5958 gtk_paint_string (GtkStyle *style,
5960 GtkStateType state_type,
5963 const gchar *detail,
5966 const gchar *string)
5968 g_return_if_fail (GTK_IS_STYLE (style));
5969 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
5971 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
5976 * @style: a #GtkStyle
5977 * @window: a #GdkWindow
5978 * @state_type: a state
5979 * @shadow_type: the type of shadow to draw
5980 * @area: clip rectangle
5981 * @widget: the widget
5982 * @detail: a style detail
5983 * @x: x origin of the box
5984 * @y: y origin of the box
5985 * @width: the width of the box
5986 * @height: the height of the box
5988 * Draws a box on @window with the given parameters.
5991 gtk_paint_box (GtkStyle *style,
5993 GtkStateType state_type,
5994 GtkShadowType shadow_type,
5997 const gchar *detail,
6003 g_return_if_fail (GTK_IS_STYLE (style));
6004 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
6006 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6010 * gtk_paint_flat_box:
6011 * @style: a #GtkStyle
6012 * @window: a #GdkWindow
6013 * @state_type: a state
6014 * @shadow_type: the type of shadow to draw
6015 * @area: clip rectangle
6016 * @widget: the widget
6017 * @detail: a style detail
6018 * @x: x origin of the box
6019 * @y: y origin of the box
6020 * @width: the width of the box
6021 * @height: the height of the box
6023 * Draws a flat box on @window with the given parameters.
6026 gtk_paint_flat_box (GtkStyle *style,
6028 GtkStateType state_type,
6029 GtkShadowType shadow_type,
6032 const gchar *detail,
6038 g_return_if_fail (GTK_IS_STYLE (style));
6039 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
6041 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6046 * @style: a #GtkStyle
6047 * @window: a #GdkWindow
6048 * @state_type: a state
6049 * @shadow_type: the type of shadow to draw
6050 * @area: clip rectangle
6051 * @widget: the widget
6052 * @detail: a style detail
6053 * @x: x origin of the rectangle to draw the check in
6054 * @y: y origin of the rectangle to draw the check in
6055 * @width: the width of the rectangle to draw the check in
6056 * @height: the height of the rectangle to draw the check in
6058 * Draws a check button indicator in the given rectangle on @window with
6059 * the given parameters.
6062 gtk_paint_check (GtkStyle *style,
6064 GtkStateType state_type,
6065 GtkShadowType shadow_type,
6068 const gchar *detail,
6074 g_return_if_fail (GTK_IS_STYLE (style));
6075 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
6077 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6082 * @style: a #GtkStyle
6083 * @window: a #GdkWindow
6084 * @state_type: a state
6085 * @shadow_type: the type of shadow to draw
6086 * @area: clip rectangle
6087 * @widget: the widget
6088 * @detail: a style detail
6089 * @x: x origin of the rectangle to draw the option in
6090 * @y: y origin of the rectangle to draw the option in
6091 * @width: the width of the rectangle to draw the option in
6092 * @height: the height of the rectangle to draw the option in
6094 * Draws a radio button indicator in the given rectangle on @window with
6095 * the given parameters.
6098 gtk_paint_option (GtkStyle *style,
6100 GtkStateType state_type,
6101 GtkShadowType shadow_type,
6104 const gchar *detail,
6110 g_return_if_fail (GTK_IS_STYLE (style));
6111 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
6113 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6118 * @style: a #GtkStyle
6119 * @window: a #GdkWindow
6120 * @state_type: a state
6121 * @shadow_type: the type of shadow to draw
6122 * @area: clip rectangle
6123 * @widget: the widget
6124 * @detail: a style detail
6125 * @x: x origin of the rectangle to draw the tab in
6126 * @y: y origin of the rectangle to draw the tab in
6127 * @width: the width of the rectangle to draw the tab in
6128 * @height: the height of the rectangle to draw the tab in
6130 * Draws an option menu tab (i.e. the up and down pointing arrows)
6131 * in the given rectangle on @window using the given parameters.
6134 gtk_paint_tab (GtkStyle *style,
6136 GtkStateType state_type,
6137 GtkShadowType shadow_type,
6140 const gchar *detail,
6146 g_return_if_fail (GTK_IS_STYLE (style));
6147 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
6149 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6153 * gtk_paint_shadow_gap:
6154 * @style: a #GtkStyle
6155 * @window: a #GdkWindow
6156 * @state_type: a state
6157 * @shadow_type: type of shadow to draw
6158 * @area: clip rectangle
6159 * @widget: the widget
6160 * @detail: a style detail
6161 * @x: x origin of the rectangle
6162 * @y: y origin of the rectangle
6163 * @width: width of the rectangle
6164 * @height: width of the rectangle
6165 * @gap_side: side in which to leave the gap
6166 * @gap_x: starting position of the gap
6167 * @gap_width: width of the gap
6169 * Draws a shadow around the given rectangle in @window
6170 * using the given style and state and shadow type, leaving a
6174 gtk_paint_shadow_gap (GtkStyle *style,
6176 GtkStateType state_type,
6177 GtkShadowType shadow_type,
6185 GtkPositionType gap_side,
6189 g_return_if_fail (GTK_IS_STYLE (style));
6190 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
6192 GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
6197 * gtk_paint_box_gap:
6198 * @style: a #GtkStyle
6199 * @window: a #GdkWindow
6200 * @state_type: a state
6201 * @shadow_type: type of shadow to draw
6202 * @area: clip rectangle
6203 * @widget: the widget
6204 * @detail: a style detail
6205 * @x: x origin of the rectangle
6206 * @y: y origin of the rectangle
6207 * @width: width of the rectangle
6208 * @height: width of the rectangle
6209 * @gap_side: side in which to leave the gap
6210 * @gap_x: starting position of the gap
6211 * @gap_width: width of the gap
6213 * Draws a box in @window using the given style and state and shadow type,
6214 * leaving a gap in one side.
6217 gtk_paint_box_gap (GtkStyle *style,
6219 GtkStateType state_type,
6220 GtkShadowType shadow_type,
6228 GtkPositionType gap_side,
6232 g_return_if_fail (GTK_IS_STYLE (style));
6233 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
6235 GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
6239 * gtk_paint_extension:
6240 * @style: a #GtkStyle
6241 * @window: a #GdkWindow
6242 * @state_type: a state
6243 * @shadow_type: type of shadow to draw
6244 * @area: clip rectangle
6245 * @widget: the widget
6246 * @detail: a style detail
6247 * @x: x origin of the extension
6248 * @y: y origin of the extension
6249 * @width: width of the extension
6250 * @height: width of the extension
6251 * @gap_side: the side on to which the extension is attached
6253 * Draws an extension, i.e. a notebook tab.
6256 gtk_paint_extension (GtkStyle *style,
6258 GtkStateType state_type,
6259 GtkShadowType shadow_type,
6267 GtkPositionType gap_side)
6269 g_return_if_fail (GTK_IS_STYLE (style));
6270 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
6272 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
6277 * @style: a #GtkStyle
6278 * @window: a #GdkWindow
6279 * @state_type: a state
6280 * @area: clip rectangle
6281 * @widget: the widget
6282 * @detail: a style detail
6283 * @x: the x origin of the rectangle around which to draw a focus indicator
6284 * @y: the y origin of the rectangle around which to draw a focus indicator
6285 * @width: the width of the rectangle around which to draw a focus indicator
6286 * @height: the height of the rectangle around which to draw a focus indicator
6288 * Draws a focus indicator around the given rectangle on @window using the
6292 gtk_paint_focus (GtkStyle *style,
6294 GtkStateType state_type,
6297 const gchar *detail,
6303 g_return_if_fail (GTK_IS_STYLE (style));
6304 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
6306 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height);
6310 gtk_paint_slider (GtkStyle *style,
6312 GtkStateType state_type,
6313 GtkShadowType shadow_type,
6316 const gchar *detail,
6321 GtkOrientation orientation)
6323 g_return_if_fail (GTK_IS_STYLE (style));
6324 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
6326 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6331 * @style: a #GtkStyle
6332 * @window: a #GdkWindow
6333 * @state_type: a state
6334 * @shadow_type: type of shadow to draw
6335 * @area: clip rectangle
6336 * @widget: the widget
6337 * @detail: a style detail
6338 * @x: x origin of the handle
6339 * @y: y origin of the handle
6340 * @width: with of the handle
6341 * @height: height of the handle
6342 * @orientation: the orientation of the handle
6344 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
6347 gtk_paint_handle (GtkStyle *style,
6349 GtkStateType state_type,
6350 GtkShadowType shadow_type,
6353 const gchar *detail,
6358 GtkOrientation orientation)
6360 g_return_if_fail (GTK_IS_STYLE (style));
6361 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
6363 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6367 * gtk_paint_expander:
6368 * @style: a #GtkStyle
6369 * @window: a #GdkWindow
6370 * @state_type: a state
6371 * @area: clip rectangle
6372 * @widget: the widget
6373 * @detail: a style detail
6374 * @x: the x position to draw the expander at
6375 * @y: the y position to draw the expander at
6376 * @expander_style: the style to draw the expander in
6378 * Draws an expander as used in #GtkTreeView.
6381 gtk_paint_expander (GtkStyle *style,
6383 GtkStateType state_type,
6386 const gchar *detail,
6389 GtkExpanderStyle expander_style)
6391 g_return_if_fail (GTK_IS_STYLE (style));
6392 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6394 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type, area,
6395 widget, detail, x, y, expander_style);
6399 gtk_paint_layout (GtkStyle *style,
6401 GtkStateType state_type,
6405 const gchar *detail,
6408 PangoLayout *layout)
6410 g_return_if_fail (GTK_IS_STYLE (style));
6411 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6413 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text, area,
6414 widget, detail, x, y, layout);
6418 * gtk_paint_resize_grip:
6419 * @style: a #GtkStyle
6420 * @window: a #GdkWindow
6421 * @state_type: a state
6422 * @area: clip rectangle
6423 * @widget: the widget
6424 * @detail: a style detail
6425 * @edge: the edge in which to draw the resize grip
6426 * @x: the x origin of the rectangle in which to draw the resize grip
6427 * @y: the y origin of the rectangle in which to draw the resize grip
6428 * @width: the width of the rectangle in which to draw the resize grip
6429 * @height: the height of the rectangle in which to draw the resize grip
6431 * Draws a resize grip in the given rectangle on @window using the given
6435 gtk_paint_resize_grip (GtkStyle *style,
6437 GtkStateType state_type,
6440 const gchar *detail,
6448 g_return_if_fail (GTK_IS_STYLE (style));
6449 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6451 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
6452 area, widget, detail,
6453 edge, x, y, width, height);
6458 * @border_: a #GtkBorder.
6459 * @returns: a copy of @border_.
6461 * Copies a #GtkBorder structure.
6464 gtk_border_copy (const GtkBorder *border)
6466 return (GtkBorder *)g_memdup (border, sizeof (GtkBorder));
6471 * @border_: a #GtkBorder.
6473 * Frees a #GtkBorder structure.
6476 gtk_border_free (GtkBorder *border)
6482 gtk_border_get_type (void)
6484 static GType our_type = 0;
6487 our_type = g_boxed_type_register_static ("GtkBorder",
6488 (GBoxedCopyFunc) gtk_border_copy,
6489 (GBoxedFreeFunc) gtk_border_free);
6495 gtk_style_get_font_internal (GtkStyle *style)
6497 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6499 if (style->private_font && style->private_font_desc)
6501 if (!style->font_desc ||
6502 !pango_font_description_equal (style->private_font_desc, style->font_desc))
6504 gdk_font_unref (style->private_font);
6505 style->private_font = NULL;
6507 if (style->private_font_desc)
6509 pango_font_description_free (style->private_font_desc);
6510 style->private_font_desc = NULL;
6515 if (!style->private_font)
6517 GdkDisplay *display;
6519 if (style->colormap)
6521 display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
6525 display = gdk_display_get_default ();
6526 GTK_NOTE (MULTIHEAD,
6527 g_warning ("gtk_style_get_font() should not be called on an unattached style"));
6530 if (style->font_desc)
6532 style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
6533 style->private_font_desc = pango_font_description_copy (style->font_desc);
6536 if (!style->private_font)
6537 style->private_font = gdk_font_load_for_display (display, "fixed");
6539 if (!style->private_font)
6540 g_error ("Unable to load \"fixed\" font");
6543 return style->private_font;
6547 * gtk_style_get_font:
6548 * @style: a #GtkStyle
6550 * Gets the #GdkFont to use for the given style. This is
6551 * meant only as a replacement for direct access to @style->font
6552 * and should not be used in new code. New code should
6553 * use @style->font_desc instead.
6555 * Return value: the #GdkFont for the style. This font is owned
6556 * by the style; if you want to keep around a copy, you must
6557 * call gdk_font_ref().
6560 gtk_style_get_font (GtkStyle *style)
6562 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6564 return gtk_style_get_font_internal (style);
6568 * gtk_style_set_font:
6569 * @style: a #GtkStyle.
6570 * @font: a #GdkFont, or %NULL to use the #GdkFont corresponding
6571 * to style->font_desc.
6573 * Sets the #GdkFont to use for a given style. This is
6574 * meant only as a replacement for direct access to style->font
6575 * and should not be used in new code. New code should
6576 * use style->font_desc instead.
6579 gtk_style_set_font (GtkStyle *style,
6584 g_return_if_fail (GTK_IS_STYLE (style));
6586 old_font = style->private_font;
6588 style->private_font = font;
6590 gdk_font_ref (font);
6593 gdk_font_unref (old_font);
6595 if (style->private_font_desc)
6597 pango_font_description_free (style->private_font_desc);
6598 style->private_font_desc = NULL;
6602 typedef struct _CursorInfo CursorInfo;
6608 GdkGC *secondary_gc;
6612 style_unrealize_cursor_gcs (GtkStyle *style)
6616 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6619 if (cursor_info->primary_gc)
6620 gtk_gc_release (cursor_info->primary_gc);
6622 if (cursor_info->secondary_gc)
6623 gtk_gc_release (cursor_info->secondary_gc);
6625 g_free (cursor_info);
6626 g_object_set_data (G_OBJECT (style), "gtk-style-cursor-info", NULL);
6631 make_cursor_gc (GtkWidget *widget,
6632 const gchar *property_name,
6633 const GdkColor *fallback)
6635 GdkGCValues gc_values;
6636 GdkGCValuesMask gc_values_mask;
6637 GdkColor *cursor_color;
6639 gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
6641 gc_values_mask = GDK_GC_FOREGROUND;
6644 gc_values.foreground = *cursor_color;
6645 gdk_color_free (cursor_color);
6648 gc_values.foreground = *fallback;
6650 gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
6651 return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
6655 get_insertion_cursor_gc (GtkWidget *widget,
6656 gboolean is_primary)
6658 CursorInfo *cursor_info;
6660 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
6663 cursor_info = g_new (CursorInfo, 1);
6664 g_object_set_data (G_OBJECT (widget->style), "gtk-style-cursor-info", cursor_info);
6665 cursor_info->primary_gc = NULL;
6666 cursor_info->secondary_gc = NULL;
6667 cursor_info->for_type = G_TYPE_INVALID;
6670 /* We have to keep track of the type because gtk_widget_style_get()
6671 * can return different results when called on the same property and
6672 * same style but for different widgets. :-(. That is,
6673 * GtkEntry::cursor-color = "red" in a style will modify the cursor
6674 * color for entries but not for text view.
6676 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
6678 cursor_info->for_type = G_OBJECT_TYPE (widget);
6679 if (cursor_info->primary_gc)
6681 gtk_gc_release (cursor_info->primary_gc);
6682 cursor_info->primary_gc = NULL;
6684 if (cursor_info->secondary_gc)
6686 gtk_gc_release (cursor_info->secondary_gc);
6687 cursor_info->secondary_gc = NULL;
6693 if (!cursor_info->primary_gc)
6694 cursor_info->primary_gc = make_cursor_gc (widget,
6696 &widget->style->black);
6698 return cursor_info->primary_gc;
6702 static const GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 };
6704 if (!cursor_info->secondary_gc)
6705 cursor_info->secondary_gc = make_cursor_gc (widget,
6706 "secondary-cursor-color",
6709 return cursor_info->secondary_gc;
6714 draw_insertion_cursor (GtkWidget *widget,
6715 GdkDrawable *drawable,
6717 GdkRectangle *location,
6718 GtkTextDirection direction,
6719 gboolean draw_arrow)
6725 gfloat cursor_aspect_ratio;
6728 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6730 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
6732 stem_width = location->height * cursor_aspect_ratio + 1;
6733 arrow_width = stem_width + 1;
6735 /* put (stem_width % 2) on the proper side of the cursor */
6736 if (direction == GTK_TEXT_DIR_LTR)
6737 offset = stem_width / 2;
6739 offset = stem_width - stem_width / 2;
6741 for (i = 0; i < stem_width; i++)
6742 gdk_draw_line (drawable, gc,
6743 location->x + i - offset, location->y,
6744 location->x + i - offset, location->y + location->height - 1);
6748 if (direction == GTK_TEXT_DIR_RTL)
6750 x = location->x - offset - 1;
6751 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6753 for (i = 0; i < arrow_width; i++)
6755 gdk_draw_line (drawable, gc,
6757 x, y + 2 * arrow_width - i - 1);
6761 else if (direction == GTK_TEXT_DIR_LTR)
6763 x = location->x + stem_width - offset;
6764 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6766 for (i = 0; i < arrow_width; i++)
6768 gdk_draw_line (drawable, gc,
6770 x, y + 2 * arrow_width - i - 1);
6778 * gtk_draw_insertion_cursor:
6779 * @widget: a #GtkWidget
6780 * @drawable: a #GdkDrawable
6781 * @area: rectangle to which the output is clipped, or %NULL if the
6782 * output should not be clipped
6783 * @location: location where to draw the cursor (@location->width is ignored)
6784 * @is_primary: if the cursor should be the primary cursor color.
6785 * @direction: whether the cursor is left-to-right or
6786 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
6787 * @draw_arrow: %TRUE to draw a directional arrow on the
6788 * cursor. Should be %FALSE unless the cursor is split.
6790 * Draws a text caret on @drawable at @location. This is not a style function
6791 * but merely a convenience function for drawing the standard cursor shape.
6796 gtk_draw_insertion_cursor (GtkWidget *widget,
6797 GdkDrawable *drawable,
6799 GdkRectangle *location,
6800 gboolean is_primary,
6801 GtkTextDirection direction,
6802 gboolean draw_arrow)
6806 g_return_if_fail (GTK_IS_WIDGET (widget));
6807 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
6808 g_return_if_fail (location != NULL);
6809 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6811 gc = get_insertion_cursor_gc (widget, is_primary);
6813 gdk_gc_set_clip_rectangle (gc, area);
6815 draw_insertion_cursor (widget, drawable, gc,
6816 location, direction, draw_arrow);
6819 gdk_gc_set_clip_rectangle (gc, NULL);