Fill in unused bits so they can be used for the depth-32 target case.

2005-05-09  Owen Taylor  <otaylor@redhat.com>

        * gdk/gdkrgb.c (gdk_rgb_convert_0888_br, gdk_rgb_convert_8880_br):
        Fill in unused bits so they can be used for the depth-32 target case.
        Rewrite so that that gives a marginal speedup rather than a
        marginal slowdown. (on x86)

        * gdk/gdkscreen.h gdk/x11/gdkscreen-x11.[ch] gdk/x11/gdkvisual-x11.c:
        Add gdk_screen_get_rgba_colormap/visual to get a visual for
        windows with an alpha channel, if one exists.

        * gdk/win32/gdkscreen-win32.c gdk/linux-fb/gdkscreen-fb.c:
        Stub out gdk_screen_get_rgba_colormap/visual.

        * gdk/x11/gdkcolor-x11.c (gdk_colormap_alloc_colors): computation of
        "unused" wasn't right for depth == 32, since it depended on
        shifting by 32.

        * gdk/gdkrgb.c: Fill in alpha bits with 1s. (Based on patch from
        Keith Packard,
        http://mail.gnome.org/archives/gtk-devel-list/2004-June/msg00080.html)

        * gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture):
        Implement again, without using Xft.

        * tests/testgtk.c: Add a test for windows with an alpha channel.
This commit is contained in:
Owen Taylor 2005-05-09 22:54:10 +00:00 committed by Owen Taylor
parent e899aa852a
commit 485fd85179
15 changed files with 559 additions and 33 deletions

View File

@ -1,3 +1,30 @@
2005-05-09 Owen Taylor <otaylor@redhat.com>
* gdk/gdkrgb.c (gdk_rgb_convert_0888_br, gdk_rgb_convert_8880_br):
Fill in unused bits so they can be used for the depth-32 target case.
Rewrite so that that gives a marginal speedup rather than a
marginal slowdown. (on x86)
* gdk/gdkscreen.h gdk/x11/gdkscreen-x11.[ch] gdk/x11/gdkvisual-x11.c:
Add gdk_screen_get_rgba_colormap/visual to get a visual for
windows with an alpha channel, if one exists.
* gdk/win32/gdkscreen-win32.c gdk/linux-fb/gdkscreen-fb.c:
Stub out gdk_screen_get_rgba_colormap/visual.
* gdk/x11/gdkcolor-x11.c (gdk_colormap_alloc_colors): computation of
"unused" wasn't right for depth == 32, since it depended on
shifting by 32.
* gdk/gdkrgb.c: Fill in alpha bits with 1s. (Based on patch from
Keith Packard,
http://mail.gnome.org/archives/gtk-devel-list/2004-June/msg00080.html)
* gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture):
Implement again, without using Xft.
* tests/testgtk.c: Add a test for windows with an alpha channel.
2005-05-09 Matthias Clasen <mclasen@redhat.com>
* autogen.sh: Revert accidental commit.

View File

@ -1,3 +1,30 @@
2005-05-09 Owen Taylor <otaylor@redhat.com>
* gdk/gdkrgb.c (gdk_rgb_convert_0888_br, gdk_rgb_convert_8880_br):
Fill in unused bits so they can be used for the depth-32 target case.
Rewrite so that that gives a marginal speedup rather than a
marginal slowdown. (on x86)
* gdk/gdkscreen.h gdk/x11/gdkscreen-x11.[ch] gdk/x11/gdkvisual-x11.c:
Add gdk_screen_get_rgba_colormap/visual to get a visual for
windows with an alpha channel, if one exists.
* gdk/win32/gdkscreen-win32.c gdk/linux-fb/gdkscreen-fb.c:
Stub out gdk_screen_get_rgba_colormap/visual.
* gdk/x11/gdkcolor-x11.c (gdk_colormap_alloc_colors): computation of
"unused" wasn't right for depth == 32, since it depended on
shifting by 32.
* gdk/gdkrgb.c: Fill in alpha bits with 1s. (Based on patch from
Keith Packard,
http://mail.gnome.org/archives/gtk-devel-list/2004-June/msg00080.html)
* gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture):
Implement again, without using Xft.
* tests/testgtk.c: Add a test for windows with an alpha channel.
2005-05-09 Matthias Clasen <mclasen@redhat.com>
* autogen.sh: Revert accidental commit.

View File

@ -1,3 +1,30 @@
2005-05-09 Owen Taylor <otaylor@redhat.com>
* gdk/gdkrgb.c (gdk_rgb_convert_0888_br, gdk_rgb_convert_8880_br):
Fill in unused bits so they can be used for the depth-32 target case.
Rewrite so that that gives a marginal speedup rather than a
marginal slowdown. (on x86)
* gdk/gdkscreen.h gdk/x11/gdkscreen-x11.[ch] gdk/x11/gdkvisual-x11.c:
Add gdk_screen_get_rgba_colormap/visual to get a visual for
windows with an alpha channel, if one exists.
* gdk/win32/gdkscreen-win32.c gdk/linux-fb/gdkscreen-fb.c:
Stub out gdk_screen_get_rgba_colormap/visual.
* gdk/x11/gdkcolor-x11.c (gdk_colormap_alloc_colors): computation of
"unused" wasn't right for depth == 32, since it depended on
shifting by 32.
* gdk/gdkrgb.c: Fill in alpha bits with 1s. (Based on patch from
Keith Packard,
http://mail.gnome.org/archives/gtk-devel-list/2004-June/msg00080.html)
* gdk/x11/gdkdrawable-x11.c (gdk_x11_drawable_get_picture):
Implement again, without using Xft.
* tests/testgtk.c: Add a test for windows with an alpha channel.
2005-05-09 Matthias Clasen <mclasen@redhat.com>
* autogen.sh: Revert accidental commit.

View File

@ -197,6 +197,8 @@ gdk_screen_get_system_colormap
gdk_screen_get_system_visual
gdk_screen_get_rgb_colormap
gdk_screen_get_rgb_visual
gdk_screen_get_rgba_colormap
gdk_screen_get_rgba_visual
gdk_screen_get_root_window
gdk_screen_get_display
gdk_screen_get_number

View File

@ -992,6 +992,8 @@ gdk_screen_get_default_colormap
gdk_screen_set_default_colormap
gdk_screen_get_n_monitors
gdk_screen_get_monitor_geometry
gdk_screen_get_rgba_colormap
gdk_screen_get_rgba_visual
gdk_screen_make_display_name
#endif
#endif

View File

@ -719,6 +719,23 @@ gdk_rgb_get_info_from_colormap (GdkColormap *cmap)
return image_info;
}
static guint32
gdk_rgb_alpha_mask (GdkRgbInfo *image_info)
{
guint padding;
/* Shifting by >= width-of-type isn't defined in C */
if (image_info->visual->depth >= 32)
padding = 0;
else
padding = ((~(guint32)0)) << image_info->visual->depth;
return ~(image_info->visual->red_mask |
image_info->visual->green_mask |
image_info->visual->blue_mask |
padding);
}
static gulong
gdk_rgb_xpixel_from_rgb_internal (GdkColormap *colormap,
guint16 r, guint16 g, guint16 b)
@ -767,6 +784,7 @@ gdk_rgb_xpixel_from_rgb_internal (GdkColormap *colormap,
pixel = (unused + ((r >> (16 - image_info->visual->red_prec)) << image_info->visual->red_shift) +
((g >> (16 - image_info->visual->green_prec)) << image_info->visual->green_shift) +
((b >> (16 - image_info->visual->blue_prec)) << image_info->visual->blue_shift));
pixel |= gdk_rgb_alpha_mask (image_info);
}
else if (image_info->visual->type == GDK_VISUAL_STATIC_GRAY ||
image_info->visual->type == GDK_VISUAL_GRAYSCALE)
@ -2126,11 +2144,10 @@ gdk_rgb_convert_0888 (GdkRgbInfo *image_info, GdkImage *image,
guchar *buf, int rowstride,
gint x_align, gint y_align, GdkRgbCmap *cmap)
{
int x, y;
guchar *obuf;
int y, w;
guchar *obuf, *p;
gint bpl;
guchar *bptr, *bp2;
int r, g, b;
bptr = buf;
bpl = image->bpl;
@ -2138,13 +2155,16 @@ gdk_rgb_convert_0888 (GdkRgbInfo *image_info, GdkImage *image,
for (y = 0; y < height; y++)
{
bp2 = bptr;
for (x = 0; x < width; x++)
p = obuf;
w = width;
while (w--)
{
r = bp2[0];
g = bp2[1];
b = bp2[2];
((guint32 *)obuf)[x] = (r << 16) | (g << 8) | b;
p[0] = bp2[2];
p[1] = bp2[1];
p[2] = bp2[0];
p[3] = 0xff;
bp2 += 3;
p += 4;
}
bptr += rowstride;
obuf += bpl;
@ -2157,11 +2177,10 @@ gdk_rgb_convert_0888_br (GdkRgbInfo *image_info, GdkImage *image,
guchar *buf, int rowstride,
gint x_align, gint y_align, GdkRgbCmap *cmap)
{
int x, y;
guchar *obuf;
int y, w;
guchar *obuf, *p;
gint bpl;
guchar *bptr, *bp2;
int r, g, b;
bptr = buf;
bpl = image->bpl;
@ -2169,13 +2188,16 @@ gdk_rgb_convert_0888_br (GdkRgbInfo *image_info, GdkImage *image,
for (y = 0; y < height; y++)
{
bp2 = bptr;
for (x = 0; x < width; x++)
p = obuf;
w = width;
while (w--)
{
r = bp2[0];
g = bp2[1];
b = bp2[2];
((guint32 *)obuf)[x] = (b << 24) | (g << 16) | (r << 8);
p[0] = 0xff;
p[1] = bp2[0];
p[2] = bp2[1];
p[3] = bp2[2];
bp2 += 3;
p += 4;
}
bptr += rowstride;
obuf += bpl;
@ -2232,6 +2254,7 @@ gdk_rgb_convert_truecolor_lsb (GdkRgbInfo *image_info, GdkImage *image,
gint b_right, b_left;
gint bpp;
guint32 pixel;
guint32 alpha_mask = gdk_rgb_alpha_mask (image_info);
gint i;
r_right = 8 - image_info->visual->red_prec;
@ -2255,7 +2278,7 @@ gdk_rgb_convert_truecolor_lsb (GdkRgbInfo *image_info, GdkImage *image,
b = bp2[2];
pixel = ((r >> r_right) << r_left) |
((g >> g_right) << g_left) |
((b >> b_right) << b_left);
((b >> b_right) << b_left) | alpha_mask;
for (i = 0; i < bpp; i++)
{
*obptr++ = pixel & 0xff;
@ -2285,6 +2308,7 @@ gdk_rgb_convert_truecolor_lsb_d (GdkRgbInfo *image_info, GdkImage *image,
gint b_right, b_left, b_prec;
gint bpp;
guint32 pixel;
guint32 alpha_mask = gdk_rgb_alpha_mask (image_info);
gint i;
gint dith;
gint r1, g1, b1;
@ -2319,7 +2343,7 @@ gdk_rgb_convert_truecolor_lsb_d (GdkRgbInfo *image_info, GdkImage *image,
b1 = b + (dith >> b_prec);
pixel = (((r1 - (r1 >> r_prec)) >> r_right) << r_left) |
(((g1 - (g1 >> g_prec)) >> g_right) << g_left) |
(((b1 - (b1 >> b_prec)) >> b_right) << b_left);
(((b1 - (b1 >> b_prec)) >> b_right) << b_left) | alpha_mask;
for (i = 0; i < bpp; i++)
{
*obptr++ = pixel & 0xff;
@ -2349,6 +2373,7 @@ gdk_rgb_convert_truecolor_msb (GdkRgbInfo *image_info, GdkImage *image,
gint b_right, b_left;
gint bpp;
guint32 pixel;
guint32 alpha_mask = gdk_rgb_alpha_mask (image_info);
gint shift, shift_init;
r_right = 8 - image_info->visual->red_prec;
@ -2373,7 +2398,7 @@ gdk_rgb_convert_truecolor_msb (GdkRgbInfo *image_info, GdkImage *image,
b = bp2[2];
pixel = ((r >> r_right) << r_left) |
((g >> g_right) << g_left) |
((b >> b_right) << b_left);
((b >> b_right) << b_left) | alpha_mask;
for (shift = shift_init; shift >= 0; shift -= 8)
{
*obptr++ = (pixel >> shift) & 0xff;
@ -2402,6 +2427,7 @@ gdk_rgb_convert_truecolor_msb_d (GdkRgbInfo *image_info, GdkImage *image,
gint b_right, b_left, b_prec;
gint bpp;
guint32 pixel;
guint32 alpha_mask = gdk_rgb_alpha_mask (image_info);
gint shift, shift_init;
gint dith;
gint r1, g1, b1;
@ -2437,7 +2463,7 @@ gdk_rgb_convert_truecolor_msb_d (GdkRgbInfo *image_info, GdkImage *image,
b1 = b + (dith >> b_prec);
pixel = (((r1 - (r1 >> r_prec)) >> r_right) << r_left) |
(((g1 - (g1 >> g_prec)) >> g_right) << g_left) |
(((b1 - (b1 >> b_prec)) >> b_right) << b_left);
(((b1 - (b1 >> b_prec)) >> b_right) << b_left) | alpha_mask;
for (shift = shift_init; shift >= 0; shift -= 8)
{
*obptr++ = (pixel >> shift) & 0xff;
@ -3110,27 +3136,43 @@ gdk_rgb_select_conv (GdkRgbInfo *image_info)
(mask_bgr && byte_order == GDK_LSB_FIRST)))
conv = gdk_rgb_convert_888_msb;
#if G_BYTE_ORDER == G_BIG_ENDIAN
else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
else if (bpp == 32 &&
(depth == 24 || depth == 32) &&
vtype == GDK_VISUAL_TRUE_COLOR &&
(mask_rgb && byte_order == GDK_LSB_FIRST))
conv = gdk_rgb_convert_0888_br;
else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
else if (bpp == 32 &&
(depth == 24 || depth == 32) &&
vtype == GDK_VISUAL_TRUE_COLOR &&
(mask_rgb && byte_order == GDK_MSB_FIRST))
conv = gdk_rgb_convert_0888;
else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
(mask_bgr && byte_order == GDK_MSB_FIRST))
conv = gdk_rgb_convert_8880_br;
else if (bpp == 32 && depth == 32 && vtype == GDK_VISUAL_TRUE_COLOR &&
(mask_rgb && byte_order == GDK_LSB_FIRST))
conv = gdk_rgb_convert_8880_br;
else if (bpp == 32 && depth == 32 && vtype == GDK_VISUAL_TRUE_COLOR &&
(mask_rgb && byte_order == GDK_MSB_FIRST))
conv = gdk_rgb_convert_8880_br;
#else
else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
else if (bpp == 32 &&
(depth == 24 || depth == 32) &&
vtype == GDK_VISUAL_TRUE_COLOR &&
(mask_rgb && byte_order == GDK_MSB_FIRST))
conv = gdk_rgb_convert_0888_br;
else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
else if (bpp == 32 &&
(depth == 24 || depth == 32) &&
vtype == GDK_VISUAL_TRUE_COLOR &&
(mask_rgb && byte_order == GDK_LSB_FIRST))
conv = gdk_rgb_convert_0888;
else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
(mask_bgr && byte_order == GDK_LSB_FIRST))
conv = gdk_rgb_convert_8880_br;
else if (bpp == 32 && depth == 32 && vtype == GDK_VISUAL_TRUE_COLOR &&
(mask_rgb && byte_order == GDK_LSB_FIRST))
conv = gdk_rgb_convert_0888;
#endif
else if (vtype == GDK_VISUAL_TRUE_COLOR && byte_order == GDK_LSB_FIRST)
{
conv = gdk_rgb_convert_truecolor_lsb;

View File

@ -63,6 +63,9 @@ GdkColormap* gdk_screen_get_system_colormap (GdkScreen *screen);
GdkVisual* gdk_screen_get_system_visual (GdkScreen *screen);
GdkColormap *gdk_screen_get_rgb_colormap (GdkScreen *screen);
GdkVisual * gdk_screen_get_rgb_visual (GdkScreen *screen);
GdkColormap *gdk_screen_get_rgba_colormap (GdkScreen *screen);
GdkVisual * gdk_screen_get_rgba_visual (GdkScreen *screen);
GdkWindow * gdk_screen_get_root_window (GdkScreen *screen);
GdkDisplay * gdk_screen_get_display (GdkScreen *screen);

View File

@ -82,6 +82,22 @@ gdk_screen_get_monitor_geometry (GdkScreen *screen,
dest->height = gdk_screen_height ();
}
GdkColormap *
gdk_screen_get_rgba_colormap (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
return NULL;
}
GdkVisual *
gdk_screen_get_rgba_visual (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
return NULL;
}
gint
gdk_screen_get_number (GdkScreen *screen)
{

View File

@ -78,6 +78,22 @@ gdk_screen_get_monitor_geometry (GdkScreen *screen,
*dest = _gdk_monitors[num_monitor];
}
GdkColormap *
gdk_screen_get_rgba_colormap (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
return NULL;
}
GdkVisual *
gdk_screen_get_rgba_visual (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
return NULL;
}
gint
gdk_screen_get_number (GdkScreen *screen)
{

View File

@ -1130,8 +1130,16 @@ gdk_colormap_alloc_colors (GdkColormap *colormap,
/* If bits not used for color are used for something other than padding,
* it's likely alpha, so we set them to 1s.
*/
guint32 unused = ~ (visual->red_mask | visual->green_mask | visual->blue_mask |
(((~(guint32)0)) << visual->depth));
guint padding, unused;
/* Shifting by >= width-of-type isn't defined in C */
if (visual->depth >= 32)
padding = 0;
else
padding = ((~(guint32)0)) << visual->depth;
unused = ~ (visual->red_mask | visual->green_mask | visual->blue_mask | padding);
colors[i].pixel = (unused +
((colors[i].red >> (16 - visual->red_prec)) << visual->red_shift) +
((colors[i].green >> (16 - visual->green_prec)) << visual->green_shift) +

View File

@ -337,7 +337,29 @@ _gdk_x11_have_render (GdkDisplay *display)
static Picture
gdk_x11_drawable_get_picture (GdkDrawable *drawable)
{
return None;
GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
if (!impl->picture)
{
Display *xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
XRenderPictFormat *format;
GdkVisual *visual = gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper);
if (!visual)
return None;
format = XRenderFindVisualFormat (xdisplay, GDK_VISUAL_XVISUAL (visual));
if (format)
{
XRenderPictureAttributes attributes;
attributes.graphics_exposures = False;
impl->picture = XRenderCreatePicture (xdisplay, impl->xid, format,
CPGraphicsExposure, &attributes);
}
}
return impl->picture;
}
static void

View File

@ -288,6 +288,12 @@ gdk_screen_x11_dispose (GObject *object)
g_object_unref (screen_x11->default_colormap);
screen_x11->default_colormap = NULL;
if (screen_x11->rgba_colormap)
{
g_object_unref (screen_x11->rgba_colormap);
screen_x11->rgba_colormap = NULL;
}
screen_x11->root_window = NULL;
@ -371,6 +377,68 @@ gdk_screen_get_monitor_geometry (GdkScreen *screen,
*dest = GDK_SCREEN_X11 (screen)->monitors[monitor_num];
}
/**
* gdk_screen_get_rgba_colormap:
* @screen: a #GdkScreen.
*
* Gets a colormap to use for creating windows or pixmaps with an
* alpha channel. The windowing system on which GTK+ is running
* may not support this capability, in which case %NULL will
* be returned. Even if a non-%NULL value is returned, its
* possible that the window's alpha channel won't be honored
* when displaying the window on the screen: in particular, for
* X an appropriate windowing manager and compositing manager
* must be running to provide appropriate display.
*
* Return value: a colormap to use for windows with an alpha channel
* or %NULL if the capability is not available.
*
* Since: 2.8
**/
GdkColormap *
gdk_screen_get_rgba_colormap (GdkScreen *screen)
{
GdkScreenX11 *screen_x11;
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
screen_x11 = GDK_SCREEN_X11 (screen);
if (!screen_x11->rgba_visual)
return NULL;
if (!screen_x11->rgba_colormap)
screen_x11->rgba_colormap = gdk_colormap_new (screen_x11->rgba_visual,
FALSE);
return screen_x11->rgba_colormap;
}
/**
* gdk_screen_get_rgba_visual:
* @screen: a #GdkScreen
*
* Gets a visual to use for creating windows or pixmaps with an
* alpha channel. See the docs for gdk_screen_get_rgba_colormap()
* for caveats.
*
* Return value: a visual to use for windows with an alpha channel
* or %NULL if the capability is not available.
*
* Since: 2.8
**/
GdkVisual *
gdk_screen_get_rgba_visual (GdkScreen *screen)
{
GdkScreenX11 *screen_x11;
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
screen_x11 = GDK_SCREEN_X11 (screen);
return screen_x11->rgba_visual;
}
/**
* gdk_x11_screen_get_xscreen:
* @screen: a #GdkScreen.

View File

@ -76,11 +76,13 @@ struct _GdkScreenX11
gint navailable_types;
GHashTable *visual_hash;
GHashTable *colormap_hash;
GdkVisual *rgba_visual;
/* Colormap Part */
GdkColormap *default_colormap;
GdkColormap *system_colormap;
GdkColormap *rgba_colormap;
/* X settings */
XSettingsClient *xsettings_client;
guint xsettings_in_init : 1;

View File

@ -257,11 +257,22 @@ _gdk_visual_init (GdkScreen *screen)
}
for (i = 0; i < nvisuals; i++)
if (default_xvisual->visualid == visuals[i]->xvisual->visualid)
{
{
if (default_xvisual->visualid == visuals[i]->xvisual->visualid)
screen_x11->system_visual = visuals[i];
break;
}
/* For now, we only support 8888 ARGB for the "rgba visual".
* Additional formats (like ABGR) could be added later if they
* turn up.
*/
if (visuals[i]->visual.depth == 32 &&
(visuals[i]->visual.red_mask == 0xff0000 &&
visuals[i]->visual.green_mask == 0x00ff00 &&
visuals[i]->visual.blue_mask == 0x0000ff))
{
screen_x11->rgba_visual = GDK_VISUAL (visuals[i]);
}
}
#ifdef G_ENABLE_DEBUG
if (_gdk_debug_flags & GDK_DEBUG_MISC)

View File

@ -147,6 +147,258 @@ destroy_tooltips (GtkWidget *widget, GtkWindow **window)
}
/*
* Windows with an alpha channel
*/
static gboolean
on_alpha_window_expose (GtkWidget *widget,
GdkEventExpose *expose)
{
cairo_t *cr;
cairo_pattern_t *pattern;
int radius;
cr = gdk_drawable_create_cairo_context (widget->window);
radius = MIN (widget->allocation.width, widget->allocation.height) / 2;
pattern = cairo_pattern_create_radial (widget->allocation.width / 2,
widget->allocation.height / 2,
0.0,
widget->allocation.width / 2,
widget->allocation.height / 2,
radius * 1.33);
if (gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)))
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */
else
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
cairo_pattern_add_color_stop_rgba (pattern, 0.0,
1.0, 0.75, 0.0, 1.0); /* solid orange */
cairo_pattern_add_color_stop_rgba (pattern, 1.0,
1.0, 0.75, 0.0, 0.0); /* transparent orange */
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_paint (cr);
cairo_destroy (cr);
return FALSE;
}
static GtkWidget *
build_alpha_widgets (void)
{
GtkWidget *table;
GtkWidget *radio_button;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *entry;
table = gtk_table_new (1, 1, FALSE);
radio_button = gtk_radio_button_new_with_label (NULL, "Red");
gtk_table_attach (GTK_TABLE (table),
radio_button,
0, 1, 0, 1,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Green");
gtk_table_attach (GTK_TABLE (table),
radio_button,
0, 1, 1, 2,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Blue"),
gtk_table_attach (GTK_TABLE (table),
radio_button,
0, 1, 2, 3,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
gtk_table_attach (GTK_TABLE (table),
gtk_check_button_new_with_label ("Sedentary"),
1, 2, 0, 1,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
gtk_table_attach (GTK_TABLE (table),
gtk_check_button_new_with_label ("Nocturnal"),
1, 2, 1, 2,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
gtk_table_attach (GTK_TABLE (table),
gtk_check_button_new_with_label ("Compulsive"),
1, 2, 2, 3,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Green");
gtk_table_attach (GTK_TABLE (table),
radio_button,
0, 1, 1, 2,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Blue"),
gtk_table_attach (GTK_TABLE (table),
radio_button,
0, 1, 2, 3,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
hbox = gtk_hbox_new (FALSE, 0);
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), "<i>Entry: </i>");
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
entry = gtk_entry_new ();
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
gtk_table_attach (GTK_TABLE (table),
hbox,
0, 1, 3, 4,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
return table;
}
static gboolean
on_alpha_drawing_expose (GtkWidget *widget,
GdkEventExpose *expose)
{
int x = widget->allocation.x;
int y = widget->allocation.y;
int width = widget->allocation.width;
int height = widget->allocation.height;
GdkPixbuf *pixbuf;
guchar *buffer;
guchar *p;
int i, j;
buffer = g_malloc (64 * 64 * 4);
gdk_draw_rectangle (widget->window, widget->style->black_gc, FALSE,
x, y,
width - 1, height - 1);
p = buffer;
for (i = 0; i < 64; i++) {
for (j = 0; j < 64; j++) {
*(p++) = i * 4 + 3;
*(p++) = 0;
*(p++) = j + 4 + 3;
*(p++) = MIN (255, ((32 - i) * (32 - i) + (32 - j) * (32 - j)) / 8);
}
}
p++;
gdk_draw_rgb_32_image (widget->window, widget->style->black_gc,
x + 18, y + (height - 64) /2,
64, 64, GDK_RGB_DITHER_NORMAL, buffer, 64 * 4);
pixbuf = gdk_pixbuf_new_from_data (buffer, GDK_COLORSPACE_RGB, TRUE,
8, 64, 64, 4 * 64, NULL, NULL);
gdk_draw_pixbuf (widget->window, widget->style->black_gc, pixbuf,
0, 0, x + width - 18 - 64, y + (height - 64) /2,
64, 64, GDK_RGB_DITHER_NORMAL, 0, 0);
g_object_unref (pixbuf);
g_free (buffer);
return FALSE;
}
static GtkWidget *
build_alpha_drawing ()
{
GtkWidget *hbox;
hbox = gtk_hbox_new (FALSE, 0);
gtk_widget_set_size_request (hbox, 100, 100);
g_signal_connect (hbox, "expose-event",
G_CALLBACK (on_alpha_drawing_expose), NULL);
return hbox;
}
static void
on_alpha_screen_changed (GtkWidget *widget,
GdkScreen *old_screen,
GtkWidget *label)
{
GdkScreen *screen = gtk_widget_get_screen (widget);
GdkColormap *colormap = gdk_screen_get_rgba_colormap (screen);
if (!colormap)
{
colormap = gdk_screen_get_rgb_colormap (screen);
gtk_label_set_markup (GTK_LABEL (label), "<b>Screen doesn't support alpha</b>");
}
else
{
gtk_label_set_markup (GTK_LABEL (label), "<b>Screen supports alpha</b>");
}
gtk_widget_set_colormap (widget, colormap);
}
void
create_alpha_window (GtkWidget *widget)
{
static GtkWidget *window;
if (!window)
{
GtkWidget *vbox;
GtkWidget *label;
window = gtk_dialog_new_with_buttons ("Alpha Window",
GTK_WINDOW (gtk_widget_get_toplevel (widget)), 0,
GTK_STOCK_CLOSE, 0,
NULL);
gtk_widget_set_app_paintable (window, TRUE);
g_signal_connect (window, "expose-event",
G_CALLBACK (on_alpha_window_expose), NULL);
vbox = gtk_vbox_new (FALSE, 8);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
TRUE, TRUE, 0);
label = gtk_label_new (NULL);
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), build_alpha_widgets (), TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), build_alpha_drawing (), TRUE, TRUE, 0);
on_alpha_screen_changed (window, NULL, label);
g_signal_connect (window, "screen-changed",
G_CALLBACK (on_alpha_screen_changed), label);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed),
&window);
}
if (!GTK_WIDGET_VISIBLE (window))
gtk_widget_show_all (window);
else
gtk_widget_destroy (window);
}
/*
* Big windows and guffaw scrolling
*/
@ -12860,6 +13112,7 @@ struct {
gboolean do_not_benchmark;
} buttons[] =
{
{ "alpha window", create_alpha_window },
#ifdef G_OS_WIN32
/* dog slow on NT, no working at all on 9x */
{ "big windows", create_big_windows, TRUE },