3 /* #define ALWAYS_DITHER_GRADIENTS */
6 get_direction (GtkWidget
*widget
)
11 dir
= gtk_widget_get_direction (widget
);
13 dir
= GTK_TEXT_DIR_LTR
;
19 generate_bit (unsigned char alpha
[], GdkColor
*color
, double mult
)
23 unsigned char *pixels
;
27 r
= (color
->red
>> 8) * mult
;
29 g
= (color
->green
>> 8) * mult
;
31 b
= (color
->blue
>> 8) * mult
;
34 pixbuf
= gdk_pixbuf_new (GDK_COLORSPACE_RGB
, TRUE
, 8, RADIO_SIZE
, RADIO_SIZE
);
36 w
= gdk_pixbuf_get_width (pixbuf
);
37 h
= gdk_pixbuf_get_height (pixbuf
);
38 rs
= gdk_pixbuf_get_rowstride (pixbuf
);
39 pixels
= gdk_pixbuf_get_pixels (pixbuf
);
46 pixels
[y
*rs
+ x
*4 + 0] = r
;
47 pixels
[y
*rs
+ x
*4 + 1] = g
;
48 pixels
[y
*rs
+ x
*4 + 2] = b
;
50 pixels
[y
*rs
+ x
*4 + 3] = alpha
[y
*w
+ x
];
52 pixels
[y
*rs
+ x
*4 + 3] = 255;
59 #define CLAMP_UCHAR(v) ((guchar) (CLAMP (((int)v), (int)0, (int)255)))
62 colorize_bit (unsigned char *bit
,
69 const guchar
*src
, *asrc
;
75 pixbuf
= gdk_pixbuf_new (GDK_COLORSPACE_RGB
, TRUE
, 8, RADIO_SIZE
, RADIO_SIZE
);
80 dest_rowstride
= gdk_pixbuf_get_rowstride (pixbuf
);
81 width
= gdk_pixbuf_get_width (pixbuf
);
82 height
= gdk_pixbuf_get_height (pixbuf
);
83 dest_pixels
= gdk_pixbuf_get_pixels (pixbuf
);
85 for (y
= 0; y
< RADIO_SIZE
; y
++)
87 src
= bit
+ y
* RADIO_SIZE
;
88 asrc
= alpha
+ y
* RADIO_SIZE
;
89 dest
= dest_pixels
+ y
* dest_rowstride
;
91 for (x
= 0; x
< RADIO_SIZE
; x
++)
95 intensity
= (src
[x
] + 0 )/ 255.0;
99 /* Go from black at intensity = 0.0 to new_color at intensity = 0.5 */
100 dr
= (new_color
->red
* intensity
* 2.0) / 65535.0;
101 dg
= (new_color
->green
* intensity
* 2.0) / 65535.0;
102 db
= (new_color
->blue
* intensity
* 2.0) / 65535.0;
106 /* Go from new_color at intensity = 0.5 to white at intensity = 1.0 */
107 dr
= (new_color
->red
+ (65535 - new_color
->red
) * (intensity
- 0.5) * 2.0) / 65535.0;
108 dg
= (new_color
->green
+ (65535 - new_color
->green
) * (intensity
- 0.5) * 2.0) / 65535.0;
109 db
= (new_color
->blue
+ (65535 - new_color
->blue
) * (intensity
- 0.5) * 2.0) / 65535.0;
112 dest
[0] = CLAMP_UCHAR (255 * dr
);
113 dest
[1] = CLAMP_UCHAR (255 * dg
);
114 dest
[2] = CLAMP_UCHAR (255 * db
);
125 pixbuf_to_pixmap (GtkStyle
*style
,
132 pixmap
= gdk_pixmap_new (gdk_screen_get_root_window (screen
),
133 gdk_pixbuf_get_width (pixbuf
),
134 gdk_pixbuf_get_height (pixbuf
),
137 gdk_drawable_set_colormap (pixmap
, style
->colormap
);
139 tmp_gc
= gdk_gc_new (pixmap
);
141 gdk_pixbuf_render_to_drawable (pixbuf
, pixmap
, tmp_gc
, 0, 0, 0, 0,
142 gdk_pixbuf_get_width (pixbuf
),
143 gdk_pixbuf_get_height (pixbuf
),
144 GDK_RGB_DITHER_NORMAL
, 0, 0);
146 gdk_gc_unref (tmp_gc
);
153 rgb_to_hls (gdouble
*r
,
201 s
= (max
- min
) / (max
+ min
);
203 s
= (max
- min
) / (2 - max
- min
);
207 h
= (green
- blue
) / delta
;
208 else if (green
== max
)
209 h
= 2 + (blue
- red
) / delta
;
210 else if (blue
== max
)
211 h
= 4 + (red
- green
) / delta
;
224 hls_to_rgb (gdouble
*h
,
237 if (lightness
<= 0.5)
238 m2
= lightness
* (1 + saturation
);
240 m2
= lightness
+ saturation
- lightness
* saturation
;
242 m1
= 2 * lightness
- m2
;
259 r
= m1
+ (m2
- m1
) * hue
/ 60;
263 r
= m1
+ (m2
- m1
) * (240 - hue
) / 60;
274 g
= m1
+ (m2
- m1
) * hue
/ 60;
278 g
= m1
+ (m2
- m1
) * (240 - hue
) / 60;
289 b
= m1
+ (m2
- m1
) * hue
/ 60;
293 b
= m1
+ (m2
- m1
) * (240 - hue
) / 60;
304 shade (GdkColor
* a
, GdkColor
* b
, float k
)
310 red
= (gdouble
) a
->red
/ 65535.0;
311 green
= (gdouble
) a
->green
/ 65535.0;
312 blue
= (gdouble
) a
->blue
/ 65535.0;
314 rgb_to_hls (&red
, &green
, &blue
);
319 else if (green
< 0.0)
328 hls_to_rgb (&red
, &green
, &blue
);
330 b
->red
= red
* 65535.0;
331 b
->green
= green
* 65535.0;
332 b
->blue
= blue
* 65535.0;
336 /**************************************************************************/
339 arrow_draw_hline (GdkWindow
*window
,
346 if (x2
- x1
< 7 && !last
) /* 7 to get garretts pixels, otherwise 6 */
348 gdk_draw_line (window
, gc
, x1
, y
, x2
, y
);
352 /* we don't draw "spikes" for very small arrows */
355 /*gdk_draw_line (window, gc, x1+1, y, x1+1, y);
356 gdk_draw_line (window, gc, x2-1, y, x2-1, y);*/
360 gdk_draw_line (window
, gc
, x1
+2, y
, x1
+2, y
);
361 gdk_draw_line (window
, gc
, x2
-2, y
, x2
-2, y
);
366 gdk_draw_line (window
, gc
, x1
, y
, x1
+2, y
);
367 gdk_draw_line (window
, gc
, x2
-2, y
, x2
, y
);
372 arrow_draw_vline (GdkWindow
*window
,
379 if (y2
- y1
< 7 && !last
) /* 7 to get garretts pixels */
380 gdk_draw_line (window
, gc
, x
, y1
, x
, y2
);
383 /* we don't draw "spikes" for very small arrows */
385 gdk_draw_line (window
, gc
, x
, y1
+2, x
, y1
+2);
386 gdk_draw_line (window
, gc
, x
, y2
-2, x
, y2
-2);
391 gdk_draw_line (window
, gc
, x
, y1
, x
, y1
+2);
392 gdk_draw_line (window
, gc
, x
, y2
-2, x
, y2
);
399 draw_arrow (GdkWindow
*window
,
402 GtkArrowType arrow_type
,
411 gdk_gc_set_clip_rectangle (gc
, area
);
413 if (arrow_type
== GTK_ARROW_DOWN
)
415 for (i
= 0, j
= -1; i
< height
; i
++, j
++)
416 arrow_draw_hline (window
, gc
, x
+ j
, x
+ width
- j
- 1, y
+ i
, i
== 0);
419 else if (arrow_type
== GTK_ARROW_UP
)
421 for (i
= height
- 1, j
= -1; i
>= 0; i
--, j
++)
422 arrow_draw_hline (window
, gc
, x
+ j
, x
+ width
- j
- 1, y
+ i
, i
== height
- 1);
424 else if (arrow_type
== GTK_ARROW_LEFT
)
426 for (i
= width
- 1, j
= -1; i
>= 0; i
--, j
++)
427 arrow_draw_vline (window
, gc
, y
+ j
, y
+ height
- j
- 1, x
+ i
, i
== width
- 1);
429 else if (arrow_type
== GTK_ARROW_RIGHT
)
431 for (i
= 0, j
= -1; i
< width
; i
++, j
++)
432 arrow_draw_vline (window
, gc
, y
+ j
, y
+ height
- j
- 1, x
+ i
, i
== 0);
436 gdk_gc_set_clip_rectangle (gc
, NULL
);
440 calculate_arrow_geometry (GtkArrowType arrow_type
,
462 if (arrow_type
== GTK_ARROW_DOWN
)
464 if (*height
% 2 == 1 || h
% 2 == 0)
469 if (*height
% 2 == 0 || h
% 2 == 0)
474 case GTK_ARROW_RIGHT
:
485 if (arrow_type
== GTK_ARROW_RIGHT
)
487 if (*width
% 2 == 1 || w
% 2 == 0)
492 if (*width
% 2 == 0 || w
% 2 == 0)
498 /* should not be reached */
502 *x
+= (*width
- w
) / 2;
503 *y
+= (*height
- h
) / 2;
509 void gtk_treeview_get_header_index (GtkTreeView
*tv
, GtkWidget
*header
,
510 gint
*column_index
, gint
*columns
,
514 *column_index
= *columns
= 0;
515 list
= gtk_tree_view_get_columns (tv
);
519 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(list
->data
);
520 if ( column
->button
== header
)
522 *column_index
= *columns
;
523 *resizable
= column
->resizable
;
525 if ( column
->visible
)
527 } while ((list
= g_list_next(list
)));
530 void gtk_clist_get_header_index (GtkCList
*clist
, GtkWidget
*button
,
531 gint
*column_index
, gint
*columns
)
533 *columns
= clist
->columns
;
536 for (i
=0; i
<*columns
; i
++)
538 if (clist
->column
[i
].button
== button
)
547 sanitize_size (GdkWindow
*window
,
551 gboolean set_bg
= FALSE
;
553 if ((*width
== -1) && (*height
== -1))
555 set_bg
= GDK_IS_WINDOW (window
);
556 gdk_window_get_size (window
, width
, height
);
558 else if (*width
== -1)
559 gdk_window_get_size (window
, width
, NULL
);
560 else if (*height
== -1)
561 gdk_window_get_size (window
, NULL
, height
);
566 static GtkRequisition default_option_indicator_size
= { 7, 13 };
567 static GtkBorder default_option_indicator_spacing
= { 7, 5, 2, 2 };
570 option_menu_get_props (GtkWidget
*widget
,
571 GtkRequisition
*indicator_size
,
572 GtkBorder
*indicator_spacing
)
574 GtkRequisition
*tmp_size
= NULL
;
575 GtkBorder
*tmp_spacing
= NULL
;
578 gtk_widget_style_get (widget
, "indicator_size", &tmp_size
,
579 "indicator_spacing", &tmp_spacing
, NULL
);
583 *indicator_size
= *tmp_size
;
587 *indicator_size
= default_option_indicator_size
;
591 *indicator_spacing
= *tmp_spacing
;
592 g_free (tmp_spacing
);
595 *indicator_spacing
= default_option_indicator_spacing
;
598 GtkWidget
*special_get_ancestor(GtkWidget
* widget
,
601 g_return_val_if_fail(GTK_IS_WIDGET(widget
), NULL
);
603 while (widget
&& widget
->parent
604 && !g_type_is_a(GTK_WIDGET_TYPE(widget
->parent
),
606 widget
= widget
->parent
;
609 (widget
&& widget
->parent
610 && g_type_is_a(GTK_WIDGET_TYPE(widget
->parent
), widget_type
)))
616 /* Dithered Gradient Buffers */
618 internel_image_buffer_free_pixels (guchar
*pixels
, gpointer data
)
624 internal_image_buffer_new (gint width
, gint height
)
629 g_return_val_if_fail (width
> 0, NULL
);
630 g_return_val_if_fail (height
> 0, NULL
);
632 rowstride
= width
* 3;
634 buf
= g_try_malloc (height
* rowstride
);
639 return gdk_pixbuf_new_from_data(buf
, GDK_COLORSPACE_RGB
,
641 width
, height
, rowstride
,
642 internel_image_buffer_free_pixels
, NULL
);
646 internal_color_get_as_uchars(GdkColor
*color
,
651 *red
= (guchar
) (color
->red
/ 256.0);
652 *green
= (guchar
) (color
->green
/ 256.0);
653 *blue
= (guchar
) (color
->blue
/ 256.0);
657 internal_create_horizontal_gradient_image_buffer (gint width
, gint height
,
662 long r
, g
, b
, dr
, dg
, db
;
670 buffer
= internal_image_buffer_new (width
, height
);
675 pixels
= gdk_pixbuf_get_pixels (buffer
);
677 rowstride
= gdk_pixbuf_get_rowstride (buffer
);
679 internal_color_get_as_uchars(from
, &r0
, &g0
, &b0
);
680 internal_color_get_as_uchars(to
, &rf
, &gf
, &bf
);
686 dr
= ((rf
-r0
)<<16)/width
;
687 dg
= ((gf
-g0
)<<16)/width
;
688 db
= ((bf
-b0
)<<16)/width
;
690 /* render the first line */
691 for (i
=0; i
<width
; i
++)
693 *(ptr
++) = (guchar
)(r
>>16);
694 *(ptr
++) = (guchar
)(g
>>16);
695 *(ptr
++) = (guchar
)(b
>>16);
702 /* copy the first line to the other lines */
703 for (i
=1; i
<height
; i
++)
705 memcpy (&(pixels
[i
*rowstride
]), pixels
, rowstride
);
712 internal_create_vertical_gradient_image_buffer (gint width
, gint height
,
716 gint i
, j
, max_block
, last_block
;
717 long r
, g
, b
, dr
, dg
, db
;
729 buffer
= internal_image_buffer_new (width
, height
);
734 pixels
= gdk_pixbuf_get_pixels (buffer
);
735 rowstride
= gdk_pixbuf_get_rowstride (buffer
);
737 internal_color_get_as_uchars(from
, &r0
, &g0
, &b0
);
738 internal_color_get_as_uchars(to
, &rf
, &gf
, &bf
);
744 dr
= ((rf
-r0
)<<16)/height
;
745 dg
= ((gf
-g0
)<<16)/height
;
746 db
= ((bf
-b0
)<<16)/height
;
750 for (i
=0; i
< height
; i
++)
752 ptr
= pixels
+ i
* rowstride
;
762 for (j
=1; j
<= max_block
; j
*= 2)
764 memcpy (&(ptr
[j
*3]), ptr
, j
*3);
766 if ((j
*2) >= max_block
)
772 if ((last_block
< width
) && (last_block
> 0))
774 memcpy (&(ptr
[last_block
*3]), ptr
, (width
- last_block
)*3);
787 draw_vgradient (GdkDrawable
*drawable
, GdkGC
*gc
, GtkStyle
*style
,
788 int x
, int y
, int width
, int height
,
789 GdkColor
*left_color
, GdkColor
*right_color
)
791 #ifndef ALWAYS_DITHER_GRADIENTS
792 gboolean dither
= ((style
->depth
> 0) && (style
->depth
<= 16));
795 if ((width
<= 0) || (height
<= 0))
798 if ( left_color
== NULL
|| right_color
== NULL
)
800 gdk_draw_rectangle (drawable
, gc
, TRUE
, x
, y
, width
, height
);
804 #ifndef ALWAYS_DITHER_GRADIENTS
808 GdkPixbuf
*image_buffer
= NULL
;
810 image_buffer
= internal_create_horizontal_gradient_image_buffer (width
, height
, left_color
, right_color
);
814 gdk_draw_pixbuf(drawable
, gc
, image_buffer
, 0, 0, x
, y
, width
, height
, GDK_RGB_DITHER_MAX
, 0, 0);
816 g_object_unref(image_buffer
);
819 #ifndef ALWAYS_DITHER_GRADIENTS
825 GdkGCValues old_values
;
827 gdk_gc_get_values (gc
, &old_values
);
829 if (left_color
== right_color
)
832 gdk_rgb_find_color (style
->colormap
, &col
);
833 gdk_gc_set_foreground (gc
, &col
);
834 gdk_draw_rectangle (drawable
, gc
, TRUE
, x
, y
, width
, height
);
835 gdk_gc_set_foreground (gc
, &old_values
.foreground
);
840 dr
= (right_color
->red
- left_color
->red
) / width
;
841 dg
= (right_color
->green
- left_color
->green
) / width
;
842 db
= (right_color
->blue
- left_color
->blue
) / width
;
844 for (i
= 0; i
< width
; i
++)
846 gdk_rgb_find_color (style
->colormap
, &col
);
848 gdk_gc_set_foreground (gc
, &col
);
849 gdk_draw_line (drawable
, gc
, x
+ i
, y
, x
+ i
, y
+ height
- 1);
856 gdk_gc_set_foreground (gc
, &old_values
.foreground
);
862 draw_hgradient (GdkDrawable
*drawable
, GdkGC
*gc
, GtkStyle
*style
,
863 int x
, int y
, int width
, int height
,
864 GdkColor
*top_color
, GdkColor
*bottom_color
)
866 #ifndef ALWAYS_DITHER_GRADIENTS
867 gboolean dither
= ((style
->depth
> 0) && (style
->depth
<= 16));
870 if ((width
<= 0) || (height
<= 0))
873 #ifndef ALWAYS_DITHER_GRADIENTS
877 GdkPixbuf
*image_buffer
= NULL
;
879 image_buffer
= internal_create_vertical_gradient_image_buffer (width
, height
, top_color
, bottom_color
);
883 gdk_draw_pixbuf(drawable
, gc
, image_buffer
, 0, 0, x
, y
, width
, height
, GDK_RGB_DITHER_MAX
, 0, 0);
885 g_object_unref(image_buffer
);
888 #ifndef ALWAYS_DITHER_GRADIENTS
894 GdkGCValues old_values
;
896 gdk_gc_get_values (gc
, &old_values
);
898 if (top_color
== bottom_color
)
901 gdk_rgb_find_color (style
->colormap
, &col
);
902 gdk_gc_set_foreground (gc
, &col
);
903 gdk_draw_rectangle (drawable
, gc
, TRUE
, x
, y
, width
, height
);
904 gdk_gc_set_foreground (gc
, &old_values
.foreground
);
909 dr
= (bottom_color
->red
- top_color
->red
) / height
;
910 dg
= (bottom_color
->green
- top_color
->green
) / height
;
911 db
= (bottom_color
->blue
- top_color
->blue
) / height
;
913 for (i
= 0; i
< height
; i
++)
915 gdk_rgb_find_color (style
->colormap
, &col
);
917 gdk_gc_set_foreground (gc
, &col
);
918 gdk_draw_line (drawable
, gc
, x
, y
+ i
, x
+ width
- 1, y
+ i
);
925 gdk_gc_set_foreground (gc
, &old_values
.foreground
);
930 void blend (GdkColormap
*colormap
,
931 GdkColor
*a
, GdkColor
*b
, GdkColor
*c
, int alpha
)
933 int inAlpha
= 100-alpha
;
934 c
->red
= (a
->red
* alpha
+ b
->red
* inAlpha
) / 100;
935 c
->green
= (a
->green
* alpha
+ b
->green
* inAlpha
) / 100;
936 c
->blue
= (a
->blue
* alpha
+ b
->blue
* inAlpha
) / 100;
938 gdk_rgb_find_color (colormap
, c
);
941 GtkWidget
*get_parent_window (GtkWidget
*widget
)
943 GtkWidget
*parent
= widget
->parent
;
945 while (parent
&& GTK_WIDGET_NO_WINDOW (parent
))
946 parent
= parent
->parent
;
951 GdkColor
*get_parent_bgcolor (GtkWidget
*widget
)
953 GtkWidget
*parent
= get_parent_window (widget
);
955 if (parent
&& parent
->style
)
956 return &parent
->style
->bg
[GTK_STATE_NORMAL
];
962 find_combo_box_widget (GtkWidget
* widget
)
964 GtkWidget
*result
= NULL
;
966 if (widget
&& !GTK_IS_COMBO_BOX_ENTRY (widget
))
968 if (GTK_IS_COMBO_BOX (widget
))
971 result
= find_combo_box_widget(widget
->parent
);
978 is_combo_box (GtkWidget
* widget
)
980 return (find_combo_box_widget(widget
) != NULL
);