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() */
42 #define LIGHTNESS_MULT 1.3
43 #define DARKNESS_MULT 0.7
45 /* --- typedefs & structures --- */
52 /* --- prototypes --- */
53 static void gtk_style_init (GtkStyle *style);
54 static void gtk_style_class_init (GtkStyleClass *klass);
55 static void gtk_style_finalize (GObject *object);
56 static void gtk_style_realize (GtkStyle *style,
57 GdkColormap *colormap);
58 static void gtk_style_real_realize (GtkStyle *style);
59 static void gtk_style_real_unrealize (GtkStyle *style);
60 static void gtk_style_real_copy (GtkStyle *style,
62 static void gtk_style_real_set_background (GtkStyle *style,
64 GtkStateType state_type);
65 static GtkStyle *gtk_style_real_clone (GtkStyle *style);
66 static void gtk_style_real_init_from_rc (GtkStyle *style,
67 GtkRcStyle *rc_style);
68 static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
69 const GtkIconSource *source,
70 GtkTextDirection direction,
75 static void gtk_default_draw_hline (GtkStyle *style,
77 GtkStateType state_type,
84 static void gtk_default_draw_vline (GtkStyle *style,
86 GtkStateType state_type,
93 static void gtk_default_draw_shadow (GtkStyle *style,
95 GtkStateType state_type,
96 GtkShadowType shadow_type,
104 static void gtk_default_draw_polygon (GtkStyle *style,
106 GtkStateType state_type,
107 GtkShadowType shadow_type,
114 static void gtk_default_draw_arrow (GtkStyle *style,
116 GtkStateType state_type,
117 GtkShadowType shadow_type,
121 GtkArrowType arrow_type,
127 static void gtk_default_draw_diamond (GtkStyle *style,
129 GtkStateType state_type,
130 GtkShadowType shadow_type,
138 static void gtk_default_draw_string (GtkStyle *style,
140 GtkStateType state_type,
146 const gchar *string);
147 static void gtk_default_draw_box (GtkStyle *style,
149 GtkStateType state_type,
150 GtkShadowType shadow_type,
158 static void gtk_default_draw_flat_box (GtkStyle *style,
160 GtkStateType state_type,
161 GtkShadowType shadow_type,
169 static void gtk_default_draw_check (GtkStyle *style,
171 GtkStateType state_type,
172 GtkShadowType shadow_type,
180 static void gtk_default_draw_option (GtkStyle *style,
182 GtkStateType state_type,
183 GtkShadowType shadow_type,
191 static void gtk_default_draw_tab (GtkStyle *style,
193 GtkStateType state_type,
194 GtkShadowType shadow_type,
202 static void gtk_default_draw_shadow_gap (GtkStyle *style,
204 GtkStateType state_type,
205 GtkShadowType shadow_type,
213 GtkPositionType gap_side,
216 static void gtk_default_draw_box_gap (GtkStyle *style,
218 GtkStateType state_type,
219 GtkShadowType shadow_type,
227 GtkPositionType gap_side,
230 static void gtk_default_draw_extension (GtkStyle *style,
232 GtkStateType state_type,
233 GtkShadowType shadow_type,
241 GtkPositionType gap_side);
242 static void gtk_default_draw_focus (GtkStyle *style,
244 GtkStateType state_type,
252 static void gtk_default_draw_slider (GtkStyle *style,
254 GtkStateType state_type,
255 GtkShadowType shadow_type,
263 GtkOrientation orientation);
264 static void gtk_default_draw_handle (GtkStyle *style,
266 GtkStateType state_type,
267 GtkShadowType shadow_type,
275 GtkOrientation orientation);
276 static void gtk_default_draw_expander (GtkStyle *style,
278 GtkStateType state_type,
284 GtkExpanderStyle expander_style);
285 static void gtk_default_draw_layout (GtkStyle *style,
287 GtkStateType state_type,
294 PangoLayout *layout);
295 static void gtk_default_draw_resize_grip (GtkStyle *style,
297 GtkStateType state_type,
307 static void gtk_style_shade (GdkColor *a,
310 static void rgb_to_hls (gdouble *r,
313 static void hls_to_rgb (gdouble *h,
317 static void style_unrealize_cursor_gcs (GtkStyle *style);
319 static GdkFont *gtk_style_get_font_internal (GtkStyle *style);
322 * Data for default check and radio buttons
325 static const GtkRequisition default_option_indicator_size = { 7, 13 };
326 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
328 #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5
329 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd
330 #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7
331 #define GTK_WHITE 0xffff, 0xffff, 0xffff
332 #define GTK_BLUE 0x4b4b, 0x6969, 0x8383
333 #define GTK_VERY_DARK_GRAY 0x9c9c, 0x9a9a, 0x9494
334 #define GTK_BLACK 0x0000, 0x0000, 0x0000
335 #define GTK_WEAK_GRAY 0x7530, 0x7530, 0x7530
337 /* --- variables --- */
338 static const GdkColor gtk_default_normal_fg = { 0, GTK_BLACK };
339 static const GdkColor gtk_default_active_fg = { 0, GTK_BLACK };
340 static const GdkColor gtk_default_prelight_fg = { 0, GTK_BLACK };
341 static const GdkColor gtk_default_selected_fg = { 0, GTK_WHITE };
342 static const GdkColor gtk_default_insensitive_fg = { 0, GTK_WEAK_GRAY };
344 static const GdkColor gtk_default_normal_bg = { 0, GTK_GRAY };
345 static const GdkColor gtk_default_active_bg = { 0, GTK_DARK_GRAY };
346 static const GdkColor gtk_default_prelight_bg = { 0, GTK_LIGHT_GRAY };
347 static const GdkColor gtk_default_selected_bg = { 0, GTK_BLUE };
348 static const GdkColor gtk_default_insensitive_bg = { 0, GTK_GRAY };
349 static const GdkColor gtk_default_selected_base = { 0, GTK_BLUE };
350 static const GdkColor gtk_default_active_base = { 0, GTK_VERY_DARK_GRAY };
352 static gpointer parent_class = NULL;
354 /* --- signals --- */
355 static guint realize_signal = 0;
356 static guint unrealize_signal = 0;
358 /* --- functions --- */
360 gtk_style_get_type (void)
362 static GType style_type = 0;
366 static const GTypeInfo style_info =
368 sizeof (GtkStyleClass),
369 (GBaseInitFunc) NULL,
370 (GBaseFinalizeFunc) NULL,
371 (GClassInitFunc) gtk_style_class_init,
372 NULL, /* class_finalize */
373 NULL, /* class_data */
376 (GInstanceInitFunc) gtk_style_init,
379 style_type = g_type_register_static (G_TYPE_OBJECT, "GtkStyle",
387 * _gtk_style_init_for_settings:
388 * @style: a #GtkStyle
389 * @settings: a #GtkSettings
391 * Initializes the font description in @style according to the default
392 * font name of @settings. This is called for gtk_style_new() with
393 * the settings for the default screen (if any); if we are creating
394 * a style for a particular screen, we then call it again in a
395 * location where we know the correct settings.
396 * The reason for this is that gtk_rc_style_create_style() doesn't
397 * take the screen for an argument.
400 _gtk_style_init_for_settings (GtkStyle *style,
401 GtkSettings *settings)
403 const gchar *font_name = _gtk_rc_context_get_default_font_name (settings);
405 if (style->font_desc)
406 pango_font_description_free (style->font_desc);
408 style->font_desc = pango_font_description_from_string (font_name);
410 if (!pango_font_description_get_family (style->font_desc))
412 g_warning ("Default font does not have a family set");
413 pango_font_description_set_family (style->font_desc, "Sans");
415 if (pango_font_description_get_size (style->font_desc) <= 0)
417 g_warning ("Default font does not have a positive size");
418 pango_font_description_set_size (style->font_desc, 10 * PANGO_SCALE);
423 gtk_style_init (GtkStyle *style)
427 GtkSettings *settings = gtk_settings_get_default ();
430 _gtk_style_init_for_settings (style, settings);
432 style->font_desc = pango_font_description_from_string ("Sans 10");
434 style->attach_count = 0;
435 style->colormap = NULL;
438 style->black.red = 0;
439 style->black.green = 0;
440 style->black.blue = 0;
442 style->white.red = 65535;
443 style->white.green = 65535;
444 style->white.blue = 65535;
446 style->black_gc = NULL;
447 style->white_gc = NULL;
449 style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
450 style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
451 style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
452 style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
453 style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
455 style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
456 style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
457 style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
458 style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
459 style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
461 for (i = 0; i < 4; i++)
463 style->text[i] = style->fg[i];
464 style->base[i] = style->white;
467 style->base[GTK_STATE_SELECTED] = gtk_default_selected_base;
468 style->text[GTK_STATE_SELECTED] = style->white;
469 style->base[GTK_STATE_ACTIVE] = gtk_default_active_base;
470 style->text[GTK_STATE_ACTIVE] = style->white;
471 style->base[GTK_STATE_INSENSITIVE] = gtk_default_prelight_bg;
472 style->text[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
474 for (i = 0; i < 5; i++)
475 style->bg_pixmap[i] = NULL;
477 style->rc_style = NULL;
479 for (i = 0; i < 5; i++)
481 style->fg_gc[i] = NULL;
482 style->bg_gc[i] = NULL;
483 style->light_gc[i] = NULL;
484 style->dark_gc[i] = NULL;
485 style->mid_gc[i] = NULL;
486 style->text_gc[i] = NULL;
487 style->base_gc[i] = NULL;
488 style->text_aa_gc[i] = NULL;
491 style->xthickness = 2;
492 style->ythickness = 2;
494 style->property_cache = NULL;
498 gtk_style_class_init (GtkStyleClass *klass)
500 GObjectClass *object_class = G_OBJECT_CLASS (klass);
502 parent_class = g_type_class_peek_parent (klass);
504 object_class->finalize = gtk_style_finalize;
506 klass->clone = gtk_style_real_clone;
507 klass->copy = gtk_style_real_copy;
508 klass->init_from_rc = gtk_style_real_init_from_rc;
509 klass->realize = gtk_style_real_realize;
510 klass->unrealize = gtk_style_real_unrealize;
511 klass->set_background = gtk_style_real_set_background;
512 klass->render_icon = gtk_default_render_icon;
514 klass->draw_hline = gtk_default_draw_hline;
515 klass->draw_vline = gtk_default_draw_vline;
516 klass->draw_shadow = gtk_default_draw_shadow;
517 klass->draw_polygon = gtk_default_draw_polygon;
518 klass->draw_arrow = gtk_default_draw_arrow;
519 klass->draw_diamond = gtk_default_draw_diamond;
520 klass->draw_string = gtk_default_draw_string;
521 klass->draw_box = gtk_default_draw_box;
522 klass->draw_flat_box = gtk_default_draw_flat_box;
523 klass->draw_check = gtk_default_draw_check;
524 klass->draw_option = gtk_default_draw_option;
525 klass->draw_tab = gtk_default_draw_tab;
526 klass->draw_shadow_gap = gtk_default_draw_shadow_gap;
527 klass->draw_box_gap = gtk_default_draw_box_gap;
528 klass->draw_extension = gtk_default_draw_extension;
529 klass->draw_focus = gtk_default_draw_focus;
530 klass->draw_slider = gtk_default_draw_slider;
531 klass->draw_handle = gtk_default_draw_handle;
532 klass->draw_expander = gtk_default_draw_expander;
533 klass->draw_layout = gtk_default_draw_layout;
534 klass->draw_resize_grip = gtk_default_draw_resize_grip;
539 * @style: the object which received the signal
541 * Emitted when the style has been initialized for a particular
542 * colormap and depth. Connecting to this signal is probably seldom
543 * useful since most of the time applications and widgets only
544 * deal with styles that have been already realized.
548 realize_signal = g_signal_new ("realize",
549 G_TYPE_FROM_CLASS (object_class),
551 G_STRUCT_OFFSET (GtkStyleClass, realize),
553 _gtk_marshal_VOID__VOID,
556 * GtkStyle::unrealize:
557 * @style: the object which received the signal
559 * Emitted when the aspects of the style specific to a particular colormap
560 * and depth are being cleaned up. A connection to this signal can be useful
561 * if a widget wants to cache objects like a #GdkGC as object data on #GtkStyle.
562 * This signal provides a convenient place to free such cached objects.
566 unrealize_signal = g_signal_new ("unrealize",
567 G_TYPE_FROM_CLASS (object_class),
569 G_STRUCT_OFFSET (GtkStyleClass, unrealize),
571 _gtk_marshal_VOID__VOID,
576 clear_property_cache (GtkStyle *style)
578 if (style->property_cache)
582 for (i = 0; i < style->property_cache->len; i++)
584 PropertyValue *node = &g_array_index (style->property_cache, PropertyValue, i);
586 g_param_spec_unref (node->pspec);
587 g_value_unset (&node->value);
589 g_array_free (style->property_cache, TRUE);
590 style->property_cache = NULL;
595 gtk_style_finalize (GObject *object)
597 GtkStyle *style = GTK_STYLE (object);
599 g_return_if_fail (style->attach_count == 0);
601 clear_property_cache (style);
603 /* All the styles in the list have the same
604 * style->styles pointer. If we delete the
605 * *first* style from the list, we need to update
606 * the style->styles pointers from all the styles.
607 * Otherwise we simply remove the node from
612 if (style->styles->data != style)
613 g_slist_remove (style->styles, style);
616 GSList *tmp_list = style->styles->next;
620 GTK_STYLE (tmp_list->data)->styles = style->styles->next;
621 tmp_list = tmp_list->next;
623 g_slist_free_1 (style->styles);
627 if (style->icon_factories)
629 GSList *tmp_list = style->icon_factories;
633 g_object_unref (tmp_list->data);
634 tmp_list = tmp_list->next;
637 g_slist_free (style->icon_factories);
640 pango_font_description_free (style->font_desc);
642 if (style->private_font)
643 gdk_font_unref (style->private_font);
645 if (style->private_font_desc)
646 pango_font_description_free (style->private_font_desc);
649 gtk_rc_style_unref (style->rc_style);
651 G_OBJECT_CLASS (parent_class)->finalize (object);
656 gtk_style_copy (GtkStyle *style)
660 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
662 new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
663 GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
669 gtk_style_duplicate (GtkStyle *style)
673 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
675 new_style = gtk_style_copy (style);
677 /* All the styles in the list have the same
678 * style->styles pointer. When we insert a new
679 * style, we append it to the list to avoid having
680 * to update the existing ones.
682 style->styles = g_slist_append (style->styles, new_style);
683 new_style->styles = style->styles;
690 * @returns: a new #GtkStyle.
692 * Creates a new #GtkStyle.
699 style = g_object_new (GTK_TYPE_STYLE, NULL);
706 * @style: a #GtkStyle.
707 * @window: a #GdkWindow.
708 * @returns: Either @style, or a newly-created #GtkStyle.
709 * If the style is newly created, the style parameter
710 * will be dereferenced, and the new style will have
711 * a reference count belonging to the caller.
713 * Attaches a style to a window; this process allocates the
714 * colors and creates the GC's for the style - it specializes
715 * it to a particular visual and colormap. The process may
716 * involve the creation of a new style if the style has already
717 * been attached to a window with a different style and colormap.
720 gtk_style_attach (GtkStyle *style,
724 GtkStyle *new_style = NULL;
725 GdkColormap *colormap;
727 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
728 g_return_val_if_fail (window != NULL, NULL);
730 colormap = gdk_drawable_get_colormap (window);
733 style->styles = g_slist_append (NULL, style);
735 styles = style->styles;
738 new_style = styles->data;
740 if (new_style->colormap == colormap)
744 styles = styles->next;
749 styles = style->styles;
753 new_style = styles->data;
755 if (new_style->attach_count == 0)
757 gtk_style_realize (new_style, colormap);
762 styles = styles->next;
768 new_style = gtk_style_duplicate (style);
769 if (gdk_colormap_get_screen (style->colormap) != gdk_colormap_get_screen (colormap) &&
770 new_style->private_font)
772 gdk_font_unref (new_style->private_font);
773 new_style->private_font = NULL;
775 gtk_style_realize (new_style, colormap);
778 /* A style gets a refcount from being attached */
779 if (new_style->attach_count == 0)
780 g_object_ref (new_style);
782 /* Another refcount belongs to the parent */
783 if (style != new_style)
785 g_object_unref (style);
786 g_object_ref (new_style);
789 new_style->attach_count++;
795 gtk_style_detach (GtkStyle *style)
797 g_return_if_fail (GTK_IS_STYLE (style));
799 style->attach_count -= 1;
800 if (style->attach_count == 0)
802 g_signal_emit (style, unrealize_signal, 0);
804 g_object_unref (style->colormap);
805 style->colormap = NULL;
807 if (style->private_font_desc)
809 if (style->private_font)
811 gdk_font_unref (style->private_font);
812 style->private_font = NULL;
815 pango_font_description_free (style->private_font_desc);
816 style->private_font_desc = NULL;
819 g_object_unref (style);
825 * @style: a #GtkStyle.
828 * Deprecated equivalent of g_object_ref().
831 gtk_style_ref (GtkStyle *style)
833 return (GtkStyle *) g_object_ref (style);
838 * @style: a #GtkStyle.
840 * Deprecated equivalent of g_object_unref().
843 gtk_style_unref (GtkStyle *style)
845 g_object_unref (style);
849 gtk_style_realize (GtkStyle *style,
850 GdkColormap *colormap)
852 g_return_if_fail (GTK_IS_STYLE (style));
853 g_return_if_fail (GDK_IS_COLORMAP (colormap));
855 style->colormap = g_object_ref (colormap);
856 style->depth = gdk_colormap_get_visual (colormap)->depth;
858 g_signal_emit (style, realize_signal, 0);
862 gtk_style_lookup_icon_set (GtkStyle *style,
863 const char *stock_id)
867 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
868 g_return_val_if_fail (stock_id != NULL, NULL);
870 iter = style->icon_factories;
873 GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
878 iter = g_slist_next (iter);
881 return gtk_icon_factory_lookup_default (stock_id);
886 * @style: a #GtkStyle
887 * @window: a #GdkWindow
888 * @state_type: a state
889 * @x1: the starting x coordinate
890 * @x2: the ending x coordinate
891 * @y: the y coordinate
893 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
894 * using the given style and state.
896 * Deprecated: Use gtk_paint_hline() instead.
899 gtk_draw_hline (GtkStyle *style,
901 GtkStateType state_type,
906 g_return_if_fail (GTK_IS_STYLE (style));
907 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
909 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
915 * @style: a #GtkStyle
916 * @window: a #GdkWindow
917 * @state_type: a state
918 * @y1_: the starting y coordinate
919 * @y2_: the ending y coordinate
920 * @x: the x coordinate
922 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
923 * using the given style and state.
925 * Deprecated: Use gtk_paint_vline() instead.
928 gtk_draw_vline (GtkStyle *style,
930 GtkStateType state_type,
935 g_return_if_fail (GTK_IS_STYLE (style));
936 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
938 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1_, y2_, x);
943 * @style: a #GtkStyle
944 * @window: a #GdkWindow
945 * @state_type: a state
946 * @shadow_type: type of shadow to draw
947 * @x: x origin of the rectangle
948 * @y: y origin of the rectangle
949 * @width: width of the rectangle
950 * @height: width of the rectangle
952 * Draws a shadow around the given rectangle in @window
953 * using the given style and state and shadow type.
955 * Deprecated: Use gtk_paint_shadow() instead.
958 gtk_draw_shadow (GtkStyle *style,
960 GtkStateType state_type,
961 GtkShadowType shadow_type,
967 g_return_if_fail (GTK_IS_STYLE (style));
968 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
970 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
975 * @style: a #GtkStyle
976 * @window: a #GdkWindow
977 * @state_type: a state
978 * @shadow_type: type of shadow to draw
979 * @points: an array of #GdkPoint<!-- -->s
980 * @npoints: length of @points
981 * @fill: %TRUE if the polygon should be filled
983 * Draws a polygon on @window with the given parameters.
985 * Deprecated: Use gtk_paint_polygon() instead.
988 gtk_draw_polygon (GtkStyle *style,
990 GtkStateType state_type,
991 GtkShadowType shadow_type,
996 g_return_if_fail (GTK_IS_STYLE (style));
997 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
999 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
1004 * @style: a #GtkStyle
1005 * @window: a #GdkWindow
1006 * @state_type: a state
1007 * @shadow_type: the type of shadow to draw
1008 * @arrow_type: the type of arrow to draw
1009 * @fill: %TRUE if the arrow tip should be filled
1010 * @x: x origin of the rectangle to draw the arrow in
1011 * @y: y origin of the rectangle to draw the arrow in
1012 * @width: width of the rectangle to draw the arrow in
1013 * @height: height of the rectangle to draw the arrow in
1015 * Draws an arrow in the given rectangle on @window using the given
1016 * parameters. @arrow_type determines the direction of the arrow.
1018 * Deprecated: Use gtk_paint_arrow() instead.
1021 gtk_draw_arrow (GtkStyle *style,
1023 GtkStateType state_type,
1024 GtkShadowType shadow_type,
1025 GtkArrowType arrow_type,
1032 g_return_if_fail (GTK_IS_STYLE (style));
1033 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
1035 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
1040 * @style: a #GtkStyle
1041 * @window: a #GdkWindow
1042 * @state_type: a state
1043 * @shadow_type: the type of shadow to draw
1044 * @x: x origin of the rectangle to draw the diamond in
1045 * @y: y origin of the rectangle to draw the diamond in
1046 * @width: width of the rectangle to draw the diamond in
1047 * @height: height of the rectangle to draw the diamond in
1049 * Draws a diamond in the given rectangle on @window using the given
1052 * Deprecated: Use gtk_paint_diamond() instead.
1055 gtk_draw_diamond (GtkStyle *style,
1057 GtkStateType state_type,
1058 GtkShadowType shadow_type,
1064 g_return_if_fail (GTK_IS_STYLE (style));
1065 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
1067 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1072 * @style: a #GtkStyle
1073 * @window: a #GdkWindow
1074 * @state_type: a state
1077 * @string: the string to draw
1079 * Draws a text string on @window with the given parameters.
1081 * Deprecated: Use gtk_paint_layout() instead.
1084 gtk_draw_string (GtkStyle *style,
1086 GtkStateType state_type,
1089 const gchar *string)
1091 g_return_if_fail (GTK_IS_STYLE (style));
1092 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
1094 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
1099 * @style: a #GtkStyle
1100 * @window: a #GdkWindow
1101 * @state_type: a state
1102 * @shadow_type: the type of shadow to draw
1103 * @x: x origin of the box
1104 * @y: y origin of the box
1105 * @width: the width of the box
1106 * @height: the height of the box
1108 * Draws a box on @window with the given parameters.
1110 * Deprecated: Use gtk_paint_box() instead.
1113 gtk_draw_box (GtkStyle *style,
1115 GtkStateType state_type,
1116 GtkShadowType shadow_type,
1122 g_return_if_fail (GTK_IS_STYLE (style));
1123 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
1125 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1129 * gtk_draw_flat_box:
1130 * @style: a #GtkStyle
1131 * @window: a #GdkWindow
1132 * @state_type: a state
1133 * @shadow_type: the type of shadow to draw
1134 * @x: x origin of the box
1135 * @y: y origin of the box
1136 * @width: the width of the box
1137 * @height: the height of the box
1139 * Draws a flat box on @window with the given parameters.
1141 * Deprecated: Use gtk_paint_flat_box() instead.
1144 gtk_draw_flat_box (GtkStyle *style,
1146 GtkStateType state_type,
1147 GtkShadowType shadow_type,
1153 g_return_if_fail (GTK_IS_STYLE (style));
1154 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
1156 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1161 * @style: a #GtkStyle
1162 * @window: a #GdkWindow
1163 * @state_type: a state
1164 * @shadow_type: the type of shadow to draw
1165 * @x: x origin of the rectangle to draw the check in
1166 * @y: y origin of the rectangle to draw the check in
1167 * @width: the width of the rectangle to draw the check in
1168 * @height: the height of the rectangle to draw the check in
1170 * Draws a check button indicator in the given rectangle on @window with
1171 * the given parameters.
1173 * Deprecated: Use gtk_paint_check() instead.
1176 gtk_draw_check (GtkStyle *style,
1178 GtkStateType state_type,
1179 GtkShadowType shadow_type,
1185 g_return_if_fail (GTK_IS_STYLE (style));
1186 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
1188 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1193 * @style: a #GtkStyle
1194 * @window: a #GdkWindow
1195 * @state_type: a state
1196 * @shadow_type: the type of shadow to draw
1197 * @x: x origin of the rectangle to draw the option in
1198 * @y: y origin of the rectangle to draw the option in
1199 * @width: the width of the rectangle to draw the option in
1200 * @height: the height of the rectangle to draw the option in
1202 * Draws a radio button indicator in the given rectangle on @window with
1203 * the given parameters.
1205 * Deprecated: Use gtk_paint_option() instead.
1208 gtk_draw_option (GtkStyle *style,
1210 GtkStateType state_type,
1211 GtkShadowType shadow_type,
1217 g_return_if_fail (GTK_IS_STYLE (style));
1218 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
1220 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1225 * @style: a #GtkStyle
1226 * @window: a #GdkWindow
1227 * @state_type: a state
1228 * @shadow_type: the type of shadow to draw
1229 * @x: x origin of the rectangle to draw the tab in
1230 * @y: y origin of the rectangle to draw the tab in
1231 * @width: the width of the rectangle to draw the tab in
1232 * @height: the height of the rectangle to draw the tab in
1234 * Draws an option menu tab (i.e. the up and down pointing arrows)
1235 * in the given rectangle on @window using the given parameters.
1237 * Deprecated: Use gtk_paint_tab() instead.
1240 gtk_draw_tab (GtkStyle *style,
1242 GtkStateType state_type,
1243 GtkShadowType shadow_type,
1249 g_return_if_fail (GTK_IS_STYLE (style));
1250 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
1252 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
1256 * gtk_draw_shadow_gap:
1257 * @style: a #GtkStyle
1258 * @window: a #GdkWindow
1259 * @state_type: a state
1260 * @shadow_type: type of shadow to draw
1261 * @x: x origin of the rectangle
1262 * @y: y origin of the rectangle
1263 * @width: width of the rectangle
1264 * @height: width of the rectangle
1265 * @gap_side: side in which to leave the gap
1266 * @gap_x: starting position of the gap
1267 * @gap_width: width of the gap
1269 * Draws a shadow around the given rectangle in @window
1270 * using the given style and state and shadow type, leaving a
1273 * Deprecated: Use gtk_paint_shadow_gap() instead.
1276 gtk_draw_shadow_gap (GtkStyle *style,
1278 GtkStateType state_type,
1279 GtkShadowType shadow_type,
1284 GtkPositionType gap_side,
1288 g_return_if_fail (GTK_IS_STYLE (style));
1289 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
1291 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);
1296 * @style: a #GtkStyle
1297 * @window: a #GdkWindow
1298 * @state_type: a state
1299 * @shadow_type: type of shadow to draw
1300 * @x: x origin of the rectangle
1301 * @y: y origin of the rectangle
1302 * @width: width of the rectangle
1303 * @height: width of the rectangle
1304 * @gap_side: side in which to leave the gap
1305 * @gap_x: starting position of the gap
1306 * @gap_width: width of the gap
1308 * Draws a box in @window using the given style and state and shadow type,
1309 * leaving a gap in one side.
1311 * Deprecated: Use gtk_paint_box_gap() instead.
1314 gtk_draw_box_gap (GtkStyle *style,
1316 GtkStateType state_type,
1317 GtkShadowType shadow_type,
1322 GtkPositionType gap_side,
1326 g_return_if_fail (GTK_IS_STYLE (style));
1327 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
1329 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);
1333 * gtk_draw_extension:
1334 * @style: a #GtkStyle
1335 * @window: a #GdkWindow
1336 * @state_type: a state
1337 * @shadow_type: type of shadow to draw
1338 * @x: x origin of the extension
1339 * @y: y origin of the extension
1340 * @width: width of the extension
1341 * @height: width of the extension
1342 * @gap_side: the side on to which the extension is attached
1344 * Draws an extension, i.e. a notebook tab.
1346 * Deprecated: Use gtk_paint_extension() instead.
1349 gtk_draw_extension (GtkStyle *style,
1351 GtkStateType state_type,
1352 GtkShadowType shadow_type,
1357 GtkPositionType gap_side)
1359 g_return_if_fail (GTK_IS_STYLE (style));
1360 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
1362 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
1367 * @style: a #GtkStyle
1368 * @window: a #GdkWindow
1369 * @x: the x origin of the rectangle around which to draw a focus indicator
1370 * @y: the y origin of the rectangle around which to draw a focus indicator
1371 * @width: the width of the rectangle around which to draw a focus indicator
1372 * @height: the height of the rectangle around which to draw a focus indicator
1374 * Draws a focus indicator around the given rectangle on @window using the
1377 * Deprecated: Use gtk_paint_focus() instead.
1380 gtk_draw_focus (GtkStyle *style,
1387 g_return_if_fail (GTK_IS_STYLE (style));
1388 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
1390 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, width, height);
1394 gtk_draw_slider (GtkStyle *style,
1396 GtkStateType state_type,
1397 GtkShadowType shadow_type,
1402 GtkOrientation orientation)
1404 g_return_if_fail (GTK_IS_STYLE (style));
1405 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
1407 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1412 * @style: a #GtkStyle
1413 * @window: a #GdkWindow
1414 * @state_type: a state
1415 * @shadow_type: type of shadow to draw
1416 * @x: x origin of the handle
1417 * @y: y origin of the handle
1418 * @width: with of the handle
1419 * @height: height of the handle
1420 * @orientation: the orientation of the handle
1422 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
1424 * Deprecated: Use gtk_paint_handle() instead.
1427 gtk_draw_handle (GtkStyle *style,
1429 GtkStateType state_type,
1430 GtkShadowType shadow_type,
1435 GtkOrientation orientation)
1437 g_return_if_fail (GTK_IS_STYLE (style));
1438 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
1440 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
1444 * gtk_draw_expander:
1445 * @style: a #GtkStyle
1446 * @window: a #GdkWindow
1447 * @state_type: a state
1448 * @x: the x position to draw the expander at
1449 * @y: the y position to draw the expander at
1450 * @expander_style: the style to draw the expander in
1452 * Draws an expander as used in #GtkTreeView.
1454 * Deprecated: Use gtk_paint_expander() instead.
1457 gtk_draw_expander (GtkStyle *style,
1459 GtkStateType state_type,
1462 GtkExpanderStyle expander_style)
1464 g_return_if_fail (GTK_IS_STYLE (style));
1465 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
1467 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type,
1469 x, y, expander_style);
1473 gtk_draw_layout (GtkStyle *style,
1475 GtkStateType state_type,
1479 PangoLayout *layout)
1481 g_return_if_fail (GTK_IS_STYLE (style));
1482 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
1484 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text,
1490 * gtk_draw_resize_grip:
1491 * @style: a #GtkStyle
1492 * @window: a #GdkWindow
1493 * @state_type: a state
1494 * @edge: the edge in which to draw the resize grip
1495 * @x: the x origin of the rectangle in which to draw the resize grip
1496 * @y: the y origin of the rectangle in which to draw the resize grip
1497 * @width: the width of the rectangle in which to draw the resize grip
1498 * @height: the height of the rectangle in which to draw the resize grip
1500 * Draws a resize grip in the given rectangle on @window using the given
1503 * Deprecated: Use gtk_paint_resize_grip() instead.
1506 gtk_draw_resize_grip (GtkStyle *style,
1508 GtkStateType state_type,
1515 g_return_if_fail (GTK_IS_STYLE (style));
1516 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
1518 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
1521 x, y, width, height);
1526 * gtk_style_set_background:
1527 * @style: a #GtkStyle
1528 * @window: a #GdkWindow
1529 * @state_type: a state
1531 * Sets the background of @window to the background color or pixmap
1532 * specified by @style for the given state.
1535 gtk_style_set_background (GtkStyle *style,
1537 GtkStateType state_type)
1539 g_return_if_fail (GTK_IS_STYLE (style));
1540 g_return_if_fail (window != NULL);
1542 GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
1545 /* Default functions */
1547 gtk_style_real_clone (GtkStyle *style)
1549 return g_object_new (G_OBJECT_TYPE (style), NULL);
1553 gtk_style_real_copy (GtkStyle *style,
1558 for (i = 0; i < 5; i++)
1560 style->fg[i] = src->fg[i];
1561 style->bg[i] = src->bg[i];
1562 style->text[i] = src->text[i];
1563 style->base[i] = src->base[i];
1565 if (style->bg_pixmap[i])
1566 g_object_unref (style->bg_pixmap[i]),
1567 style->bg_pixmap[i] = src->bg_pixmap[i];
1568 if (style->bg_pixmap[i])
1569 g_object_ref (style->bg_pixmap[i]);
1572 if (style->private_font)
1573 gdk_font_unref (style->private_font);
1574 style->private_font = src->private_font;
1575 if (style->private_font)
1576 gdk_font_ref (style->private_font);
1578 if (style->font_desc)
1579 pango_font_description_free (style->font_desc);
1581 style->font_desc = pango_font_description_copy (src->font_desc);
1583 style->font_desc = NULL;
1585 style->xthickness = src->xthickness;
1586 style->ythickness = src->ythickness;
1588 if (style->rc_style)
1589 gtk_rc_style_unref (style->rc_style);
1590 style->rc_style = src->rc_style;
1592 gtk_rc_style_ref (src->rc_style);
1594 /* don't copy, just clear cache */
1595 clear_property_cache (style);
1599 gtk_style_real_init_from_rc (GtkStyle *style,
1600 GtkRcStyle *rc_style)
1604 /* cache _should_ be still empty */
1605 clear_property_cache (style);
1607 if (rc_style->font_desc)
1608 pango_font_description_merge (style->font_desc, rc_style->font_desc, TRUE);
1610 for (i = 0; i < 5; i++)
1612 if (rc_style->color_flags[i] & GTK_RC_FG)
1613 style->fg[i] = rc_style->fg[i];
1614 if (rc_style->color_flags[i] & GTK_RC_BG)
1615 style->bg[i] = rc_style->bg[i];
1616 if (rc_style->color_flags[i] & GTK_RC_TEXT)
1617 style->text[i] = rc_style->text[i];
1618 if (rc_style->color_flags[i] & GTK_RC_BASE)
1619 style->base[i] = rc_style->base[i];
1622 if (rc_style->xthickness >= 0)
1623 style->xthickness = rc_style->xthickness;
1624 if (rc_style->ythickness >= 0)
1625 style->ythickness = rc_style->ythickness;
1627 if (rc_style->icon_factories)
1631 style->icon_factories = g_slist_copy (rc_style->icon_factories);
1633 iter = style->icon_factories;
1634 while (iter != NULL)
1636 g_object_ref (iter->data);
1637 iter = g_slist_next (iter);
1643 style_property_values_cmp (gconstpointer bsearch_node1,
1644 gconstpointer bsearch_node2)
1646 const PropertyValue *val1 = bsearch_node1;
1647 const PropertyValue *val2 = bsearch_node2;
1649 if (val1->widget_type == val2->widget_type)
1650 return val1->pspec < val2->pspec ? -1 : val1->pspec == val2->pspec ? 0 : 1;
1652 return val1->widget_type < val2->widget_type ? -1 : 1;
1656 _gtk_style_peek_property_value (GtkStyle *style,
1659 GtkRcPropertyParser parser)
1661 PropertyValue *pcache, key = { 0, NULL, { 0, } };
1662 const GtkRcProperty *rcprop = NULL;
1665 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1666 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
1667 g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
1668 g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
1670 key.widget_type = widget_type;
1673 /* need value cache array */
1674 if (!style->property_cache)
1675 style->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
1678 pcache = bsearch (&key,
1679 style->property_cache->data, style->property_cache->len,
1680 sizeof (PropertyValue), style_property_values_cmp);
1682 return &pcache->value;
1686 while (i < style->property_cache->len &&
1687 style_property_values_cmp (&key, &g_array_index (style->property_cache, PropertyValue, i)) >= 0)
1690 g_array_insert_val (style->property_cache, i, key);
1691 pcache = &g_array_index (style->property_cache, PropertyValue, i);
1693 /* cache miss, initialize value type, then set contents */
1694 g_param_spec_ref (pcache->pspec);
1695 g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1697 /* value provided by rc style? */
1698 if (style->rc_style)
1700 GQuark prop_quark = g_quark_from_string (pspec->name);
1704 rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
1705 g_type_qname (widget_type),
1709 widget_type = g_type_parent (widget_type);
1711 while (g_type_is_a (widget_type, pspec->owner_type));
1714 /* when supplied by rc style, we need to convert */
1715 if (rcprop && !_gtk_settings_parse_convert (parser, &rcprop->value,
1716 pspec, &pcache->value))
1718 gchar *contents = g_strdup_value_contents (&rcprop->value);
1720 g_message ("%s: failed to retrieve property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
1722 g_type_name (pspec->owner_type), pspec->name,
1723 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1725 G_VALUE_TYPE_NAME (&rcprop->value));
1727 rcprop = NULL; /* needs default */
1730 /* not supplied by rc style (or conversion failed), revert to default */
1732 g_param_value_set_default (pspec, &pcache->value);
1734 return &pcache->value;
1738 load_bg_image (GdkColormap *colormap,
1740 const gchar *filename)
1742 if (strcmp (filename, "<parent>") == 0)
1743 return (GdkPixmap*) GDK_PARENT_RELATIVE;
1746 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
1753 gtk_style_real_realize (GtkStyle *style)
1755 GdkGCValues gc_values;
1756 GdkGCValuesMask gc_values_mask;
1760 for (i = 0; i < 5; i++)
1762 gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
1763 gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
1765 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1766 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
1767 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1769 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1770 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
1771 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
1774 style->black.red = 0x0000;
1775 style->black.green = 0x0000;
1776 style->black.blue = 0x0000;
1777 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
1779 style->white.red = 0xffff;
1780 style->white.green = 0xffff;
1781 style->white.blue = 0xffff;
1782 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
1784 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
1786 gc_values.foreground = style->black;
1787 gc_values.background = style->white;
1788 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1790 gc_values.foreground = style->white;
1791 gc_values.background = style->black;
1792 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1794 gc_values_mask = GDK_GC_FOREGROUND;
1796 for (i = 0; i < 5; i++)
1798 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
1799 style->bg_pixmap[i] = load_bg_image (style->colormap,
1801 style->rc_style->bg_pixmap_name[i]);
1803 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
1804 g_warning ("unable to allocate color: ( %d %d %d )",
1805 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
1806 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
1807 g_warning ("unable to allocate color: ( %d %d %d )",
1808 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
1809 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
1810 g_warning ("unable to allocate color: ( %d %d %d )",
1811 style->light[i].red, style->light[i].green, style->light[i].blue);
1812 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
1813 g_warning ("unable to allocate color: ( %d %d %d )",
1814 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
1815 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
1816 g_warning ("unable to allocate color: ( %d %d %d )",
1817 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
1818 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
1819 g_warning ("unable to allocate color: ( %d %d %d )",
1820 style->text[i].red, style->text[i].green, style->text[i].blue);
1821 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
1822 g_warning ("unable to allocate color: ( %d %d %d )",
1823 style->base[i].red, style->base[i].green, style->base[i].blue);
1824 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
1825 g_warning ("unable to allocate color: ( %d %d %d )",
1826 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
1828 gc_values.foreground = style->fg[i];
1829 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1831 gc_values.foreground = style->bg[i];
1832 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1834 gc_values.foreground = style->light[i];
1835 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1837 gc_values.foreground = style->dark[i];
1838 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1840 gc_values.foreground = style->mid[i];
1841 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1843 gc_values.foreground = style->text[i];
1844 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1846 gc_values.foreground = style->base[i];
1847 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1849 gc_values.foreground = style->text_aa[i];
1850 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
1855 gtk_style_real_unrealize (GtkStyle *style)
1859 gtk_gc_release (style->black_gc);
1860 gtk_gc_release (style->white_gc);
1862 for (i = 0; i < 5; i++)
1864 gtk_gc_release (style->fg_gc[i]);
1865 gtk_gc_release (style->bg_gc[i]);
1866 gtk_gc_release (style->light_gc[i]);
1867 gtk_gc_release (style->dark_gc[i]);
1868 gtk_gc_release (style->mid_gc[i]);
1869 gtk_gc_release (style->text_gc[i]);
1870 gtk_gc_release (style->base_gc[i]);
1871 gtk_gc_release (style->text_aa_gc[i]);
1873 if (style->bg_pixmap[i] && style->bg_pixmap[i] != (GdkPixmap*) GDK_PARENT_RELATIVE)
1875 g_object_unref (style->bg_pixmap[i]);
1876 style->bg_pixmap[i] = NULL;
1881 gdk_colormap_free_colors (style->colormap, style->fg, 5);
1882 gdk_colormap_free_colors (style->colormap, style->bg, 5);
1883 gdk_colormap_free_colors (style->colormap, style->light, 5);
1884 gdk_colormap_free_colors (style->colormap, style->dark, 5);
1885 gdk_colormap_free_colors (style->colormap, style->mid, 5);
1886 gdk_colormap_free_colors (style->colormap, style->text, 5);
1887 gdk_colormap_free_colors (style->colormap, style->base, 5);
1888 gdk_colormap_free_colors (style->colormap, style->text_aa, 5);
1890 style_unrealize_cursor_gcs (style);
1894 gtk_style_real_set_background (GtkStyle *style,
1896 GtkStateType state_type)
1899 gint parent_relative;
1901 if (style->bg_pixmap[state_type])
1903 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
1906 parent_relative = TRUE;
1910 pixmap = style->bg_pixmap[state_type];
1911 parent_relative = FALSE;
1914 gdk_window_set_back_pixmap (window, pixmap, parent_relative);
1917 gdk_window_set_background (window, &style->bg[state_type]);
1921 * gtk_style_render_icon:
1922 * @style: a #GtkStyle
1923 * @source: the #GtkIconSource specifying the icon to render
1924 * @direction: a text direction
1926 * @size: the size to render the icon at. A size of (GtkIconSize)-1
1927 * means render at the size of the source and don't scale.
1928 * @widget: the widget
1929 * @detail: a style detail
1930 * @returns: a newly-created #GdkPixbuf containing the rendered icon
1932 * Renders the icon specified by @source at the given @size
1933 * according to the given parameters and returns the result in a
1937 gtk_style_render_icon (GtkStyle *style,
1938 const GtkIconSource *source,
1939 GtkTextDirection direction,
1943 const gchar *detail)
1947 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
1948 g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
1950 pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
1951 size, widget, detail);
1953 g_return_val_if_fail (pixbuf != NULL, NULL);
1958 /* Default functions */
1960 gtk_style_apply_default_background (GtkStyle *style,
1963 GtkStateType state_type,
1970 GdkRectangle new_rect, old_rect;
1976 old_rect.width = width;
1977 old_rect.height = height;
1979 if (!gdk_rectangle_intersect (area, &old_rect, &new_rect))
1986 new_rect.width = width;
1987 new_rect.height = height;
1990 if (!style->bg_pixmap[state_type] ||
1991 GDK_IS_PIXMAP (window) ||
1992 (!set_bg && style->bg_pixmap[state_type] != (GdkPixmap*) GDK_PARENT_RELATIVE))
1994 GdkGC *gc = style->bg_gc[state_type];
1996 if (style->bg_pixmap[state_type])
1998 gdk_gc_set_fill (gc, GDK_TILED);
1999 gdk_gc_set_tile (gc, style->bg_pixmap[state_type]);
2002 gdk_draw_rectangle (window, gc, TRUE,
2003 new_rect.x, new_rect.y, new_rect.width, new_rect.height);
2004 if (style->bg_pixmap[state_type])
2005 gdk_gc_set_fill (gc, GDK_SOLID);
2011 if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
2012 gdk_window_set_back_pixmap (window, NULL, TRUE);
2014 gdk_window_set_back_pixmap (window, style->bg_pixmap[state_type], FALSE);
2017 gdk_window_clear_area (window,
2018 new_rect.x, new_rect.y,
2019 new_rect.width, new_rect.height);
2024 scale_or_ref (GdkPixbuf *src,
2028 if (width == gdk_pixbuf_get_width (src) &&
2029 height == gdk_pixbuf_get_height (src))
2031 return g_object_ref (src);
2035 return gdk_pixbuf_scale_simple (src,
2037 GDK_INTERP_BILINEAR);
2042 gtk_default_render_icon (GtkStyle *style,
2043 const GtkIconSource *source,
2044 GtkTextDirection direction,
2048 const gchar *detail)
2054 GdkPixbuf *base_pixbuf;
2056 GtkSettings *settings;
2058 /* Oddly, style can be NULL in this function, because
2059 * GtkIconSet can be used without a style and if so
2060 * it uses this function.
2063 base_pixbuf = gtk_icon_source_get_pixbuf (source);
2065 g_return_val_if_fail (base_pixbuf != NULL, NULL);
2067 if (widget && gtk_widget_has_screen (widget))
2069 screen = gtk_widget_get_screen (widget);
2070 settings = gtk_settings_get_for_screen (screen);
2072 else if (style && style->colormap)
2074 screen = gdk_colormap_get_screen (style->colormap);
2075 settings = gtk_settings_get_for_screen (screen);
2079 settings = gtk_settings_get_default ();
2080 GTK_NOTE (MULTIHEAD,
2081 g_warning ("Using the default screen for gtk_default_render_icon()"));
2085 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
2087 g_warning (G_STRLOC ": invalid icon size '%d'", size);
2091 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
2094 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
2095 scaled = scale_or_ref (base_pixbuf, width, height);
2097 scaled = g_object_ref (base_pixbuf);
2099 /* If the state was wildcarded, then generate a state. */
2100 if (gtk_icon_source_get_state_wildcarded (source))
2102 if (state == GTK_STATE_INSENSITIVE)
2104 stated = gdk_pixbuf_copy (scaled);
2106 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2109 g_object_unref (scaled);
2111 else if (state == GTK_STATE_PRELIGHT)
2113 stated = gdk_pixbuf_copy (scaled);
2115 gdk_pixbuf_saturate_and_pixelate (scaled, stated,
2118 g_object_unref (scaled);
2132 sanitize_size (GdkWindow *window,
2136 if ((*width == -1) && (*height == -1))
2137 gdk_drawable_get_size (window, width, height);
2138 else if (*width == -1)
2139 gdk_drawable_get_size (window, width, NULL);
2140 else if (*height == -1)
2141 gdk_drawable_get_size (window, NULL, height);
2145 gtk_default_draw_hline (GtkStyle *style,
2147 GtkStateType state_type,
2150 const gchar *detail,
2155 gint thickness_light;
2156 gint thickness_dark;
2159 g_return_if_fail (GTK_IS_STYLE (style));
2160 g_return_if_fail (window != NULL);
2162 thickness_light = style->ythickness / 2;
2163 thickness_dark = style->ythickness - thickness_light;
2167 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2168 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2171 if (detail && !strcmp (detail, "label"))
2173 if (state_type == GTK_STATE_INSENSITIVE)
2174 gdk_draw_line (window, style->white_gc, x1 + 1, y + 1, x2 + 1, y + 1);
2175 gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y);
2179 for (i = 0; i < thickness_dark; i++)
2181 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
2182 gdk_draw_line (window, style->light_gc[state_type], x2 - i, y + i, x2, y + i);
2185 y += thickness_dark;
2186 for (i = 0; i < thickness_light; i++)
2188 gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
2189 gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i, y + i, x2, y + i);
2195 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2196 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2202 gtk_default_draw_vline (GtkStyle *style,
2204 GtkStateType state_type,
2207 const gchar *detail,
2212 gint thickness_light;
2213 gint thickness_dark;
2216 g_return_if_fail (GTK_IS_STYLE (style));
2217 g_return_if_fail (window != NULL);
2219 thickness_light = style->xthickness / 2;
2220 thickness_dark = style->xthickness - thickness_light;
2224 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2225 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2227 for (i = 0; i < thickness_dark; i++)
2229 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
2230 gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i, x + i, y2);
2233 x += thickness_dark;
2234 for (i = 0; i < thickness_light; i++)
2236 gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i - 1);
2237 gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
2241 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2242 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2247 draw_thin_shadow (GtkStyle *style,
2258 sanitize_size (window, &width, &height);
2260 gc1 = style->light_gc[state];
2261 gc2 = style->dark_gc[state];
2265 gdk_gc_set_clip_rectangle (gc1, area);
2266 gdk_gc_set_clip_rectangle (gc2, area);
2269 gdk_draw_line (window, gc1,
2270 x, y + height - 1, x + width - 1, y + height - 1);
2271 gdk_draw_line (window, gc1,
2272 x + width - 1, y, x + width - 1, y + height - 1);
2274 gdk_draw_line (window, gc2,
2275 x, y, x + width - 2, y);
2276 gdk_draw_line (window, gc2,
2277 x, y, x, y + height - 2);
2281 gdk_gc_set_clip_rectangle (gc1, NULL);
2282 gdk_gc_set_clip_rectangle (gc2, NULL);
2287 draw_spinbutton_shadow (GtkStyle *style,
2290 GtkTextDirection direction,
2297 sanitize_size (window, &width, &height);
2301 gdk_gc_set_clip_rectangle (style->black_gc, area);
2302 gdk_gc_set_clip_rectangle (style->bg_gc[state], area);
2303 gdk_gc_set_clip_rectangle (style->dark_gc[state], area);
2304 gdk_gc_set_clip_rectangle (style->light_gc[state], area);
2307 if (direction == GTK_TEXT_DIR_LTR)
2309 gdk_draw_line (window, style->dark_gc[state],
2310 x, y, x + width - 1, y);
2311 gdk_draw_line (window, style->black_gc,
2312 x, y + 1, x + width - 2, y + 1);
2313 gdk_draw_line (window, style->black_gc,
2314 x + width - 2, y + 2, x + width - 2, y + height - 3);
2315 gdk_draw_line (window, style->light_gc[state],
2316 x + width - 1, y + 1, x + width - 1, y + height - 2);
2317 gdk_draw_line (window, style->light_gc[state],
2318 x, y + height - 1, x + width - 1, y + height - 1);
2319 gdk_draw_line (window, style->bg_gc[state],
2320 x, y + height - 2, x + width - 2, y + height - 2);
2321 gdk_draw_line (window, style->black_gc,
2322 x, y + 2, x, y + height - 3);
2326 gdk_draw_line (window, style->dark_gc[state],
2327 x, y, x + width - 1, y);
2328 gdk_draw_line (window, style->dark_gc[state],
2329 x, y + 1, x, y + height - 1);
2330 gdk_draw_line (window, style->black_gc,
2331 x + 1, y + 1, x + width - 1, y + 1);
2332 gdk_draw_line (window, style->black_gc,
2333 x + 1, y + 2, x + 1, y + height - 2);
2334 gdk_draw_line (window, style->black_gc,
2335 x + width - 1, y + 2, x + width - 1, y + height - 3);
2336 gdk_draw_line (window, style->light_gc[state],
2337 x + 1, y + height - 1, x + width - 1, y + height - 1);
2338 gdk_draw_line (window, style->bg_gc[state],
2339 x + 2, y + height - 2, x + width - 1, y + height - 2);
2344 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2345 gdk_gc_set_clip_rectangle (style->bg_gc[state], NULL);
2346 gdk_gc_set_clip_rectangle (style->dark_gc[state], NULL);
2347 gdk_gc_set_clip_rectangle (style->light_gc[state], NULL);
2352 draw_menu_shadow (GtkStyle *style,
2361 if (style->ythickness > 0)
2363 if (style->ythickness > 1)
2365 gdk_draw_line (window, style->dark_gc[state],
2366 x + 1, y + height - 2, x + width - 2, y + height - 2);
2367 gdk_draw_line (window, style->black_gc,
2368 x, y + height - 1, x + width - 1, y + height - 1);
2372 gdk_draw_line (window, style->dark_gc[state],
2373 x + 1, y + height - 1, x + width - 1, y + height - 1);
2377 if (style->xthickness > 0)
2379 if (style->xthickness > 1)
2381 gdk_draw_line (window, style->dark_gc[state],
2382 x + width - 2, y + 1, x + width - 2, y + height - 2);
2384 gdk_draw_line (window, style->black_gc,
2385 x + width - 1, y, x + width - 1, y + height - 1);
2389 gdk_draw_line (window, style->dark_gc[state],
2390 x + width - 1, y + 1, x + width - 1, y + height - 1);
2394 /* Light around top and left */
2396 if (style->ythickness > 0)
2397 gdk_draw_line (window, style->black_gc,
2398 x, y, x + width - 2, y);
2399 if (style->xthickness > 0)
2400 gdk_draw_line (window, style->black_gc,
2401 x, y, x, y + height - 2);
2403 if (style->ythickness > 1)
2404 gdk_draw_line (window, style->light_gc[state],
2405 x + 1, y + 1, x + width - 3, y + 1);
2406 if (style->xthickness > 1)
2407 gdk_draw_line (window, style->light_gc[state],
2408 x + 1, y + 1, x + 1, y + height - 3);
2411 static GtkTextDirection
2412 get_direction (GtkWidget *widget)
2414 GtkTextDirection dir;
2417 dir = gtk_widget_get_direction (widget);
2419 dir = GTK_TEXT_DIR_LTR;
2426 gtk_default_draw_shadow (GtkStyle *style,
2428 GtkStateType state_type,
2429 GtkShadowType shadow_type,
2432 const gchar *detail,
2440 gint thickness_light;
2441 gint thickness_dark;
2444 g_return_if_fail (GTK_IS_STYLE (style));
2445 g_return_if_fail (window != NULL);
2447 if (shadow_type == GTK_SHADOW_IN)
2449 if (detail && (strcmp (detail, "buttondefault") == 0))
2451 sanitize_size (window, &width, &height);
2453 gdk_draw_rectangle (window, style->black_gc, FALSE,
2454 x, y, width - 1, height - 1);
2458 if (detail && strcmp (detail, "trough") == 0)
2460 draw_thin_shadow (style, window, state_type, area,
2461 x, y, width, height);
2464 if (widget && GTK_IS_SPIN_BUTTON (widget) &&
2465 detail && strcmp (detail, "spinbutton") == 0)
2467 draw_spinbutton_shadow (style, window, state_type,
2468 get_direction (widget), area, x, y, width, height);
2474 if (shadow_type == GTK_SHADOW_OUT && detail && strcmp (detail, "menu") == 0)
2476 draw_menu_shadow (style, window, state_type, area, x, y, width, height);
2480 sanitize_size (window, &width, &height);
2482 switch (shadow_type)
2484 case GTK_SHADOW_NONE:
2487 case GTK_SHADOW_ETCHED_IN:
2488 gc1 = style->light_gc[state_type];
2489 gc2 = style->dark_gc[state_type];
2491 case GTK_SHADOW_OUT:
2492 case GTK_SHADOW_ETCHED_OUT:
2493 gc1 = style->dark_gc[state_type];
2494 gc2 = style->light_gc[state_type];
2500 gdk_gc_set_clip_rectangle (gc1, area);
2501 gdk_gc_set_clip_rectangle (gc2, area);
2502 if (shadow_type == GTK_SHADOW_IN ||
2503 shadow_type == GTK_SHADOW_OUT)
2505 gdk_gc_set_clip_rectangle (style->black_gc, area);
2506 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
2510 switch (shadow_type)
2512 case GTK_SHADOW_NONE:
2516 /* Light around right and bottom edge */
2518 if (style->ythickness > 0)
2519 gdk_draw_line (window, gc1,
2520 x, y + height - 1, x + width - 1, y + height - 1);
2521 if (style->xthickness > 0)
2522 gdk_draw_line (window, gc1,
2523 x + width - 1, y, x + width - 1, y + height - 1);
2525 if (style->ythickness > 1)
2526 gdk_draw_line (window, style->bg_gc[state_type],
2527 x + 1, y + height - 2, x + width - 2, y + height - 2);
2528 if (style->xthickness > 1)
2529 gdk_draw_line (window, style->bg_gc[state_type],
2530 x + width - 2, y + 1, x + width - 2, y + height - 2);
2532 /* Dark around left and top */
2534 if (style->ythickness > 1)
2535 gdk_draw_line (window, style->black_gc,
2536 x + 1, y + 1, x + width - 2, y + 1);
2537 if (style->xthickness > 1)
2538 gdk_draw_line (window, style->black_gc,
2539 x + 1, y + 1, x + 1, y + height - 2);
2541 if (style->ythickness > 0)
2542 gdk_draw_line (window, gc2,
2543 x, y, x + width - 1, y);
2544 if (style->xthickness > 0)
2545 gdk_draw_line (window, gc2,
2546 x, y, x, y + height - 1);
2549 case GTK_SHADOW_OUT:
2550 /* Dark around right and bottom edge */
2552 if (style->ythickness > 0)
2554 if (style->ythickness > 1)
2556 gdk_draw_line (window, gc1,
2557 x + 1, y + height - 2, x + width - 2, y + height - 2);
2558 gdk_draw_line (window, style->black_gc,
2559 x, y + height - 1, x + width - 1, y + height - 1);
2563 gdk_draw_line (window, gc1,
2564 x + 1, y + height - 1, x + width - 1, y + height - 1);
2568 if (style->xthickness > 0)
2570 if (style->xthickness > 1)
2572 gdk_draw_line (window, gc1,
2573 x + width - 2, y + 1, x + width - 2, y + height - 2);
2575 gdk_draw_line (window, style->black_gc,
2576 x + width - 1, y, x + width - 1, y + height - 1);
2580 gdk_draw_line (window, gc1,
2581 x + width - 1, y + 1, x + width - 1, y + height - 1);
2585 /* Light around top and left */
2587 if (style->ythickness > 0)
2588 gdk_draw_line (window, gc2,
2589 x, y, x + width - 2, y);
2590 if (style->xthickness > 0)
2591 gdk_draw_line (window, gc2,
2592 x, y, x, y + height - 2);
2594 if (style->ythickness > 1)
2595 gdk_draw_line (window, style->bg_gc[state_type],
2596 x + 1, y + 1, x + width - 3, y + 1);
2597 if (style->xthickness > 1)
2598 gdk_draw_line (window, style->bg_gc[state_type],
2599 x + 1, y + 1, x + 1, y + height - 3);
2602 case GTK_SHADOW_ETCHED_IN:
2603 case GTK_SHADOW_ETCHED_OUT:
2604 if (style->xthickness > 0)
2606 if (style->xthickness > 1)
2608 thickness_light = 1;
2611 for (i = 0; i < thickness_dark; i++)
2613 gdk_draw_line (window, gc1,
2617 y + height - i - 1);
2618 gdk_draw_line (window, gc2,
2622 y + height - i - 2);
2625 for (i = 0; i < thickness_light; i++)
2627 gdk_draw_line (window, gc1,
2628 x + thickness_dark + i,
2629 y + thickness_dark + i,
2630 x + thickness_dark + i,
2631 y + height - thickness_dark - i - 1);
2632 gdk_draw_line (window, gc2,
2633 x + width - thickness_light - i - 1,
2634 y + thickness_dark + i,
2635 x + width - thickness_light - i - 1,
2636 y + height - thickness_light - 1);
2641 gdk_draw_line (window,
2642 style->dark_gc[state_type],
2643 x, y, x, y + height);
2644 gdk_draw_line (window,
2645 style->dark_gc[state_type],
2646 x + width, y, x + width, y + height);
2650 if (style->ythickness > 0)
2652 if (style->ythickness > 1)
2654 thickness_light = 1;
2657 for (i = 0; i < thickness_dark; i++)
2659 gdk_draw_line (window, gc1,
2663 y + height - i - 1);
2665 gdk_draw_line (window, gc2,
2672 for (i = 0; i < thickness_light; i++)
2674 gdk_draw_line (window, gc1,
2675 x + thickness_dark + i,
2676 y + thickness_dark + i,
2677 x + width - thickness_dark - i - 2,
2678 y + thickness_dark + i);
2680 gdk_draw_line (window, gc2,
2681 x + thickness_dark + i,
2682 y + height - thickness_light - i - 1,
2683 x + width - thickness_light - 1,
2684 y + height - thickness_light - i - 1);
2689 gdk_draw_line (window,
2690 style->dark_gc[state_type],
2691 x, y, x + width, y);
2692 gdk_draw_line (window,
2693 style->dark_gc[state_type],
2694 x, y + height, x + width, y + height);
2701 if (shadow_type == GTK_SHADOW_IN &&
2702 widget && GTK_IS_SPIN_BUTTON (widget) &&
2703 detail && strcmp (detail, "entry") == 0)
2705 if (get_direction (widget) == GTK_TEXT_DIR_LTR)
2707 gdk_draw_line (window,
2708 style->base_gc[state_type],
2709 x + width - 1, y + 2,
2710 x + width - 1, y + height - 3);
2711 gdk_draw_line (window,
2712 style->base_gc[state_type],
2713 x + width - 2, y + 2,
2714 x + width - 2, y + height - 3);
2715 gdk_draw_point (window,
2717 x + width - 1, y + 1);
2718 gdk_draw_point (window,
2719 style->bg_gc[state_type],
2720 x + width - 1, y + height - 2);
2724 gdk_draw_line (window,
2725 style->base_gc[state_type],
2728 gdk_draw_line (window,
2729 style->base_gc[state_type],
2731 x + 1, y + height - 3);
2732 gdk_draw_point (window,
2735 gdk_draw_line (window,
2736 style->bg_gc[state_type],
2738 x + 1, y + height - 2);
2739 gdk_draw_point (window,
2740 style->light_gc[state_type],
2748 gdk_gc_set_clip_rectangle (gc1, NULL);
2749 gdk_gc_set_clip_rectangle (gc2, NULL);
2750 if (shadow_type == GTK_SHADOW_IN ||
2751 shadow_type == GTK_SHADOW_OUT)
2753 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
2754 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
2760 gtk_default_draw_polygon (GtkStyle *style,
2762 GtkStateType state_type,
2763 GtkShadowType shadow_type,
2766 const gchar *detail,
2771 static const gdouble pi_over_4 = G_PI_4;
2772 static const gdouble pi_3_over_4 = G_PI_4 * 3;
2782 g_return_if_fail (GTK_IS_STYLE (style));
2783 g_return_if_fail (window != NULL);
2784 g_return_if_fail (points != NULL);
2786 switch (shadow_type)
2789 gc1 = style->bg_gc[state_type];
2790 gc2 = style->dark_gc[state_type];
2791 gc3 = style->light_gc[state_type];
2792 gc4 = style->black_gc;
2794 case GTK_SHADOW_ETCHED_IN:
2795 gc1 = style->light_gc[state_type];
2796 gc2 = style->dark_gc[state_type];
2797 gc3 = style->dark_gc[state_type];
2798 gc4 = style->light_gc[state_type];
2800 case GTK_SHADOW_OUT:
2801 gc1 = style->dark_gc[state_type];
2802 gc2 = style->light_gc[state_type];
2803 gc3 = style->black_gc;
2804 gc4 = style->bg_gc[state_type];
2806 case GTK_SHADOW_ETCHED_OUT:
2807 gc1 = style->dark_gc[state_type];
2808 gc2 = style->light_gc[state_type];
2809 gc3 = style->light_gc[state_type];
2810 gc4 = style->dark_gc[state_type];
2818 gdk_gc_set_clip_rectangle (gc1, area);
2819 gdk_gc_set_clip_rectangle (gc2, area);
2820 gdk_gc_set_clip_rectangle (gc3, area);
2821 gdk_gc_set_clip_rectangle (gc4, area);
2825 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
2829 for (i = 0; i < npoints; i++)
2831 if ((points[i].x == points[i+1].x) &&
2832 (points[i].y == points[i+1].y))
2838 angle = atan2 (points[i+1].y - points[i].y,
2839 points[i+1].x - points[i].x);
2842 if ((angle > -pi_3_over_4) && (angle < pi_over_4))
2844 if (angle > -pi_over_4)
2855 gdk_draw_line (window, gc1,
2856 points[i].x-xadjust, points[i].y-yadjust,
2857 points[i+1].x-xadjust, points[i+1].y-yadjust);
2858 gdk_draw_line (window, gc3,
2859 points[i].x, points[i].y,
2860 points[i+1].x, points[i+1].y);
2864 if ((angle < -pi_3_over_4) || (angle > pi_3_over_4))
2875 gdk_draw_line (window, gc4,
2876 points[i].x+xadjust, points[i].y+yadjust,
2877 points[i+1].x+xadjust, points[i+1].y+yadjust);
2878 gdk_draw_line (window, gc2,
2879 points[i].x, points[i].y,
2880 points[i+1].x, points[i+1].y);
2886 gdk_gc_set_clip_rectangle (gc1, NULL);
2887 gdk_gc_set_clip_rectangle (gc2, NULL);
2888 gdk_gc_set_clip_rectangle (gc3, NULL);
2889 gdk_gc_set_clip_rectangle (gc4, NULL);
2894 draw_arrow (GdkWindow *window,
2897 GtkArrowType arrow_type,
2903 cairo_t *cr = gdk_cairo_create (window);
2904 gdk_cairo_set_source_color (cr, color);
2908 gdk_cairo_rectangle (cr, area);
2912 if (arrow_type == GTK_ARROW_DOWN)
2914 cairo_move_to (cr, x, y);
2915 cairo_line_to (cr, x + width, y);
2916 cairo_line_to (cr, x + width / 2., y + height);
2918 else if (arrow_type == GTK_ARROW_UP)
2920 cairo_move_to (cr, x, y + height);
2921 cairo_line_to (cr, x + width / 2., y);
2922 cairo_line_to (cr, x + width, y + height);
2924 else if (arrow_type == GTK_ARROW_LEFT)
2926 cairo_move_to (cr, x + width, y);
2927 cairo_line_to (cr, x + width, y + height);
2928 cairo_line_to (cr, x, y + height / 2.);
2930 else if (arrow_type == GTK_ARROW_RIGHT)
2932 cairo_move_to (cr, x, y);
2933 cairo_line_to (cr, x + width, y + height / 2.);
2934 cairo_line_to (cr, x, y + height);
2937 cairo_close_path (cr);
2944 calculate_arrow_geometry (GtkArrowType arrow_type,
2956 case GTK_ARROW_DOWN:
2966 if (arrow_type == GTK_ARROW_DOWN)
2968 if (*height % 2 == 1 || h % 2 == 0)
2973 if (*height % 2 == 0 || h % 2 == 0)
2978 case GTK_ARROW_RIGHT:
2979 case GTK_ARROW_LEFT:
2989 if (arrow_type == GTK_ARROW_RIGHT)
2991 if (*width % 2 == 1 || w % 2 == 0)
2996 if (*width % 2 == 0 || w % 2 == 0)
3002 /* should not be reached */
3006 *x += (*width - w) / 2;
3007 *y += (*height - h) / 2;
3013 gtk_default_draw_arrow (GtkStyle *style,
3016 GtkShadowType shadow,
3019 const gchar *detail,
3020 GtkArrowType arrow_type,
3027 gint original_width, original_x;
3029 sanitize_size (window, &width, &height);
3031 original_width = width;
3034 calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
3036 if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
3039 if (state == GTK_STATE_INSENSITIVE)
3040 draw_arrow (window, &style->white, area, arrow_type,
3041 x + 1, y + 1, width, height);
3042 draw_arrow (window, &style->fg[state], area, arrow_type,
3043 x, y, width, height);
3047 gtk_default_draw_diamond (GtkStyle *style,
3049 GtkStateType state_type,
3050 GtkShadowType shadow_type,
3053 const gchar *detail,
3061 GdkGC *outer_nw = NULL;
3062 GdkGC *outer_ne = NULL;
3063 GdkGC *outer_sw = NULL;
3064 GdkGC *outer_se = NULL;
3065 GdkGC *middle_nw = NULL;
3066 GdkGC *middle_ne = NULL;
3067 GdkGC *middle_sw = NULL;
3068 GdkGC *middle_se = NULL;
3069 GdkGC *inner_nw = NULL;
3070 GdkGC *inner_ne = NULL;
3071 GdkGC *inner_sw = NULL;
3072 GdkGC *inner_se = NULL;
3074 g_return_if_fail (GTK_IS_STYLE (style));
3075 g_return_if_fail (window != NULL);
3077 sanitize_size (window, &width, &height);
3079 half_width = width / 2;
3080 half_height = height / 2;
3084 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3085 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
3086 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3087 gdk_gc_set_clip_rectangle (style->black_gc, area);
3090 switch (shadow_type)
3093 inner_sw = inner_se = style->bg_gc[state_type];
3094 middle_sw = middle_se = style->light_gc[state_type];
3095 outer_sw = outer_se = style->light_gc[state_type];
3096 inner_nw = inner_ne = style->black_gc;
3097 middle_nw = middle_ne = style->dark_gc[state_type];
3098 outer_nw = outer_ne = style->dark_gc[state_type];
3101 case GTK_SHADOW_OUT:
3102 inner_sw = inner_se = style->dark_gc[state_type];
3103 middle_sw = middle_se = style->dark_gc[state_type];
3104 outer_sw = outer_se = style->black_gc;
3105 inner_nw = inner_ne = style->bg_gc[state_type];
3106 middle_nw = middle_ne = style->light_gc[state_type];
3107 outer_nw = outer_ne = style->light_gc[state_type];
3110 case GTK_SHADOW_ETCHED_IN:
3111 inner_sw = inner_se = style->bg_gc[state_type];
3112 middle_sw = middle_se = style->dark_gc[state_type];
3113 outer_sw = outer_se = style->light_gc[state_type];
3114 inner_nw = inner_ne = style->bg_gc[state_type];
3115 middle_nw = middle_ne = style->light_gc[state_type];
3116 outer_nw = outer_ne = style->dark_gc[state_type];
3119 case GTK_SHADOW_ETCHED_OUT:
3120 inner_sw = inner_se = style->bg_gc[state_type];
3121 middle_sw = middle_se = style->light_gc[state_type];
3122 outer_sw = outer_se = style->dark_gc[state_type];
3123 inner_nw = inner_ne = style->bg_gc[state_type];
3124 middle_nw = middle_ne = style->dark_gc[state_type];
3125 outer_nw = outer_ne = style->light_gc[state_type];
3135 gdk_draw_line (window, inner_sw,
3136 x + 2, y + half_height,
3137 x + half_width, y + height - 2);
3138 gdk_draw_line (window, inner_se,
3139 x + half_width, y + height - 2,
3140 x + width - 2, y + half_height);
3141 gdk_draw_line (window, middle_sw,
3142 x + 1, y + half_height,
3143 x + half_width, y + height - 1);
3144 gdk_draw_line (window, middle_se,
3145 x + half_width, y + height - 1,
3146 x + width - 1, y + half_height);
3147 gdk_draw_line (window, outer_sw,
3149 x + half_width, y + height);
3150 gdk_draw_line (window, outer_se,
3151 x + half_width, y + height,
3152 x + width, y + half_height);
3154 gdk_draw_line (window, inner_nw,
3155 x + 2, y + half_height,
3156 x + half_width, y + 2);
3157 gdk_draw_line (window, inner_ne,
3158 x + half_width, y + 2,
3159 x + width - 2, y + half_height);
3160 gdk_draw_line (window, middle_nw,
3161 x + 1, y + half_height,
3162 x + half_width, y + 1);
3163 gdk_draw_line (window, middle_ne,
3164 x + half_width, y + 1,
3165 x + width - 1, y + half_height);
3166 gdk_draw_line (window, outer_nw,
3169 gdk_draw_line (window, outer_ne,
3171 x + width, y + half_height);
3176 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3177 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
3178 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3179 gdk_gc_set_clip_rectangle (style->black_gc, NULL);
3184 gtk_default_draw_string (GtkStyle *style,
3186 GtkStateType state_type,
3189 const gchar *detail,
3192 const gchar *string)
3194 GdkDisplay *display;
3196 g_return_if_fail (GTK_IS_STYLE (style));
3197 g_return_if_fail (window != NULL);
3199 display = gdk_drawable_get_display (window);
3203 gdk_gc_set_clip_rectangle (style->white_gc, area);
3204 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], area);
3207 if (state_type == GTK_STATE_INSENSITIVE)
3208 gdk_draw_string (window,
3209 gtk_style_get_font_internal (style),
3210 style->white_gc, x + 1, y + 1, string);
3212 gdk_draw_string (window,
3213 gtk_style_get_font_internal (style),
3214 style->fg_gc[state_type], x, y, string);
3218 gdk_gc_set_clip_rectangle (style->white_gc, NULL);
3219 gdk_gc_set_clip_rectangle (style->fg_gc[state_type], NULL);
3224 option_menu_get_props (GtkWidget *widget,
3225 GtkRequisition *indicator_size,
3226 GtkBorder *indicator_spacing)
3228 GtkRequisition *tmp_size = NULL;
3229 GtkBorder *tmp_spacing = NULL;
3232 gtk_widget_style_get (widget,
3233 "indicator-size", &tmp_size,
3234 "indicator-spacing", &tmp_spacing,
3239 *indicator_size = *tmp_size;
3243 *indicator_size = default_option_indicator_size;
3247 *indicator_spacing = *tmp_spacing;
3248 g_free (tmp_spacing);
3251 *indicator_spacing = default_option_indicator_spacing;
3255 gtk_default_draw_box (GtkStyle *style,
3257 GtkStateType state_type,
3258 GtkShadowType shadow_type,
3261 const gchar *detail,
3267 gboolean is_spinbutton_box = FALSE;
3269 g_return_if_fail (GTK_IS_STYLE (style));
3270 g_return_if_fail (window != NULL);
3272 sanitize_size (window, &width, &height);
3274 if (widget && GTK_IS_SPIN_BUTTON (widget) && detail)
3276 if (strcmp (detail, "spinbutton_up") == 0)
3282 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3287 is_spinbutton_box = TRUE;
3289 else if (strcmp (detail, "spinbutton_down") == 0)
3294 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3299 is_spinbutton_box = TRUE;
3303 if (!style->bg_pixmap[state_type] ||
3304 GDK_IS_PIXMAP (window))
3306 GdkGC *gc = style->bg_gc[state_type];
3308 if (state_type == GTK_STATE_SELECTED && detail && strcmp (detail, "paned") == 0)
3310 if (widget && !GTK_WIDGET_HAS_FOCUS (widget))
3311 gc = style->base_gc[GTK_STATE_ACTIVE];
3315 gdk_gc_set_clip_rectangle (gc, area);
3317 gdk_draw_rectangle (window, gc, TRUE,
3318 x, y, width, height);
3320 gdk_gc_set_clip_rectangle (gc, NULL);
3323 gtk_style_apply_default_background (style, window,
3324 widget && !GTK_WIDGET_NO_WINDOW (widget),
3325 state_type, area, x, y, width, height);
3327 if (is_spinbutton_box)
3332 lower_gc = style->dark_gc[state_type];
3333 if (shadow_type == GTK_SHADOW_OUT)
3334 upper_gc = style->light_gc[state_type];
3336 upper_gc = style->dark_gc[state_type];
3340 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3341 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3344 gdk_draw_line (window, upper_gc, x, y, x + width - 1, y);
3345 gdk_draw_line (window, lower_gc, x, y + height - 1, x + width - 1, y + height - 1);
3349 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3350 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3355 gtk_paint_shadow (style, window, state_type, shadow_type, area, widget, detail,
3356 x, y, width, height);
3358 if (detail && strcmp (detail, "optionmenu") == 0)
3360 GtkRequisition indicator_size;
3361 GtkBorder indicator_spacing;
3364 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3366 sanitize_size (window, &width, &height);
3368 if (get_direction (widget) == GTK_TEXT_DIR_RTL)
3369 vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
3371 vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
3373 gtk_paint_vline (style, window, state_type, area, widget,
3375 y + style->ythickness + 1,
3376 y + height - style->ythickness - 3,
3382 get_darkened_gc (GdkWindow *window,
3386 GdkColor src = *color;
3387 GdkColor shaded = *color;
3390 gc = gdk_gc_new (window);
3392 while (darken_count)
3394 gtk_style_shade (&src, &shaded, 0.93);
3399 gdk_gc_set_rgb_fg_color (gc, &shaded);
3405 gtk_default_draw_flat_box (GtkStyle *style,
3407 GtkStateType state_type,
3408 GtkShadowType shadow_type,
3411 const gchar *detail,
3418 GdkGC *freeme = NULL;
3420 g_return_if_fail (GTK_IS_STYLE (style));
3421 g_return_if_fail (window != NULL);
3423 sanitize_size (window, &width, &height);
3427 if (state_type == GTK_STATE_SELECTED)
3429 if (!strcmp ("text", detail))
3430 gc1 = style->bg_gc[GTK_STATE_SELECTED];
3431 else if (!strncmp ("cell_even", detail, strlen ("cell_even")) ||
3432 !strncmp ("cell_odd", detail, strlen ("cell_odd")))
3434 /* This has to be really broken; alex made me do it. -jrb */
3435 if (GTK_WIDGET_HAS_FOCUS (widget))
3436 gc1 = style->base_gc[state_type];
3438 gc1 = style->base_gc[GTK_STATE_ACTIVE];
3442 gc1 = style->bg_gc[state_type];
3447 if (!strcmp ("viewportbin", detail))
3448 gc1 = style->bg_gc[GTK_STATE_NORMAL];
3449 else if (!strcmp ("entry_bg", detail))
3450 gc1 = style->base_gc[state_type];
3452 /* For trees: even rows are base color, odd rows are a shade of
3453 * the base color, the sort column is a shade of the original color
3457 else if (!strcmp ("cell_even", detail) ||
3458 !strcmp ("cell_odd", detail) ||
3459 !strcmp ("cell_even_ruled", detail))
3461 GdkColor *color = NULL;
3463 gtk_widget_style_get (widget,
3464 "even-row-color", &color,
3469 freeme = get_darkened_gc (window, color, 0);
3472 gdk_color_free (color);
3475 gc1 = style->base_gc[state_type];
3477 else if (!strcmp ("cell_odd_ruled", detail))
3481 gtk_widget_style_get (widget,
3482 "odd-row-color", &color,
3487 freeme = get_darkened_gc (window, color, 0);
3490 gdk_color_free (color);
3494 gtk_widget_style_get (widget,
3495 "even-row-color", &color,
3500 freeme = get_darkened_gc (window, color, 1);
3501 gdk_color_free (color);
3504 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3508 else if (!strcmp ("cell_even_sorted", detail) ||
3509 !strcmp ("cell_odd_sorted", detail) ||
3510 !strcmp ("cell_even_ruled_sorted", detail))
3512 GdkColor *color = NULL;
3514 if (!strcmp ("cell_odd_sorted", detail))
3515 gtk_widget_style_get (widget,
3516 "odd-row-color", &color,
3519 gtk_widget_style_get (widget,
3520 "even-row-color", &color,
3525 freeme = get_darkened_gc (window, color, 1);
3528 gdk_color_free (color);
3532 freeme = get_darkened_gc (window, &style->base[state_type], 1);
3536 else if (!strcmp ("cell_odd_ruled_sorted", detail))
3538 GdkColor *color = NULL;
3540 gtk_widget_style_get (widget,
3541 "odd-row-color", &color,
3546 freeme = get_darkened_gc (window, color, 1);
3549 gdk_color_free (color);
3553 gtk_widget_style_get (widget,
3554 "even-row-color", &color,
3559 freeme = get_darkened_gc (window, color, 2);
3560 gdk_color_free (color);
3563 freeme = get_darkened_gc (window, &style->base[state_type], 2);
3568 gc1 = style->bg_gc[state_type];
3572 gc1 = style->bg_gc[state_type];
3574 if (!style->bg_pixmap[state_type] || gc1 != style->bg_gc[state_type] ||
3575 GDK_IS_PIXMAP (window))
3578 gdk_gc_set_clip_rectangle (gc1, area);
3580 gdk_draw_rectangle (window, gc1, TRUE,
3581 x, y, width, height);
3583 if (detail && !strcmp ("tooltip", detail))
3584 gdk_draw_rectangle (window, style->black_gc, FALSE,
3585 x, y, width - 1, height - 1);
3588 gdk_gc_set_clip_rectangle (gc1, NULL);
3591 gtk_style_apply_default_background (style, window,
3592 widget && !GTK_WIDGET_NO_WINDOW (widget),
3593 state_type, area, x, y, width, height);
3597 g_object_unref (freeme);
3601 gtk_default_draw_check (GtkStyle *style,
3603 GtkStateType state_type,
3604 GtkShadowType shadow_type,
3607 const gchar *detail,
3613 cairo_t *cr = gdk_cairo_create (window);
3614 enum { BUTTON, MENU, CELL } type = BUTTON;
3621 if (strcmp (detail, "cellcheck") == 0)
3623 else if (strcmp (detail, "check") == 0)
3629 gdk_cairo_rectangle (cr, area);
3633 exterior_size = MIN (width, height);
3634 if (exterior_size % 2 == 0) /* Ensure odd */
3635 exterior_size -= -1;
3637 pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3638 interior_size = MAX (1, exterior_size - 2 * pad);
3640 if (interior_size < 7)
3643 pad = MAX (0, (exterior_size - interior_size) / 2);
3646 x -= (1 + exterior_size - width) / 2;
3647 y -= (1 + exterior_size - height) / 2;
3654 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3656 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3658 cairo_set_line_width (cr, 1.0);
3659 cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
3662 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3663 cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
3675 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3678 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3682 if (shadow_type == GTK_SHADOW_IN)
3684 cairo_translate (cr,
3687 cairo_scale (cr, interior_size / 7., interior_size / 7.);
3689 cairo_move_to (cr, 7.0, 0.0);
3690 cairo_line_to (cr, 7.5, 1.0);
3691 cairo_curve_to (cr, 5.3, 2.0,
3694 cairo_curve_to (cr, 3.0, 5.7,
3697 cairo_line_to (cr, 0.2, 3.5);
3698 cairo_curve_to (cr, 1.1, 3.5,
3701 cairo_curve_to (cr, 1.0, 3.9,
3704 cairo_curve_to (cr, 3.5, 3.1,
3710 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3712 int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3714 cairo_rectangle (cr,
3716 y + pad + (1 + interior_size - line_thickness) / 2,
3726 gtk_default_draw_option (GtkStyle *style,
3728 GtkStateType state_type,
3729 GtkShadowType shadow_type,
3732 const gchar *detail,
3738 cairo_t *cr = gdk_cairo_create (window);
3739 enum { BUTTON, MENU, CELL } type = BUTTON;
3744 if (strcmp (detail, "radio") == 0)
3746 else if (strcmp (detail, "option") == 0)
3752 gdk_cairo_rectangle (cr, area);
3756 exterior_size = MIN (width, height);
3757 if (exterior_size % 2 == 0) /* Ensure odd */
3758 exterior_size -= -1;
3760 x -= (1 + exterior_size - width) / 2;
3761 y -= (1 + exterior_size - height) / 2;
3767 gdk_cairo_set_source_color (cr, &style->base[state_type]);
3770 x + exterior_size / 2.,
3771 y + exterior_size / 2.,
3772 (exterior_size - 1) / 2.,
3775 cairo_fill_preserve (cr);
3778 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3780 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3782 cairo_set_line_width (cr, 1.);
3793 gdk_cairo_set_source_color (cr, &style->text[state_type]);
3798 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
3802 if (shadow_type == GTK_SHADOW_IN)
3804 int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
3805 int interior_size = MAX (1, exterior_size - 2 * pad);
3807 if (interior_size < 5)
3810 pad = MAX (0, (exterior_size - interior_size) / 2);
3814 x + pad + interior_size / 2.,
3815 y + pad + interior_size / 2.,
3820 else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
3822 int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
3823 int interior_size = MAX (1, exterior_size - 2 * pad);
3826 if (interior_size < 7)
3829 pad = MAX (0, (exterior_size - interior_size) / 2);
3832 line_thickness = MAX (1, (3 + interior_size * 2) / 7);
3834 cairo_rectangle (cr,
3836 y + pad + (interior_size - line_thickness) / 2.,
3846 gtk_default_draw_tab (GtkStyle *style,
3848 GtkStateType state_type,
3849 GtkShadowType shadow_type,
3852 const gchar *detail,
3858 #define ARROW_SPACE 4
3860 GtkRequisition indicator_size;
3861 GtkBorder indicator_spacing;
3864 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
3866 indicator_size.width += (indicator_size.width % 2) - 1;
3867 arrow_height = indicator_size.width / 2 + 1;
3869 x += (width - indicator_size.width) / 2;
3870 y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
3872 if (state_type == GTK_STATE_INSENSITIVE)
3874 draw_arrow (window, &style->white, area,
3875 GTK_ARROW_UP, x + 1, y + 1,
3876 indicator_size.width, arrow_height);
3878 draw_arrow (window, &style->white, area,
3879 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
3880 indicator_size.width, arrow_height);
3883 draw_arrow (window, &style->fg[state_type], area,
3885 indicator_size.width, arrow_height);
3888 draw_arrow (window, &style->fg[state_type], area,
3889 GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
3890 indicator_size.width, arrow_height);
3894 gtk_default_draw_shadow_gap (GtkStyle *style,
3896 GtkStateType state_type,
3897 GtkShadowType shadow_type,
3900 const gchar *detail,
3905 GtkPositionType gap_side,
3914 g_return_if_fail (GTK_IS_STYLE (style));
3915 g_return_if_fail (window != NULL);
3917 sanitize_size (window, &width, &height);
3919 switch (shadow_type)
3921 case GTK_SHADOW_NONE:
3924 gc1 = style->dark_gc[state_type];
3925 gc2 = style->black_gc;
3926 gc3 = style->bg_gc[state_type];
3927 gc4 = style->light_gc[state_type];
3929 case GTK_SHADOW_ETCHED_IN:
3930 gc1 = style->dark_gc[state_type];
3931 gc2 = style->light_gc[state_type];
3932 gc3 = style->dark_gc[state_type];
3933 gc4 = style->light_gc[state_type];
3935 case GTK_SHADOW_OUT:
3936 gc1 = style->light_gc[state_type];
3937 gc2 = style->bg_gc[state_type];
3938 gc3 = style->dark_gc[state_type];
3939 gc4 = style->black_gc;
3941 case GTK_SHADOW_ETCHED_OUT:
3942 gc1 = style->light_gc[state_type];
3943 gc2 = style->dark_gc[state_type];
3944 gc3 = style->light_gc[state_type];
3945 gc4 = style->dark_gc[state_type];
3950 gdk_gc_set_clip_rectangle (gc1, area);
3951 gdk_gc_set_clip_rectangle (gc2, area);
3952 gdk_gc_set_clip_rectangle (gc3, area);
3953 gdk_gc_set_clip_rectangle (gc4, area);
3956 switch (shadow_type)
3958 case GTK_SHADOW_NONE:
3960 case GTK_SHADOW_OUT:
3961 case GTK_SHADOW_ETCHED_IN:
3962 case GTK_SHADOW_ETCHED_OUT:
3966 gdk_draw_line (window, gc1,
3967 x, y, x, y + height - 1);
3968 gdk_draw_line (window, gc2,
3969 x + 1, y, x + 1, y + height - 2);
3971 gdk_draw_line (window, gc3,
3972 x + 1, y + height - 2, x + width - 2, y + height - 2);
3973 gdk_draw_line (window, gc3,
3974 x + width - 2, y, x + width - 2, y + height - 2);
3975 gdk_draw_line (window, gc4,
3976 x, y + height - 1, x + width - 1, y + height - 1);
3977 gdk_draw_line (window, gc4,
3978 x + width - 1, y, x + width - 1, y + height - 1);
3981 gdk_draw_line (window, gc1,
3982 x, y, x + gap_x - 1, y);
3983 gdk_draw_line (window, gc2,
3984 x + 1, y + 1, x + gap_x - 1, y + 1);
3985 gdk_draw_line (window, gc2,
3986 x + gap_x, y, x + gap_x, y);
3988 if ((width - (gap_x + gap_width)) > 0)
3990 gdk_draw_line (window, gc1,
3991 x + gap_x + gap_width, y, x + width - 2, y);
3992 gdk_draw_line (window, gc2,
3993 x + gap_x + gap_width, y + 1, x + width - 3, y + 1);
3994 gdk_draw_line (window, gc2,
3995 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
3998 case GTK_POS_BOTTOM:
3999 gdk_draw_line (window, gc1,
4000 x, y, x + width - 1, y);
4001 gdk_draw_line (window, gc1,
4002 x, y, x, y + height - 1);
4003 gdk_draw_line (window, gc2,
4004 x + 1, y + 1, x + width - 2, y + 1);
4005 gdk_draw_line (window, gc2,
4006 x + 1, y + 1, x + 1, y + height - 1);
4008 gdk_draw_line (window, gc3,
4009 x + width - 2, y + 1, x + width - 2, y + height - 1);
4010 gdk_draw_line (window, gc4,
4011 x + width - 1, y, x + width - 1, y + height - 1);
4014 gdk_draw_line (window, gc4,
4015 x, y + height - 1, x + gap_x - 1, y + height - 1);
4016 gdk_draw_line (window, gc3,
4017 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4018 gdk_draw_line (window, gc3,
4019 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4021 if ((width - (gap_x + gap_width)) > 0)
4023 gdk_draw_line (window, gc4,
4024 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4025 gdk_draw_line (window, gc3,
4026 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4027 gdk_draw_line (window, gc3,
4028 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4032 gdk_draw_line (window, gc1,
4033 x, y, x + width - 1, y);
4034 gdk_draw_line (window, gc2,
4035 x, y + 1, x + width - 2, y + 1);
4037 gdk_draw_line (window, gc3,
4038 x, y + height - 2, x + width - 2, y + height - 2);
4039 gdk_draw_line (window, gc3,
4040 x + width - 2, y + 1, x + width - 2, y + height - 2);
4041 gdk_draw_line (window, gc4,
4042 x, y + height - 1, x + width - 1, y + height - 1);
4043 gdk_draw_line (window, gc4,
4044 x + width - 1, y, x + width - 1, y + height - 1);
4047 gdk_draw_line (window, gc1,
4048 x, y, x, y + gap_x - 1);
4049 gdk_draw_line (window, gc2,
4050 x + 1, y + 1, x + 1, y + gap_x - 1);
4051 gdk_draw_line (window, gc2,
4052 x, y + gap_x, x, y + gap_x);
4054 if ((width - (gap_x + gap_width)) > 0)
4056 gdk_draw_line (window, gc1,
4057 x, y + gap_x + gap_width, x, y + height - 2);
4058 gdk_draw_line (window, gc2,
4059 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4060 gdk_draw_line (window, gc2,
4061 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4065 gdk_draw_line (window, gc1,
4066 x, y, x + width - 1, y);
4067 gdk_draw_line (window, gc1,
4068 x, y, x, y + height - 1);
4069 gdk_draw_line (window, gc2,
4070 x + 1, y + 1, x + width - 1, y + 1);
4071 gdk_draw_line (window, gc2,
4072 x + 1, y + 1, x + 1, y + height - 2);
4074 gdk_draw_line (window, gc3,
4075 x + 1, y + height - 2, x + width - 1, y + height - 2);
4076 gdk_draw_line (window, gc4,
4077 x, y + height - 1, x + width - 1, y + height - 1);
4080 gdk_draw_line (window, gc4,
4081 x + width - 1, y, x + width - 1, y + gap_x - 1);
4082 gdk_draw_line (window, gc3,
4083 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4084 gdk_draw_line (window, gc3,
4085 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4087 if ((width - (gap_x + gap_width)) > 0)
4089 gdk_draw_line (window, gc4,
4090 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4091 gdk_draw_line (window, gc3,
4092 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4093 gdk_draw_line (window, gc3,
4094 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4102 gdk_gc_set_clip_rectangle (gc1, NULL);
4103 gdk_gc_set_clip_rectangle (gc2, NULL);
4104 gdk_gc_set_clip_rectangle (gc3, NULL);
4105 gdk_gc_set_clip_rectangle (gc4, NULL);
4110 gtk_default_draw_box_gap (GtkStyle *style,
4112 GtkStateType state_type,
4113 GtkShadowType shadow_type,
4116 const gchar *detail,
4121 GtkPositionType gap_side,
4130 g_return_if_fail (GTK_IS_STYLE (style));
4131 g_return_if_fail (window != NULL);
4133 gtk_style_apply_default_background (style, window,
4134 widget && !GTK_WIDGET_NO_WINDOW (widget),
4135 state_type, area, x, y, width, height);
4137 sanitize_size (window, &width, &height);
4139 switch (shadow_type)
4141 case GTK_SHADOW_NONE:
4144 gc1 = style->dark_gc[state_type];
4145 gc2 = style->black_gc;
4146 gc3 = style->bg_gc[state_type];
4147 gc4 = style->light_gc[state_type];
4149 case GTK_SHADOW_ETCHED_IN:
4150 gc1 = style->dark_gc[state_type];
4151 gc2 = style->light_gc[state_type];
4152 gc3 = style->dark_gc[state_type];
4153 gc4 = style->light_gc[state_type];
4155 case GTK_SHADOW_OUT:
4156 gc1 = style->light_gc[state_type];
4157 gc2 = style->bg_gc[state_type];
4158 gc3 = style->dark_gc[state_type];
4159 gc4 = style->black_gc;
4161 case GTK_SHADOW_ETCHED_OUT:
4162 gc1 = style->light_gc[state_type];
4163 gc2 = style->dark_gc[state_type];
4164 gc3 = style->light_gc[state_type];
4165 gc4 = style->dark_gc[state_type];
4171 gdk_gc_set_clip_rectangle (gc1, area);
4172 gdk_gc_set_clip_rectangle (gc2, area);
4173 gdk_gc_set_clip_rectangle (gc3, area);
4174 gdk_gc_set_clip_rectangle (gc4, area);
4177 switch (shadow_type)
4179 case GTK_SHADOW_NONE:
4181 case GTK_SHADOW_OUT:
4182 case GTK_SHADOW_ETCHED_IN:
4183 case GTK_SHADOW_ETCHED_OUT:
4187 gdk_draw_line (window, gc1,
4188 x, y, x, y + height - 1);
4189 gdk_draw_line (window, gc2,
4190 x + 1, y, x + 1, y + height - 2);
4192 gdk_draw_line (window, gc3,
4193 x + 1, y + height - 2, x + width - 2, y + height - 2);
4194 gdk_draw_line (window, gc3,
4195 x + width - 2, y, x + width - 2, y + height - 2);
4196 gdk_draw_line (window, gc4,
4197 x, y + height - 1, x + width - 1, y + height - 1);
4198 gdk_draw_line (window, gc4,
4199 x + width - 1, y, x + width - 1, y + height - 1);
4202 gdk_draw_line (window, gc1,
4203 x, y, x + gap_x - 1, y);
4204 gdk_draw_line (window, gc2,
4205 x + 1, y + 1, x + gap_x - 1, y + 1);
4206 gdk_draw_line (window, gc2,
4207 x + gap_x, y, x + gap_x, y);
4209 if ((width - (gap_x + gap_width)) > 0)
4211 gdk_draw_line (window, gc1,
4212 x + gap_x + gap_width, y, x + width - 2, y);
4213 gdk_draw_line (window, gc2,
4214 x + gap_x + gap_width, y + 1, x + width - 2, y + 1);
4215 gdk_draw_line (window, gc2,
4216 x + gap_x + gap_width - 1, y, x + gap_x + gap_width - 1, y);
4219 case GTK_POS_BOTTOM:
4220 gdk_draw_line (window, gc1,
4221 x, y, x + width - 1, y);
4222 gdk_draw_line (window, gc1,
4223 x, y, x, y + height - 1);
4224 gdk_draw_line (window, gc2,
4225 x + 1, y + 1, x + width - 2, y + 1);
4226 gdk_draw_line (window, gc2,
4227 x + 1, y + 1, x + 1, y + height - 1);
4229 gdk_draw_line (window, gc3,
4230 x + width - 2, y + 1, x + width - 2, y + height - 1);
4231 gdk_draw_line (window, gc4,
4232 x + width - 1, y, x + width - 1, y + height - 1);
4235 gdk_draw_line (window, gc4,
4236 x, y + height - 1, x + gap_x - 1, y + height - 1);
4237 gdk_draw_line (window, gc3,
4238 x + 1, y + height - 2, x + gap_x - 1, y + height - 2);
4239 gdk_draw_line (window, gc3,
4240 x + gap_x, y + height - 1, x + gap_x, y + height - 1);
4242 if ((width - (gap_x + gap_width)) > 0)
4244 gdk_draw_line (window, gc4,
4245 x + gap_x + gap_width, y + height - 1, x + width - 2, y + height - 1);
4246 gdk_draw_line (window, gc3,
4247 x + gap_x + gap_width, y + height - 2, x + width - 2, y + height - 2);
4248 gdk_draw_line (window, gc3,
4249 x + gap_x + gap_width - 1, y + height - 1, x + gap_x + gap_width - 1, y + height - 1);
4253 gdk_draw_line (window, gc1,
4254 x, y, x + width - 1, y);
4255 gdk_draw_line (window, gc2,
4256 x, y + 1, x + width - 2, y + 1);
4258 gdk_draw_line (window, gc3,
4259 x, y + height - 2, x + width - 2, y + height - 2);
4260 gdk_draw_line (window, gc3,
4261 x + width - 2, y + 1, x + width - 2, y + height - 2);
4262 gdk_draw_line (window, gc4,
4263 x, y + height - 1, x + width - 1, y + height - 1);
4264 gdk_draw_line (window, gc4,
4265 x + width - 1, y, x + width - 1, y + height - 1);
4268 gdk_draw_line (window, gc1,
4269 x, y, x, y + gap_x - 1);
4270 gdk_draw_line (window, gc2,
4271 x + 1, y + 1, x + 1, y + gap_x - 1);
4272 gdk_draw_line (window, gc2,
4273 x, y + gap_x, x, y + gap_x);
4275 if ((width - (gap_x + gap_width)) > 0)
4277 gdk_draw_line (window, gc1,
4278 x, y + gap_x + gap_width, x, y + height - 2);
4279 gdk_draw_line (window, gc2,
4280 x + 1, y + gap_x + gap_width, x + 1, y + height - 2);
4281 gdk_draw_line (window, gc2,
4282 x, y + gap_x + gap_width - 1, x, y + gap_x + gap_width - 1);
4286 gdk_draw_line (window, gc1,
4287 x, y, x + width - 1, y);
4288 gdk_draw_line (window, gc1,
4289 x, y, x, y + height - 1);
4290 gdk_draw_line (window, gc2,
4291 x + 1, y + 1, x + width - 1, y + 1);
4292 gdk_draw_line (window, gc2,
4293 x + 1, y + 1, x + 1, y + height - 2);
4295 gdk_draw_line (window, gc3,
4296 x + 1, y + height - 2, x + width - 1, y + height - 2);
4297 gdk_draw_line (window, gc4,
4298 x, y + height - 1, x + width - 1, y + height - 1);
4301 gdk_draw_line (window, gc4,
4302 x + width - 1, y, x + width - 1, y + gap_x - 1);
4303 gdk_draw_line (window, gc3,
4304 x + width - 2, y + 1, x + width - 2, y + gap_x - 1);
4305 gdk_draw_line (window, gc3,
4306 x + width - 1, y + gap_x, x + width - 1, y + gap_x);
4308 if ((width - (gap_x + gap_width)) > 0)
4310 gdk_draw_line (window, gc4,
4311 x + width - 1, y + gap_x + gap_width, x + width - 1, y + height - 2);
4312 gdk_draw_line (window, gc3,
4313 x + width - 2, y + gap_x + gap_width, x + width - 2, y + height - 2);
4314 gdk_draw_line (window, gc3,
4315 x + width - 1, y + gap_x + gap_width - 1, x + width - 1, y + gap_x + gap_width - 1);
4323 gdk_gc_set_clip_rectangle (gc1, NULL);
4324 gdk_gc_set_clip_rectangle (gc2, NULL);
4325 gdk_gc_set_clip_rectangle (gc3, NULL);
4326 gdk_gc_set_clip_rectangle (gc4, NULL);
4331 gtk_default_draw_extension (GtkStyle *style,
4333 GtkStateType state_type,
4334 GtkShadowType shadow_type,
4337 const gchar *detail,
4342 GtkPositionType gap_side)
4349 g_return_if_fail (GTK_IS_STYLE (style));
4350 g_return_if_fail (window != NULL);
4352 gtk_style_apply_default_background (style, window,
4353 widget && !GTK_WIDGET_NO_WINDOW (widget),
4354 GTK_STATE_NORMAL, area, x, y, width, height);
4356 sanitize_size (window, &width, &height);
4358 switch (shadow_type)
4360 case GTK_SHADOW_NONE:
4363 gc1 = style->dark_gc[state_type];
4364 gc2 = style->black_gc;
4365 gc3 = style->bg_gc[state_type];
4366 gc4 = style->light_gc[state_type];
4368 case GTK_SHADOW_ETCHED_IN:
4369 gc1 = style->dark_gc[state_type];
4370 gc2 = style->light_gc[state_type];
4371 gc3 = style->dark_gc[state_type];
4372 gc4 = style->light_gc[state_type];
4374 case GTK_SHADOW_OUT:
4375 gc1 = style->light_gc[state_type];
4376 gc2 = style->bg_gc[state_type];
4377 gc3 = style->dark_gc[state_type];
4378 gc4 = style->black_gc;
4380 case GTK_SHADOW_ETCHED_OUT:
4381 gc1 = style->light_gc[state_type];
4382 gc2 = style->dark_gc[state_type];
4383 gc3 = style->light_gc[state_type];
4384 gc4 = style->dark_gc[state_type];
4390 gdk_gc_set_clip_rectangle (gc1, area);
4391 gdk_gc_set_clip_rectangle (gc2, area);
4392 gdk_gc_set_clip_rectangle (gc3, area);
4393 gdk_gc_set_clip_rectangle (gc4, area);
4396 switch (shadow_type)
4398 case GTK_SHADOW_NONE:
4400 case GTK_SHADOW_OUT:
4401 case GTK_SHADOW_ETCHED_IN:
4402 case GTK_SHADOW_ETCHED_OUT:
4406 gtk_style_apply_default_background (style, window,
4407 widget && !GTK_WIDGET_NO_WINDOW (widget),
4409 x + style->xthickness,
4411 width - (2 * style->xthickness),
4412 height - (style->ythickness));
4413 gdk_draw_line (window, gc1,
4414 x, y, x, y + height - 2);
4415 gdk_draw_line (window, gc2,
4416 x + 1, y, x + 1, y + height - 2);
4418 gdk_draw_line (window, gc3,
4419 x + 2, y + height - 2, x + width - 2, y + height - 2);
4420 gdk_draw_line (window, gc3,
4421 x + width - 2, y, x + width - 2, y + height - 2);
4422 gdk_draw_line (window, gc4,
4423 x + 1, y + height - 1, x + width - 2, y + height - 1);
4424 gdk_draw_line (window, gc4,
4425 x + width - 1, y, x + width - 1, y + height - 2);
4427 case GTK_POS_BOTTOM:
4428 gtk_style_apply_default_background (style, window,
4429 widget && !GTK_WIDGET_NO_WINDOW (widget),
4431 x + style->xthickness,
4432 y + style->ythickness,
4433 width - (2 * style->xthickness),
4434 height - (style->ythickness));
4435 gdk_draw_line (window, gc1,
4436 x + 1, y, x + width - 2, y);
4437 gdk_draw_line (window, gc1,
4438 x, y + 1, x, y + height - 1);
4439 gdk_draw_line (window, gc2,
4440 x + 1, y + 1, x + width - 2, y + 1);
4441 gdk_draw_line (window, gc2,
4442 x + 1, y + 1, x + 1, y + height - 1);
4444 gdk_draw_line (window, gc3,
4445 x + width - 2, y + 2, x + width - 2, y + height - 1);
4446 gdk_draw_line (window, gc4,
4447 x + width - 1, y + 1, x + width - 1, y + height - 1);
4450 gtk_style_apply_default_background (style, window,
4451 widget && !GTK_WIDGET_NO_WINDOW (widget),
4454 y + style->ythickness,
4455 width - (style->xthickness),
4456 height - (2 * style->ythickness));
4457 gdk_draw_line (window, gc1,
4458 x, y, x + width - 2, y);
4459 gdk_draw_line (window, gc2,
4460 x + 1, y + 1, x + width - 2, y + 1);
4462 gdk_draw_line (window, gc3,
4463 x, y + height - 2, x + width - 2, y + height - 2);
4464 gdk_draw_line (window, gc3,
4465 x + width - 2, y + 2, x + width - 2, y + height - 2);
4466 gdk_draw_line (window, gc4,
4467 x, y + height - 1, x + width - 2, y + height - 1);
4468 gdk_draw_line (window, gc4,
4469 x + width - 1, y + 1, x + width - 1, y + height - 2);
4472 gtk_style_apply_default_background (style, window,
4473 widget && !GTK_WIDGET_NO_WINDOW (widget),
4475 x + style->xthickness,
4476 y + style->ythickness,
4477 width - (style->xthickness),
4478 height - (2 * style->ythickness));
4479 gdk_draw_line (window, gc1,
4480 x + 1, y, x + width - 1, y);
4481 gdk_draw_line (window, gc1,
4482 x, y + 1, x, y + height - 2);
4483 gdk_draw_line (window, gc2,
4484 x + 1, y + 1, x + width - 1, y + 1);
4485 gdk_draw_line (window, gc2,
4486 x + 1, y + 1, x + 1, y + height - 2);
4488 gdk_draw_line (window, gc3,
4489 x + 2, y + height - 2, x + width - 1, y + height - 2);
4490 gdk_draw_line (window, gc4,
4491 x + 1, y + height - 1, x + width - 1, y + height - 1);
4498 gdk_gc_set_clip_rectangle (gc1, NULL);
4499 gdk_gc_set_clip_rectangle (gc2, NULL);
4500 gdk_gc_set_clip_rectangle (gc3, NULL);
4501 gdk_gc_set_clip_rectangle (gc4, NULL);
4506 gtk_default_draw_focus (GtkStyle *style,
4508 GtkStateType state_type,
4511 const gchar *detail,
4518 gboolean free_dash_list = FALSE;
4519 gint line_width = 1;
4520 gint8 *dash_list = "\1\1";
4524 gtk_widget_style_get (widget,
4525 "focus-line-width", &line_width,
4526 "focus-line-pattern", (gchar *)&dash_list,
4529 free_dash_list = TRUE;
4532 if (detail && !strcmp (detail, "add-mode"))
4538 free_dash_list = FALSE;
4541 sanitize_size (window, &width, &height);
4543 cr = gdk_cairo_create (window);
4545 if (detail && !strcmp (detail, "colorwheel_light"))
4546 cairo_set_source_rgb (cr, 0., 0., 0.);
4547 else if (detail && !strcmp (detail, "colorwheel_dark"))
4548 cairo_set_source_rgb (cr, 1., 1., 1.);
4550 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4552 cairo_set_line_width (cr, line_width);
4556 gint n_dashes = strlen (dash_list);
4557 gdouble *dashes = g_new (gdouble, n_dashes);
4558 gdouble total_length = 0;
4559 gdouble dash_offset;
4562 for (i = 0; i < n_dashes; i++)
4564 dashes[i] = dash_list[i];
4565 total_length += dash_list[i];
4568 /* The dash offset here aligns the pattern to integer pixels
4569 * by starting the dash at the right side of the left border
4570 * Negative dash offsets in cairo don't work
4571 * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
4573 dash_offset = - line_width / 2.;
4574 while (dash_offset < 0)
4575 dash_offset += total_length;
4577 cairo_set_dash (cr, dashes, n_dashes, dash_offset);
4583 gdk_cairo_rectangle (cr, area);
4587 cairo_rectangle (cr,
4588 x + line_width / 2.,
4589 y + line_width / 2.,
4591 height - line_width);
4600 gtk_default_draw_slider (GtkStyle *style,
4602 GtkStateType state_type,
4603 GtkShadowType shadow_type,
4606 const gchar *detail,
4611 GtkOrientation orientation)
4613 g_return_if_fail (GTK_IS_STYLE (style));
4614 g_return_if_fail (window != NULL);
4616 sanitize_size (window, &width, &height);
4618 gtk_paint_box (style, window, state_type, shadow_type,
4619 area, widget, detail, x, y, width, height);
4622 (strcmp ("hscale", detail) == 0 ||
4623 strcmp ("vscale", detail) == 0))
4625 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4626 gtk_paint_vline (style, window, state_type, area, widget, detail,
4627 y + style->ythickness,
4628 y + height - style->ythickness - 1, x + width / 2);
4630 gtk_paint_hline (style, window, state_type, area, widget, detail,
4631 x + style->xthickness,
4632 x + width - style->xthickness - 1, y + height / 2);
4637 draw_dot (GdkWindow *window,
4645 size = CLAMP (size, 2, 3);
4649 gdk_draw_point (window, light_gc, x, y);
4650 gdk_draw_point (window, light_gc, x+1, y+1);
4654 gdk_draw_point (window, light_gc, x, y);
4655 gdk_draw_point (window, light_gc, x+1, y);
4656 gdk_draw_point (window, light_gc, x, y+1);
4657 gdk_draw_point (window, dark_gc, x+1, y+2);
4658 gdk_draw_point (window, dark_gc, x+2, y+1);
4659 gdk_draw_point (window, dark_gc, x+2, y+2);
4664 gtk_default_draw_handle (GtkStyle *style,
4666 GtkStateType state_type,
4667 GtkShadowType shadow_type,
4670 const gchar *detail,
4675 GtkOrientation orientation)
4678 gint xthick, ythick;
4679 GdkGC *light_gc, *dark_gc;
4680 GdkGC *free_me = NULL;
4685 g_return_if_fail (GTK_IS_STYLE (style));
4686 g_return_if_fail (window != NULL);
4688 sanitize_size (window, &width, &height);
4690 gtk_paint_box (style, window, state_type, shadow_type, area, widget,
4691 detail, x, y, width, height);
4694 if (detail && !strcmp (detail, "paned"))
4696 /* we want to ignore the shadow border in paned widgets */
4700 if (state_type == GTK_STATE_SELECTED && widget && !GTK_WIDGET_HAS_FOCUS (widget))
4702 GdkColor unfocused_light;
4704 gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
4707 light_gc = free_me = gdk_gc_new (window);
4708 gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
4711 light_gc = style->light_gc[state_type];
4713 dark_gc = style->black_gc;
4717 xthick = style->xthickness;
4718 ythick = style->ythickness;
4720 light_gc = style->light_gc[state_type];
4721 dark_gc = style->dark_gc[state_type];
4724 rect.x = x + xthick;
4725 rect.y = y + ythick;
4726 rect.width = width - (xthick * 2);
4727 rect.height = height - (ythick * 2);
4730 intersect = gdk_rectangle_intersect (area, &rect, &dest);
4740 gdk_gc_set_clip_rectangle (light_gc, &dest);
4741 gdk_gc_set_clip_rectangle (dark_gc, &dest);
4743 if (detail && !strcmp (detail, "paned"))
4745 if (orientation == GTK_ORIENTATION_HORIZONTAL)
4746 for (xx = x + width/2 - 15; xx <= x + width/2 + 15; xx += 5)
4747 draw_dot (window, light_gc, dark_gc, xx, y + height/2 - 1, 3);
4749 for (yy = y + height/2 - 15; yy <= y + height/2 + 15; yy += 5)
4750 draw_dot (window, light_gc, dark_gc, x + width/2 - 1, yy, 3);
4754 for (yy = y + ythick; yy < (y + height - ythick); yy += 3)
4755 for (xx = x + xthick; xx < (x + width - xthick); xx += 6)
4757 draw_dot (window, light_gc, dark_gc, xx, yy, 2);
4758 draw_dot (window, light_gc, dark_gc, xx + 3, yy + 1, 2);
4762 gdk_gc_set_clip_rectangle (light_gc, NULL);
4763 gdk_gc_set_clip_rectangle (dark_gc, NULL);
4767 g_object_unref (free_me);
4771 gtk_default_draw_expander (GtkStyle *style,
4773 GtkStateType state_type,
4776 const gchar *detail,
4779 GtkExpanderStyle expander_style)
4781 #define DEFAULT_EXPANDER_SIZE 12
4785 double vertical_overshoot;
4788 double interp; /* interpolation factor for center position */
4789 double x_double_horz, y_double_horz;
4790 double x_double_vert, y_double_vert;
4791 double x_double, y_double;
4794 cairo_t *cr = gdk_cairo_create (window);
4798 gdk_cairo_rectangle (cr, area);
4803 gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
4806 gtk_widget_style_get (widget,
4807 "expander-size", &expander_size,
4811 expander_size = DEFAULT_EXPANDER_SIZE;
4813 line_width = MAX (1, expander_size/9);
4815 switch (expander_style)
4817 case GTK_EXPANDER_COLLAPSED:
4818 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
4821 case GTK_EXPANDER_SEMI_COLLAPSED:
4822 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
4825 case GTK_EXPANDER_SEMI_EXPANDED:
4826 degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
4829 case GTK_EXPANDER_EXPANDED:
4834 g_assert_not_reached ();
4837 /* Compute distance that the stroke extends beyonds the end
4838 * of the triangle we draw.
4840 vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
4842 /* For odd line widths, we end the vertical line of the triangle
4843 * at a half pixel, so we round differently.
4845 if (line_width % 2 == 1)
4846 vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
4848 vertical_overshoot = ceil (vertical_overshoot);
4850 /* Adjust the size of the triangle we draw so that the entire stroke fits
4852 diameter = MAX (3, expander_size - 2 * vertical_overshoot);
4854 /* If the line width is odd, we want the diameter to be even,
4855 * and vice versa, so force the sum to be odd. This relationship
4856 * makes the point of the triangle look right.
4858 diameter -= (1 - (diameter + line_width) % 2);
4860 radius = diameter / 2.;
4862 /* Adjust the center so that the stroke is properly aligned with
4863 * the pixel grid. The center adjustment is different for the
4864 * horizontal and vertical orientations. For intermediate positions
4865 * we interpolate between the two.
4867 x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4868 y_double_vert = y - 0.5;
4870 x_double_horz = x - 0.5;
4871 y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
4873 x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
4874 y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
4876 cairo_translate (cr, x_double, y_double);
4877 cairo_rotate (cr, degrees * G_PI / 180);
4879 cairo_move_to (cr, - radius / 2., - radius);
4880 cairo_line_to (cr, radius / 2., 0);
4881 cairo_line_to (cr, - radius / 2., radius);
4882 cairo_close_path (cr);
4884 cairo_set_line_width (cr, line_width);
4886 if (state_type == GTK_STATE_PRELIGHT)
4887 gdk_cairo_set_source_color (cr,
4888 &style->fg[GTK_STATE_PRELIGHT]);
4889 else if (state_type == GTK_STATE_ACTIVE)
4890 gdk_cairo_set_source_color (cr,
4891 &style->light[GTK_STATE_ACTIVE]);
4893 gdk_cairo_set_source_color (cr,
4894 &style->base[GTK_STATE_NORMAL]);
4896 cairo_fill_preserve (cr);
4898 gdk_cairo_set_source_color (cr, &style->fg[state_type]);
4904 typedef struct _ByteRange ByteRange;
4913 range_new (guint start,
4916 ByteRange *br = g_new (ByteRange, 1);
4925 get_insensitive_layout (GdkDrawable *drawable,
4926 PangoLayout *layout)
4928 GSList *embossed_ranges = NULL;
4929 GSList *stippled_ranges = NULL;
4930 PangoLayoutIter *iter;
4931 GSList *tmp_list = NULL;
4932 PangoLayout *new_layout;
4933 PangoAttrList *attrs;
4934 GdkBitmap *stipple = NULL;
4936 iter = pango_layout_get_iter (layout);
4940 PangoLayoutRun *run;
4941 PangoAttribute *attr;
4942 gboolean need_stipple = FALSE;
4945 run = pango_layout_iter_get_run (iter);
4949 tmp_list = run->item->analysis.extra_attrs;
4951 while (tmp_list != NULL)
4953 attr = tmp_list->data;
4954 switch (attr->klass->type)
4956 case PANGO_ATTR_FOREGROUND:
4957 case PANGO_ATTR_BACKGROUND:
4958 need_stipple = TRUE;
4968 tmp_list = g_slist_next (tmp_list);
4971 br = range_new (run->item->offset, run->item->offset + run->item->length);
4974 stippled_ranges = g_slist_prepend (stippled_ranges, br);
4976 embossed_ranges = g_slist_prepend (embossed_ranges, br);
4979 while (pango_layout_iter_next_run (iter));
4981 pango_layout_iter_free (iter);
4983 new_layout = pango_layout_copy (layout);
4985 attrs = pango_layout_get_attributes (new_layout);
4989 /* Create attr list if there wasn't one */
4990 attrs = pango_attr_list_new ();
4991 pango_layout_set_attributes (new_layout, attrs);
4992 pango_attr_list_unref (attrs);
4995 tmp_list = embossed_ranges;
4996 while (tmp_list != NULL)
4998 PangoAttribute *attr;
4999 ByteRange *br = tmp_list->data;
5001 attr = gdk_pango_attr_embossed_new (TRUE);
5003 attr->start_index = br->start;
5004 attr->end_index = br->end;
5006 pango_attr_list_change (attrs, attr);
5010 tmp_list = g_slist_next (tmp_list);
5013 g_slist_free (embossed_ranges);
5015 tmp_list = stippled_ranges;
5016 while (tmp_list != NULL)
5018 PangoAttribute *attr;
5019 ByteRange *br = tmp_list->data;
5021 if (stipple == NULL)
5023 #define gray50_width 2
5024 #define gray50_height 2
5025 static const char gray50_bits[] = {
5029 stipple = gdk_bitmap_create_from_data (drawable,
5030 gray50_bits, gray50_width,
5034 attr = gdk_pango_attr_stipple_new (stipple);
5036 attr->start_index = br->start;
5037 attr->end_index = br->end;
5039 pango_attr_list_change (attrs, attr);
5043 tmp_list = g_slist_next (tmp_list);
5046 g_slist_free (stippled_ranges);
5049 g_object_unref (stipple);
5055 gtk_default_draw_layout (GtkStyle *style,
5057 GtkStateType state_type,
5061 const gchar *detail,
5064 PangoLayout *layout)
5068 g_return_if_fail (GTK_IS_STYLE (style));
5069 g_return_if_fail (window != NULL);
5071 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
5074 gdk_gc_set_clip_rectangle (gc, area);
5076 if (state_type == GTK_STATE_INSENSITIVE)
5080 ins = get_insensitive_layout (window, layout);
5082 gdk_draw_layout (window, gc, x, y, ins);
5084 g_object_unref (ins);
5088 gdk_draw_layout (window, gc, x, y, layout);
5092 gdk_gc_set_clip_rectangle (gc, NULL);
5096 gtk_default_draw_resize_grip (GtkStyle *style,
5098 GtkStateType state_type,
5101 const gchar *detail,
5111 g_return_if_fail (GTK_IS_STYLE (style));
5112 g_return_if_fail (window != NULL);
5116 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
5117 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
5118 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area);
5124 case GDK_WINDOW_EDGE_NORTH_WEST:
5125 /* make it square */
5128 else if (height < width)
5132 case GDK_WINDOW_EDGE_NORTH:
5136 case GDK_WINDOW_EDGE_NORTH_EAST:
5137 /* make it square, aligning to top right */
5140 else if (height < width)
5142 x += (width - height);
5147 case GDK_WINDOW_EDGE_WEST:
5151 case GDK_WINDOW_EDGE_EAST:
5152 /* aligning to right */
5155 x += (width - height);
5159 case GDK_WINDOW_EDGE_SOUTH_WEST:
5160 /* make it square, aligning to bottom left */
5163 y += (height - width);
5166 else if (height < width)
5170 case GDK_WINDOW_EDGE_SOUTH:
5171 /* align to bottom */
5174 y += (height - width);
5178 case GDK_WINDOW_EDGE_SOUTH_EAST:
5179 /* make it square, aligning to bottom right */
5182 y += (height - width);
5185 else if (height < width)
5187 x += (width - height);
5193 g_assert_not_reached ();
5195 /* Clear background */
5197 for (i = 0; i < 4; i++)
5201 points[j].x = (i == 0 || i == 3) ? x : x + width;
5202 points[j].y = (i < 2) ? y : y + height;
5207 gdk_draw_polygon (window, style->bg_gc[state_type], TRUE,
5208 points, skip < 0 ? 4 : 3);
5212 case GDK_WINDOW_EDGE_WEST:
5213 case GDK_WINDOW_EDGE_EAST:
5219 while (xi < x + width)
5221 gdk_draw_line (window,
5222 style->light_gc[state_type],
5227 gdk_draw_line (window,
5228 style->dark_gc[state_type],
5236 case GDK_WINDOW_EDGE_NORTH:
5237 case GDK_WINDOW_EDGE_SOUTH:
5243 while (yi < y + height)
5245 gdk_draw_line (window,
5246 style->light_gc[state_type],
5251 gdk_draw_line (window,
5252 style->dark_gc[state_type],
5260 case GDK_WINDOW_EDGE_NORTH_WEST:
5269 gdk_draw_line (window,
5270 style->dark_gc[state_type],
5277 gdk_draw_line (window,
5278 style->dark_gc[state_type],
5285 gdk_draw_line (window,
5286 style->light_gc[state_type],
5296 case GDK_WINDOW_EDGE_NORTH_EAST:
5303 while (xi < (x + width - 3))
5305 gdk_draw_line (window,
5306 style->light_gc[state_type],
5313 gdk_draw_line (window,
5314 style->dark_gc[state_type],
5321 gdk_draw_line (window,
5322 style->dark_gc[state_type],
5331 case GDK_WINDOW_EDGE_SOUTH_WEST:
5340 gdk_draw_line (window,
5341 style->dark_gc[state_type],
5348 gdk_draw_line (window,
5349 style->dark_gc[state_type],
5356 gdk_draw_line (window,
5357 style->light_gc[state_type],
5367 case GDK_WINDOW_EDGE_SOUTH_EAST:
5374 while (xi < (x + width - 3))
5376 gdk_draw_line (window,
5377 style->light_gc[state_type],
5384 gdk_draw_line (window,
5385 style->dark_gc[state_type],
5392 gdk_draw_line (window,
5393 style->dark_gc[state_type],
5403 g_assert_not_reached ();
5409 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
5410 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
5411 gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL);
5416 gtk_style_shade (GdkColor *a,
5424 red = (gdouble) a->red / 65535.0;
5425 green = (gdouble) a->green / 65535.0;
5426 blue = (gdouble) a->blue / 65535.0;
5428 rgb_to_hls (&red, &green, &blue);
5433 else if (green < 0.0)
5439 else if (blue < 0.0)
5442 hls_to_rgb (&red, &green, &blue);
5444 b->red = red * 65535.0;
5445 b->green = green * 65535.0;
5446 b->blue = blue * 65535.0;
5450 rgb_to_hls (gdouble *r,
5491 l = (max + min) / 2;
5498 s = (max - min) / (max + min);
5500 s = (max - min) / (2 - max - min);
5504 h = (green - blue) / delta;
5505 else if (green == max)
5506 h = 2 + (blue - red) / delta;
5507 else if (blue == max)
5508 h = 4 + (red - green) / delta;
5521 hls_to_rgb (gdouble *h,
5534 if (lightness <= 0.5)
5535 m2 = lightness * (1 + saturation);
5537 m2 = lightness + saturation - lightness * saturation;
5538 m1 = 2 * lightness - m2;
5540 if (saturation == 0)
5555 r = m1 + (m2 - m1) * hue / 60;
5559 r = m1 + (m2 - m1) * (240 - hue) / 60;
5570 g = m1 + (m2 - m1) * hue / 60;
5574 g = m1 + (m2 - m1) * (240 - hue) / 60;
5585 b = m1 + (m2 - m1) * hue / 60;
5589 b = m1 + (m2 - m1) * (240 - hue) / 60;
5602 * @style: a #GtkStyle
5603 * @window: a #GdkWindow
5604 * @state_type: a state
5605 * @area: rectangle to which the output is clipped, or %NULL if the
5606 * output should not be clipped
5607 * @widget: the widget (may be %NULL)
5608 * @detail: a style detail (may be %NULL)
5609 * @x1: the starting x coordinate
5610 * @x2: the ending x coordinate
5611 * @y: the y coordinate
5613 * Draws a horizontal line from (@x1, @y) to (@x2, @y) in @window
5614 * using the given style and state.
5617 gtk_paint_hline (GtkStyle *style,
5619 GtkStateType state_type,
5622 const gchar *detail,
5627 g_return_if_fail (GTK_IS_STYLE (style));
5628 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
5629 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5631 GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
5636 * @style: a #GtkStyle
5637 * @window: a #GdkWindow
5638 * @state_type: a state
5639 * @area: rectangle to which the output is clipped, or %NULL if the
5640 * output should not be clipped
5641 * @widget: the widget (may be %NULL)
5642 * @detail: a style detail (may be %NULL)
5643 * @y1_: the starting y coordinate
5644 * @y2_: the ending y coordinate
5645 * @x: the x coordinate
5647 * Draws a vertical line from (@x, @y1_) to (@x, @y2_) in @window
5648 * using the given style and state.
5651 gtk_paint_vline (GtkStyle *style,
5653 GtkStateType state_type,
5656 const gchar *detail,
5661 g_return_if_fail (GTK_IS_STYLE (style));
5662 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
5663 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5665 GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1_, y2_, x);
5670 * @style: a #GtkStyle
5671 * @window: a #GdkWindow
5672 * @state_type: a state
5673 * @shadow_type: type of shadow to draw
5674 * @area: clip rectangle or %NULL if the
5675 * output should not be clipped
5676 * @widget: the widget (may be %NULL)
5677 * @detail: a style detail (may be %NULL)
5678 * @x: x origin of the rectangle
5679 * @y: y origin of the rectangle
5680 * @width: width of the rectangle
5681 * @height: width of the rectangle
5683 * Draws a shadow around the given rectangle in @window
5684 * using the given style and state and shadow type.
5687 gtk_paint_shadow (GtkStyle *style,
5689 GtkStateType state_type,
5690 GtkShadowType shadow_type,
5693 const gchar *detail,
5699 g_return_if_fail (GTK_IS_STYLE (style));
5700 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
5701 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5703 GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5707 * gtk_paint_polygon:
5708 * @style: a #GtkStyle
5709 * @window: a #GdkWindow
5710 * @state_type: a state
5711 * @shadow_type: type of shadow to draw
5712 * @area: clip rectangle, or %NULL if the
5713 * output should not be clipped
5714 * @widget: the widget (may be %NULL)
5715 * @detail: a style detail (may be %NULL)
5716 * @points: an array of #GdkPoint<!-- -->s
5717 * @npoints: length of @points
5718 * @fill: %TRUE if the polygon should be filled
5720 * Draws a polygon on @window with the given parameters.
5723 gtk_paint_polygon (GtkStyle *style,
5725 GtkStateType state_type,
5726 GtkShadowType shadow_type,
5729 const gchar *detail,
5734 g_return_if_fail (GTK_IS_STYLE (style));
5735 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
5736 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5738 GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
5743 * @style: a #GtkStyle
5744 * @window: a #GdkWindow
5745 * @state_type: a state
5746 * @shadow_type: the type of shadow to draw
5747 * @area: clip rectangle, or %NULL if the
5748 * output should not be clipped
5749 * @widget: the widget (may be %NULL)
5750 * @detail: a style detail (may be %NULL)
5751 * @arrow_type: the type of arrow to draw
5752 * @fill: %TRUE if the arrow tip should be filled
5753 * @x: x origin of the rectangle to draw the arrow in
5754 * @y: y origin of the rectangle to draw the arrow in
5755 * @width: width of the rectangle to draw the arrow in
5756 * @height: height of the rectangle to draw the arrow in
5758 * Draws an arrow in the given rectangle on @window using the given
5759 * parameters. @arrow_type determines the direction of the arrow.
5762 gtk_paint_arrow (GtkStyle *style,
5764 GtkStateType state_type,
5765 GtkShadowType shadow_type,
5768 const gchar *detail,
5769 GtkArrowType arrow_type,
5776 g_return_if_fail (GTK_IS_STYLE (style));
5777 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
5778 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5780 GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
5784 * gtk_paint_diamond:
5785 * @style: a #GtkStyle
5786 * @window: a #GdkWindow
5787 * @state_type: a state
5788 * @shadow_type: the type of shadow to draw
5789 * @area: clip rectangle, or %NULL if the
5790 * output should not be clipped
5791 * @widget: the widget (may be %NULL)
5792 * @detail: a style detail (may be %NULL)
5793 * @x: x origin of the rectangle to draw the diamond in
5794 * @y: y origin of the rectangle to draw the diamond in
5795 * @width: width of the rectangle to draw the diamond in
5796 * @height: height of the rectangle to draw the diamond in
5798 * Draws a diamond in the given rectangle on @window using the given
5802 gtk_paint_diamond (GtkStyle *style,
5804 GtkStateType state_type,
5805 GtkShadowType shadow_type,
5808 const gchar *detail,
5814 g_return_if_fail (GTK_IS_STYLE (style));
5815 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
5816 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5818 GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5823 * @style: a #GtkStyle
5824 * @window: a #GdkWindow
5825 * @state_type: a state
5826 * @area: clip rectangle, or %NULL if the
5827 * output should not be clipped
5828 * @widget: the widget (may be %NULL)
5829 * @detail: a style detail (may be %NULL)
5832 * @string: the string to draw
5834 * Draws a text string on @window with the given parameters.
5836 * Deprecated: Use gtk_paint_layout() instead.
5839 gtk_paint_string (GtkStyle *style,
5841 GtkStateType state_type,
5844 const gchar *detail,
5847 const gchar *string)
5849 g_return_if_fail (GTK_IS_STYLE (style));
5850 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
5851 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5853 GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
5858 * @style: a #GtkStyle
5859 * @window: a #GdkWindow
5860 * @state_type: a state
5861 * @shadow_type: the type of shadow to draw
5862 * @area: clip rectangle, or %NULL if the
5863 * output should not be clipped
5864 * @widget: the widget (may be %NULL)
5865 * @detail: a style detail (may be %NULL)
5866 * @x: x origin of the box
5867 * @y: y origin of the box
5868 * @width: the width of the box
5869 * @height: the height of the box
5871 * Draws a box on @window with the given parameters.
5874 gtk_paint_box (GtkStyle *style,
5876 GtkStateType state_type,
5877 GtkShadowType shadow_type,
5880 const gchar *detail,
5886 g_return_if_fail (GTK_IS_STYLE (style));
5887 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
5888 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5890 GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5894 * gtk_paint_flat_box:
5895 * @style: a #GtkStyle
5896 * @window: a #GdkWindow
5897 * @state_type: a state
5898 * @shadow_type: the type of shadow to draw
5899 * @area: clip rectangle, or %NULL if the
5900 * output should not be clipped
5901 * @widget: the widget (may be %NULL)
5902 * @detail: a style detail (may be %NULL)
5903 * @x: x origin of the box
5904 * @y: y origin of the box
5905 * @width: the width of the box
5906 * @height: the height of the box
5908 * Draws a flat box on @window with the given parameters.
5911 gtk_paint_flat_box (GtkStyle *style,
5913 GtkStateType state_type,
5914 GtkShadowType shadow_type,
5917 const gchar *detail,
5923 g_return_if_fail (GTK_IS_STYLE (style));
5924 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
5925 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5927 GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5932 * @style: a #GtkStyle
5933 * @window: a #GdkWindow
5934 * @state_type: a state
5935 * @shadow_type: the type of shadow to draw
5936 * @area: clip rectangle, or %NULL if the
5937 * output should not be clipped
5938 * @widget: the widget (may be %NULL)
5939 * @detail: a style detail (may be %NULL)
5940 * @x: x origin of the rectangle to draw the check in
5941 * @y: y origin of the rectangle to draw the check in
5942 * @width: the width of the rectangle to draw the check in
5943 * @height: the height of the rectangle to draw the check in
5945 * Draws a check button indicator in the given rectangle on @window with
5946 * the given parameters.
5949 gtk_paint_check (GtkStyle *style,
5951 GtkStateType state_type,
5952 GtkShadowType shadow_type,
5955 const gchar *detail,
5961 g_return_if_fail (GTK_IS_STYLE (style));
5962 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
5963 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
5965 GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
5970 * @style: a #GtkStyle
5971 * @window: a #GdkWindow
5972 * @state_type: a state
5973 * @shadow_type: the type of shadow to draw
5974 * @area: clip rectangle, or %NULL if the
5975 * output should not be clipped
5976 * @widget: the widget (may be %NULL)
5977 * @detail: a style detail (may be %NULL)
5978 * @x: x origin of the rectangle to draw the option in
5979 * @y: y origin of the rectangle to draw the option in
5980 * @width: the width of the rectangle to draw the option in
5981 * @height: the height of the rectangle to draw the option in
5983 * Draws a radio button indicator in the given rectangle on @window with
5984 * the given parameters.
5987 gtk_paint_option (GtkStyle *style,
5989 GtkStateType state_type,
5990 GtkShadowType shadow_type,
5993 const gchar *detail,
5999 g_return_if_fail (GTK_IS_STYLE (style));
6000 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
6001 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6003 GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6008 * @style: a #GtkStyle
6009 * @window: a #GdkWindow
6010 * @state_type: a state
6011 * @shadow_type: the type of shadow to draw
6012 * @area: clip rectangle, or %NULL if the
6013 * output should not be clipped
6014 * @widget: the widget (may be %NULL)
6015 * @detail: a style detail (may be %NULL)
6016 * @x: x origin of the rectangle to draw the tab in
6017 * @y: y origin of the rectangle to draw the tab in
6018 * @width: the width of the rectangle to draw the tab in
6019 * @height: the height of the rectangle to draw the tab in
6021 * Draws an option menu tab (i.e. the up and down pointing arrows)
6022 * in the given rectangle on @window using the given parameters.
6025 gtk_paint_tab (GtkStyle *style,
6027 GtkStateType state_type,
6028 GtkShadowType shadow_type,
6031 const gchar *detail,
6037 g_return_if_fail (GTK_IS_STYLE (style));
6038 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
6039 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6041 GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
6045 * gtk_paint_shadow_gap:
6046 * @style: a #GtkStyle
6047 * @window: a #GdkWindow
6048 * @state_type: a state
6049 * @shadow_type: type of shadow to draw
6050 * @area: clip rectangle, or %NULL if the
6051 * output should not be clipped
6052 * @widget: the widget (may be %NULL)
6053 * @detail: a style detail (may be %NULL)
6054 * @x: x origin of the rectangle
6055 * @y: y origin of the rectangle
6056 * @width: width of the rectangle
6057 * @height: width of the rectangle
6058 * @gap_side: side in which to leave the gap
6059 * @gap_x: starting position of the gap
6060 * @gap_width: width of the gap
6062 * Draws a shadow around the given rectangle in @window
6063 * using the given style and state and shadow type, leaving a
6067 gtk_paint_shadow_gap (GtkStyle *style,
6069 GtkStateType state_type,
6070 GtkShadowType shadow_type,
6078 GtkPositionType gap_side,
6082 g_return_if_fail (GTK_IS_STYLE (style));
6083 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
6084 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6086 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);
6091 * gtk_paint_box_gap:
6092 * @style: a #GtkStyle
6093 * @window: a #GdkWindow
6094 * @state_type: a state
6095 * @shadow_type: type of shadow to draw
6096 * @area: clip rectangle, or %NULL if the
6097 * output should not be clipped
6098 * @widget: the widget (may be %NULL)
6099 * @detail: a style detail (may be %NULL)
6100 * @x: x origin of the rectangle
6101 * @y: y origin of the rectangle
6102 * @width: width of the rectangle
6103 * @height: width of the rectangle
6104 * @gap_side: side in which to leave the gap
6105 * @gap_x: starting position of the gap
6106 * @gap_width: width of the gap
6108 * Draws a box in @window using the given style and state and shadow type,
6109 * leaving a gap in one side.
6112 gtk_paint_box_gap (GtkStyle *style,
6114 GtkStateType state_type,
6115 GtkShadowType shadow_type,
6123 GtkPositionType gap_side,
6127 g_return_if_fail (GTK_IS_STYLE (style));
6128 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
6129 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6131 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);
6135 * gtk_paint_extension:
6136 * @style: a #GtkStyle
6137 * @window: a #GdkWindow
6138 * @state_type: a state
6139 * @shadow_type: type of shadow to draw
6140 * @area: clip rectangle, or %NULL if the
6141 * output should not be clipped
6142 * @widget: the widget (may be %NULL)
6143 * @detail: a style detail (may be %NULL)
6144 * @x: x origin of the extension
6145 * @y: y origin of the extension
6146 * @width: width of the extension
6147 * @height: width of the extension
6148 * @gap_side: the side on to which the extension is attached
6150 * Draws an extension, i.e. a notebook tab.
6153 gtk_paint_extension (GtkStyle *style,
6155 GtkStateType state_type,
6156 GtkShadowType shadow_type,
6164 GtkPositionType gap_side)
6166 g_return_if_fail (GTK_IS_STYLE (style));
6167 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
6168 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6170 GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
6175 * @style: a #GtkStyle
6176 * @window: a #GdkWindow
6177 * @state_type: a state
6178 * @area: clip rectangle, or %NULL if the
6179 * output should not be clipped
6180 * @widget: the widget (may be %NULL)
6181 * @detail: a style detail (may be %NULL)
6182 * @x: the x origin of the rectangle around which to draw a focus indicator
6183 * @y: the y origin of the rectangle around which to draw a focus indicator
6184 * @width: the width of the rectangle around which to draw a focus indicator
6185 * @height: the height of the rectangle around which to draw a focus indicator
6187 * Draws a focus indicator around the given rectangle on @window using the
6191 gtk_paint_focus (GtkStyle *style,
6193 GtkStateType state_type,
6196 const gchar *detail,
6202 g_return_if_fail (GTK_IS_STYLE (style));
6203 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
6204 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6206 GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height);
6210 gtk_paint_slider (GtkStyle *style,
6212 GtkStateType state_type,
6213 GtkShadowType shadow_type,
6216 const gchar *detail,
6221 GtkOrientation orientation)
6223 g_return_if_fail (GTK_IS_STYLE (style));
6224 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
6225 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6227 GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6232 * @style: a #GtkStyle
6233 * @window: a #GdkWindow
6234 * @state_type: a state
6235 * @shadow_type: type of shadow to draw
6236 * @area: clip rectangle, or %NULL if the
6237 * output should not be clipped
6238 * @widget: the widget (may be %NULL)
6239 * @detail: a style detail (may be %NULL)
6240 * @x: x origin of the handle
6241 * @y: y origin of the handle
6242 * @width: with of the handle
6243 * @height: height of the handle
6244 * @orientation: the orientation of the handle
6246 * Draws a handle as used in #GtkHandleBox and #GtkPaned.
6249 gtk_paint_handle (GtkStyle *style,
6251 GtkStateType state_type,
6252 GtkShadowType shadow_type,
6255 const gchar *detail,
6260 GtkOrientation orientation)
6262 g_return_if_fail (GTK_IS_STYLE (style));
6263 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
6264 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6266 GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
6270 * gtk_paint_expander:
6271 * @style: a #GtkStyle
6272 * @window: a #GdkWindow
6273 * @state_type: a state
6274 * @area: clip rectangle, or %NULL if the
6275 * output should not be clipped
6276 * @widget: the widget (may be %NULL)
6277 * @detail: a style detail (may be %NULL)
6278 * @x: the x position to draw the expander at
6279 * @y: the y position to draw the expander at
6280 * @expander_style: the style to draw the expander in; determines
6281 * whether the expander is collapsed, expanded, or in an
6282 * intermediate state.
6284 * Draws an expander as used in #GtkTreeView. @x and @y specify the
6285 * center the expander. The size of the expander is determined by the
6286 * "expander-size" style property of @widget. (If widget is not
6287 * specified or doesn't have an "expander-size" property, an
6288 * unspecified default size will be used, since the caller doesn't
6289 * have sufficient information to position the expander, this is
6290 * likely not useful.) The expander is expander_size pixels tall
6291 * in the collapsed position and expander_size pixels wide in the
6292 * expanded position.
6295 gtk_paint_expander (GtkStyle *style,
6297 GtkStateType state_type,
6300 const gchar *detail,
6303 GtkExpanderStyle expander_style)
6305 g_return_if_fail (GTK_IS_STYLE (style));
6306 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
6307 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6309 GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type, area,
6310 widget, detail, x, y, expander_style);
6314 gtk_paint_layout (GtkStyle *style,
6316 GtkStateType state_type,
6320 const gchar *detail,
6323 PangoLayout *layout)
6325 g_return_if_fail (GTK_IS_STYLE (style));
6326 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
6327 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6329 GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text, area,
6330 widget, detail, x, y, layout);
6334 * gtk_paint_resize_grip:
6335 * @style: a #GtkStyle
6336 * @window: a #GdkWindow
6337 * @state_type: a state
6338 * @area: clip rectangle, or %NULL if the
6339 * output should not be clipped
6340 * @widget: the widget (may be %NULL)
6341 * @detail: a style detail (may be %NULL)
6342 * @edge: the edge in which to draw the resize grip
6343 * @x: the x origin of the rectangle in which to draw the resize grip
6344 * @y: the y origin of the rectangle in which to draw the resize grip
6345 * @width: the width of the rectangle in which to draw the resize grip
6346 * @height: the height of the rectangle in which to draw the resize grip
6348 * Draws a resize grip in the given rectangle on @window using the given
6352 gtk_paint_resize_grip (GtkStyle *style,
6354 GtkStateType state_type,
6357 const gchar *detail,
6365 g_return_if_fail (GTK_IS_STYLE (style));
6366 g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
6367 g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
6369 GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
6370 area, widget, detail,
6371 edge, x, y, width, height);
6376 * @border_: a #GtkBorder.
6377 * @returns: a copy of @border_.
6379 * Copies a #GtkBorder structure.
6382 gtk_border_copy (const GtkBorder *border)
6384 return (GtkBorder *)g_memdup (border, sizeof (GtkBorder));
6389 * @border_: a #GtkBorder.
6391 * Frees a #GtkBorder structure.
6394 gtk_border_free (GtkBorder *border)
6400 gtk_border_get_type (void)
6402 static GType our_type = 0;
6405 our_type = g_boxed_type_register_static ("GtkBorder",
6406 (GBoxedCopyFunc) gtk_border_copy,
6407 (GBoxedFreeFunc) gtk_border_free);
6413 gtk_style_get_font_internal (GtkStyle *style)
6415 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6417 if (style->private_font && style->private_font_desc)
6419 if (!style->font_desc ||
6420 !pango_font_description_equal (style->private_font_desc, style->font_desc))
6422 gdk_font_unref (style->private_font);
6423 style->private_font = NULL;
6425 if (style->private_font_desc)
6427 pango_font_description_free (style->private_font_desc);
6428 style->private_font_desc = NULL;
6433 if (!style->private_font)
6435 GdkDisplay *display;
6437 if (style->colormap)
6439 display = gdk_screen_get_display (gdk_colormap_get_screen (style->colormap));
6443 display = gdk_display_get_default ();
6444 GTK_NOTE (MULTIHEAD,
6445 g_warning ("gtk_style_get_font() should not be called on an unattached style"));
6448 if (style->font_desc)
6450 style->private_font = gdk_font_from_description_for_display (display, style->font_desc);
6451 style->private_font_desc = pango_font_description_copy (style->font_desc);
6454 if (!style->private_font)
6455 style->private_font = gdk_font_load_for_display (display, "fixed");
6457 if (!style->private_font)
6458 g_error ("Unable to load \"fixed\" font");
6461 return style->private_font;
6465 * gtk_style_get_font:
6466 * @style: a #GtkStyle
6468 * Gets the #GdkFont to use for the given style. This is
6469 * meant only as a replacement for direct access to @style->font
6470 * and should not be used in new code. New code should
6471 * use @style->font_desc instead.
6473 * Return value: the #GdkFont for the style. This font is owned
6474 * by the style; if you want to keep around a copy, you must
6475 * call gdk_font_ref().
6478 gtk_style_get_font (GtkStyle *style)
6480 g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
6482 return gtk_style_get_font_internal (style);
6486 * gtk_style_set_font:
6487 * @style: a #GtkStyle.
6488 * @font: a #GdkFont, or %NULL to use the #GdkFont corresponding
6489 * to style->font_desc.
6491 * Sets the #GdkFont to use for a given style. This is
6492 * meant only as a replacement for direct access to style->font
6493 * and should not be used in new code. New code should
6494 * use style->font_desc instead.
6497 gtk_style_set_font (GtkStyle *style,
6502 g_return_if_fail (GTK_IS_STYLE (style));
6504 old_font = style->private_font;
6506 style->private_font = font;
6508 gdk_font_ref (font);
6511 gdk_font_unref (old_font);
6513 if (style->private_font_desc)
6515 pango_font_description_free (style->private_font_desc);
6516 style->private_font_desc = NULL;
6520 typedef struct _CursorInfo CursorInfo;
6526 GdkGC *secondary_gc;
6530 style_unrealize_cursor_gcs (GtkStyle *style)
6534 cursor_info = g_object_get_data (G_OBJECT (style), "gtk-style-cursor-info");
6537 if (cursor_info->primary_gc)
6538 gtk_gc_release (cursor_info->primary_gc);
6540 if (cursor_info->secondary_gc)
6541 gtk_gc_release (cursor_info->secondary_gc);
6543 g_free (cursor_info);
6544 g_object_set_data (G_OBJECT (style), "gtk-style-cursor-info", NULL);
6549 make_cursor_gc (GtkWidget *widget,
6550 const gchar *property_name,
6551 const GdkColor *fallback)
6553 GdkGCValues gc_values;
6554 GdkGCValuesMask gc_values_mask;
6555 GdkColor *cursor_color;
6557 gtk_widget_style_get (widget, property_name, &cursor_color, NULL);
6559 gc_values_mask = GDK_GC_FOREGROUND;
6562 gc_values.foreground = *cursor_color;
6563 gdk_color_free (cursor_color);
6566 gc_values.foreground = *fallback;
6568 gdk_rgb_find_color (widget->style->colormap, &gc_values.foreground);
6569 return gtk_gc_get (widget->style->depth, widget->style->colormap, &gc_values, gc_values_mask);
6573 get_insertion_cursor_gc (GtkWidget *widget,
6574 gboolean is_primary)
6576 CursorInfo *cursor_info;
6578 cursor_info = g_object_get_data (G_OBJECT (widget->style), "gtk-style-cursor-info");
6581 cursor_info = g_new (CursorInfo, 1);
6582 g_object_set_data (G_OBJECT (widget->style), "gtk-style-cursor-info", cursor_info);
6583 cursor_info->primary_gc = NULL;
6584 cursor_info->secondary_gc = NULL;
6585 cursor_info->for_type = G_TYPE_INVALID;
6588 /* We have to keep track of the type because gtk_widget_style_get()
6589 * can return different results when called on the same property and
6590 * same style but for different widgets. :-(. That is,
6591 * GtkEntry::cursor-color = "red" in a style will modify the cursor
6592 * color for entries but not for text view.
6594 if (cursor_info->for_type != G_OBJECT_TYPE (widget))
6596 cursor_info->for_type = G_OBJECT_TYPE (widget);
6597 if (cursor_info->primary_gc)
6599 gtk_gc_release (cursor_info->primary_gc);
6600 cursor_info->primary_gc = NULL;
6602 if (cursor_info->secondary_gc)
6604 gtk_gc_release (cursor_info->secondary_gc);
6605 cursor_info->secondary_gc = NULL;
6611 if (!cursor_info->primary_gc)
6612 cursor_info->primary_gc = make_cursor_gc (widget,
6614 &widget->style->black);
6616 return cursor_info->primary_gc;
6620 static const GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 };
6622 if (!cursor_info->secondary_gc)
6623 cursor_info->secondary_gc = make_cursor_gc (widget,
6624 "secondary-cursor-color",
6627 return cursor_info->secondary_gc;
6632 draw_insertion_cursor (GtkWidget *widget,
6633 GdkDrawable *drawable,
6635 GdkRectangle *location,
6636 GtkTextDirection direction,
6637 gboolean draw_arrow)
6643 gfloat cursor_aspect_ratio;
6646 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6648 /* When changing the shape or size of the cursor here,
6649 * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
6652 gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL);
6654 stem_width = location->height * cursor_aspect_ratio + 1;
6655 arrow_width = stem_width + 1;
6657 /* put (stem_width % 2) on the proper side of the cursor */
6658 if (direction == GTK_TEXT_DIR_LTR)
6659 offset = stem_width / 2;
6661 offset = stem_width - stem_width / 2;
6663 for (i = 0; i < stem_width; i++)
6664 gdk_draw_line (drawable, gc,
6665 location->x + i - offset, location->y,
6666 location->x + i - offset, location->y + location->height - 1);
6670 if (direction == GTK_TEXT_DIR_RTL)
6672 x = location->x - offset - 1;
6673 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6675 for (i = 0; i < arrow_width; i++)
6677 gdk_draw_line (drawable, gc,
6679 x, y + 2 * arrow_width - i - 1);
6683 else if (direction == GTK_TEXT_DIR_LTR)
6685 x = location->x + stem_width - offset;
6686 y = location->y + location->height - arrow_width * 2 - arrow_width + 1;
6688 for (i = 0; i < arrow_width; i++)
6690 gdk_draw_line (drawable, gc,
6692 x, y + 2 * arrow_width - i - 1);
6700 * gtk_draw_insertion_cursor:
6701 * @widget: a #GtkWidget
6702 * @drawable: a #GdkDrawable
6703 * @area: rectangle to which the output is clipped, or %NULL if the
6704 * output should not be clipped
6705 * @location: location where to draw the cursor (@location->width is ignored)
6706 * @is_primary: if the cursor should be the primary cursor color.
6707 * @direction: whether the cursor is left-to-right or
6708 * right-to-left. Should never be #GTK_TEXT_DIR_NONE
6709 * @draw_arrow: %TRUE to draw a directional arrow on the
6710 * cursor. Should be %FALSE unless the cursor is split.
6712 * Draws a text caret on @drawable at @location. This is not a style function
6713 * but merely a convenience function for drawing the standard cursor shape.
6718 gtk_draw_insertion_cursor (GtkWidget *widget,
6719 GdkDrawable *drawable,
6721 GdkRectangle *location,
6722 gboolean is_primary,
6723 GtkTextDirection direction,
6724 gboolean draw_arrow)
6728 g_return_if_fail (GTK_IS_WIDGET (widget));
6729 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
6730 g_return_if_fail (location != NULL);
6731 g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
6733 gc = get_insertion_cursor_gc (widget, is_primary);
6735 gdk_gc_set_clip_rectangle (gc, area);
6737 draw_insertion_cursor (widget, drawable, gc,
6738 location, direction, draw_arrow);
6741 gdk_gc_set_clip_rectangle (gc, NULL);
6744 #define __GTK_STYLE_C__
6745 #include "gtkaliasdef.c"