diff options
-rw-r--r-- | ChangeLog | 27 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 27 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 27 | ||||
-rw-r--r-- | docs/reference/gdk/gdk-sections.txt | 2 | ||||
-rw-r--r-- | gdk/gdk.symbols | 2 | ||||
-rw-r--r-- | gdk/gdkrgb.c | 92 | ||||
-rw-r--r-- | gdk/gdkscreen.h | 3 | ||||
-rw-r--r-- | gdk/linux-fb/gdkscreen-fb.c | 16 | ||||
-rw-r--r-- | gdk/win32/gdkscreen-win32.c | 16 | ||||
-rw-r--r-- | gdk/x11/gdkcolor-x11.c | 12 | ||||
-rw-r--r-- | gdk/x11/gdkdrawable-x11.c | 24 | ||||
-rw-r--r-- | gdk/x11/gdkscreen-x11.c | 68 | ||||
-rw-r--r-- | gdk/x11/gdkscreen-x11.h | 4 | ||||
-rw-r--r-- | gdk/x11/gdkvisual-x11.c | 19 | ||||
-rw-r--r-- | tests/testgtk.c | 253 |
15 files changed, 559 insertions, 33 deletions
@@ -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. diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 50564b3240..005494f7fd 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -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. diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 50564b3240..005494f7fd 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -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. diff --git a/docs/reference/gdk/gdk-sections.txt b/docs/reference/gdk/gdk-sections.txt index 10f911d383..db2f0e264f 100644 --- a/docs/reference/gdk/gdk-sections.txt +++ b/docs/reference/gdk/gdk-sections.txt @@ -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 diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols index a7883569be..93448836dc 100644 --- a/gdk/gdk.symbols +++ b/gdk/gdk.symbols @@ -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 diff --git a/gdk/gdkrgb.c b/gdk/gdkrgb.c index e8c1e53602..d78584216d 100644 --- a/gdk/gdkrgb.c +++ b/gdk/gdkrgb.c @@ -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; diff --git a/gdk/gdkscreen.h b/gdk/gdkscreen.h index f527099f44..5a27cbe232 100644 --- a/gdk/gdkscreen.h +++ b/gdk/gdkscreen.h @@ -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); diff --git a/gdk/linux-fb/gdkscreen-fb.c b/gdk/linux-fb/gdkscreen-fb.c index fd237c3fb4..ff19caaa98 100644 --- a/gdk/linux-fb/gdkscreen-fb.c +++ b/gdk/linux-fb/gdkscreen-fb.c @@ -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) { diff --git a/gdk/win32/gdkscreen-win32.c b/gdk/win32/gdkscreen-win32.c index a68d24c2c0..45e151a377 100644 --- a/gdk/win32/gdkscreen-win32.c +++ b/gdk/win32/gdkscreen-win32.c @@ -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) { diff --git a/gdk/x11/gdkcolor-x11.c b/gdk/x11/gdkcolor-x11.c index 9322e9391b..95fffe82b7 100644 --- a/gdk/x11/gdkcolor-x11.c +++ b/gdk/x11/gdkcolor-x11.c @@ -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) + diff --git a/gdk/x11/gdkdrawable-x11.c b/gdk/x11/gdkdrawable-x11.c index 71e02909f5..7922aaeee0 100644 --- a/gdk/x11/gdkdrawable-x11.c +++ b/gdk/x11/gdkdrawable-x11.c @@ -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 diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c index 3ab2bfc8af..1dbff67c2e 100644 --- a/gdk/x11/gdkscreen-x11.c +++ b/gdk/x11/gdkscreen-x11.c @@ -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; @@ -372,6 +378,68 @@ gdk_screen_get_monitor_geometry (GdkScreen *screen, } /** + * 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. * @returns: an Xlib <type>Screen*</type> diff --git a/gdk/x11/gdkscreen-x11.h b/gdk/x11/gdkscreen-x11.h index fddc28dd04..aa08dca15b 100644 --- a/gdk/x11/gdkscreen-x11.h +++ b/gdk/x11/gdkscreen-x11.h @@ -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; diff --git a/gdk/x11/gdkvisual-x11.c b/gdk/x11/gdkvisual-x11.c index 95b2df7a2a..94d3687a11 100644 --- a/gdk/x11/gdkvisual-x11.c +++ b/gdk/x11/gdkvisual-x11.c @@ -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) diff --git a/tests/testgtk.c b/tests/testgtk.c index 22919bd23c..b4480be8d4 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -148,6 +148,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 }, |