From 1f7f29e059f4e835a33c94a5bc88d43f718429cc Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Fri, 27 Aug 2004 02:17:49 +0000 Subject: [PATCH] move the have_xrender variable initialization up in the file since it can 2004-08-26 Havoc Pennington * configure.in: move the have_xrender variable initialization up in the file since it can be set as part of composite check 2004-08-19 Havoc Pennington Fixes from Rich Wareham * src/display.h (struct _MetaDisplay): add render extension check to the display * src/display.c: check for render * configure.in: don't build compositing manager by default, don't want any nasty surprises; check for render separately from compositing manager * src/frame.c: use an ARGB visual when available for the window frame, so we can be all cool-ass --- ChangeLog | 21 +++++++++++++ configure.in | 43 +++++++++++++++++++++++++- src/compositor.c | 23 ++------------ src/display.c | 38 +++++++++++++++++++++++ src/display.h | 24 ++++++++++++--- src/frame.c | 79 ++++++++++++++++++++++++++++++++++++++++++++---- src/frames.c | 40 ++++++++++++++++++------ src/theme.c | 2 +- 8 files changed, 229 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0025934f..60648f274 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2004-08-26 Havoc Pennington + + * configure.in: move the have_xrender variable initialization up + in the file since it can be set as part of composite check + +2004-08-19 Havoc Pennington + + Fixes from Rich Wareham + + * src/display.h (struct _MetaDisplay): add render extension check + to the display + + * src/display.c: check for render + + * configure.in: don't build compositing manager by default, don't + want any nasty surprises; check for render separately from + compositing manager + + * src/frame.c: use an ARGB visual when available for the window + frame, so we can be all cool-ass + 2004-08-25 Elijah Newren Make dialogs that Metacity shows follow focus-stealing-prevention diff --git a/configure.in b/configure.in index 597882f6e..e1f4637ee 100644 --- a/configure.in +++ b/configure.in @@ -131,6 +131,8 @@ AC_ARG_ENABLE(compositor, [ --disable-compositor disable metacity AC_ARG_ENABLE(xsync, [ --disable-xsync disable metacity's use of the XSync extension],,enable_xsync=auto) +AC_ARG_ENABLE(render, [ --disable-render disable metacity's use of the RENDER extension],,enable_render=auto) + AC_ARG_ENABLE(shape, [ --disable-shape disable metacity's use of the shaped window extension],,enable_shape=auto) ## try definining HAVE_BACKTRACE @@ -179,6 +181,10 @@ else echo "Building without libstartup-notification" fi +## init this, it gets set either in the compositor check below +## or the render-specific check later +have_xrender=no + XCOMPOSITE_VERSION=1.0 AC_MSG_CHECKING([Xcomposite >= $XCOMPOSITE_VERSION]) if $PKG_CONFIG --atleast-version $XCOMPOSITE_VERSION xcomposite; then @@ -192,7 +198,8 @@ if test x$enable_compositor = xyes; then have_xcomposite=yes echo "CompositeExt support forced on" elif test x$enable_compositor = xauto; then - true + echo "Not building compositing manager by default now, must enable explicitly to get it. And it doesn't work, so don't bother unless you want to hack on it..." + have_xcomposite=no else have_xcomposite=no fi @@ -201,10 +208,43 @@ if test x$have_xcomposite = xyes; then echo "Building with CompositeExt" METACITY_PC_MODULES="$METACITY_PC_MODULES xcomposite >= $XCOMPOSITE_VERSION xfixes xrender xdamage" AC_DEFINE(HAVE_COMPOSITE_EXTENSIONS, , [Building with compositing manager support]) + + ## force on render also + have_xrender=yes else echo "Building without compositing manager" fi +## if no compositor, still possibly enable render +if test x$have_xcomposite = xno; then + XRENDER_VERSION=0.0 + AC_MSG_CHECKING([xrender >= $XRENDER_VERSION]) + if $PKG_CONFIG --atleast-version $XRENDER_VERSION xrender; then + have_xrender=yes + else + have_xrender=no + fi + AC_MSG_RESULT($have_xrender) + + if test x$enable_render = xyes; then + have_xrender=yes + echo "Render support forced on" + elif test x$enable_render = xauto; then + true + else + have_xrender=no + fi + + if test x$have_xrender = xyes; then + echo "Building with Render" + METACITY_PC_MODULES="$METACITY_PC_MODULES xrender >= $XRENDER_VERSION" + fi +fi ## have_composite + +if test x$have_xrender = xyes; then + AC_DEFINE(HAVE_RENDER, , [Building with Render extension support]) +fi + PKG_CHECK_MODULES(METACITY, $METACITY_PC_MODULES) AC_PATH_XTRA @@ -439,6 +479,7 @@ metacity-$VERSION: Shape extension: ${found_shape} Resize-and-rotate: ${found_randr} Xsync: ${found_xsync} + Render: ${have_xrender} Deprecated config dialog: ${enable_config_dialog} " echo "This is the UNSTABLE branch of metacity, use 2.8.1.x for stable (gnome-2-6 branch in CVS)" diff --git a/src/compositor.c b/src/compositor.c index df887a328..6e7a17e5b 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1,7 +1,7 @@ /* Metacity compositing manager */ /* - * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003, 2004 Red Hat, Inc. * Copyright (C) 2003 Keith Packard * * This program is free software; you can redistribute it and/or @@ -82,8 +82,6 @@ struct MetaCompositor int damage_event_base; int fixes_error_base; int fixes_event_base; - int render_error_base; - int render_event_base; GHashTable *window_hash; @@ -94,7 +92,6 @@ struct MetaCompositor guint have_composite : 1; guint have_damage : 1; guint have_fixes : 1; - guint have_render : 1; }; #ifdef HAVE_COMPOSITE_EXTENSIONS @@ -176,25 +173,11 @@ meta_compositor_new (MetaDisplay *display) meta_topic (META_DEBUG_COMPOSITOR, "Fixes extension event base %d error base %d\n", compositor->fixes_event_base, compositor->fixes_error_base); - - if (!XRenderQueryExtension (display->xdisplay, - &compositor->render_event_base, - &compositor->render_error_base)) - { - compositor->render_event_base = 0; - compositor->render_error_base = 0; - } - else - compositor->have_render = TRUE; - - meta_topic (META_DEBUG_COMPOSITOR, "Render extension event base %d error base %d\n", - compositor->render_event_base, - compositor->render_error_base); if (!(compositor->have_composite && compositor->have_fixes && - compositor->have_render && - compositor->have_damage)) + compositor->have_damage && + META_DISPLAY_HAS_RENDER (compositor->display))) { meta_topic (META_DEBUG_COMPOSITOR, "Failed to find all extensions needed for compositing manager, disabling compositing manager\n"); g_assert (!compositor->enabled); diff --git a/src/display.c b/src/display.c index 4c1890d49..d8f11225b 100644 --- a/src/display.c +++ b/src/display.c @@ -53,6 +53,9 @@ #ifdef HAVE_SHAPE #include #endif +#ifdef HAVE_RENDER +#include +#endif #ifdef HAVE_XKB #include #endif @@ -507,6 +510,8 @@ meta_display_open (const char *name) #ifdef HAVE_XSYNC { int major, minor; + + display->have_xsync = FALSE; display->xsync_error_base = 0; display->xsync_event_base = 0; @@ -524,6 +529,9 @@ meta_display_open (const char *name) display->xsync_error_base = 0; display->xsync_event_base = 0; } + else + display->have_xsync = TRUE; + meta_verbose ("Attempted to init Xsync, found version %d.%d error base %d event base %d\n", major, minor, display->xsync_error_base, @@ -536,6 +544,8 @@ meta_display_open (const char *name) #ifdef HAVE_SHAPE { + display->have_shape = FALSE; + display->shape_error_base = 0; display->shape_event_base = 0; @@ -546,6 +556,9 @@ meta_display_open (const char *name) display->shape_error_base = 0; display->shape_event_base = 0; } + else + display->have_shape = TRUE; + meta_verbose ("Attempted to init Shape, found error base %d event base %d\n", display->shape_error_base, display->shape_event_base); @@ -554,6 +567,31 @@ meta_display_open (const char *name) meta_verbose ("Not compiled with Shape support\n"); #endif /* !HAVE_SHAPE */ +#ifdef HAVE_RENDER + { + display->have_render = FALSE; + + display->render_error_base = 0; + display->render_event_base = 0; + + if (!XRenderQueryExtension (display->xdisplay, + &display->render_event_base, + &display->render_error_base)) + { + display->render_error_base = 0; + display->render_event_base = 0; + } + else + display->have_render = TRUE; + + meta_verbose ("Attempted to init Render, found error base %d event base %d\n", + display->render_error_base, + display->render_event_base); + } +#else /* HAVE_RENDER */ + meta_verbose ("Not compiled with Render support\n"); +#endif /* !HAVE_RENDER */ + /* Create the leader window here. Set its properties and * use the timestamp from one of the PropertyNotify events * that will follow. diff --git a/src/display.h b/src/display.h index 8b93253d4..cfc3b980c 100644 --- a/src/display.h +++ b/src/display.h @@ -316,17 +316,33 @@ struct _MetaDisplay #ifdef HAVE_XSYNC int xsync_event_base; int xsync_error_base; -#define META_DISPLAY_HAS_XSYNC(display) ((display)->xsync_event_base != 0) -#else -#define META_DISPLAY_HAS_XSYNC(display) FALSE #endif #ifdef HAVE_SHAPE int shape_event_base; int shape_error_base; -#define META_DISPLAY_HAS_SHAPE(display) ((display)->shape_event_base != 0) +#endif +#ifdef HAVE_RENDER + int render_event_base; + int render_error_base; +#endif +#ifdef HAVE_XSYNC + unsigned int have_xsync : 1; +#define META_DISPLAY_HAS_XSYNC(display) ((display)->have_xsync) +#else +#define META_DISPLAY_HAS_XSYNC(display) FALSE +#endif +#ifdef HAVE_SHAPE + unsigned int have_shape : 1; +#define META_DISPLAY_HAS_SHAPE(display) ((display)->have_shape) #else #define META_DISPLAY_HAS_SHAPE(display) FALSE #endif +#ifdef HAVE_RENDER + unsigned int have_render : 1; +#define META_DISPLAY_HAS_RENDER(display) ((display)->have_render) +#else +#define META_DISPLAY_HAS_RENDER(display) FALSE +#endif }; gboolean meta_display_open (const char *name); diff --git a/src/frame.c b/src/frame.c index a699d1845..ca600339d 100644 --- a/src/frame.c +++ b/src/frame.c @@ -2,7 +2,7 @@ /* * Copyright (C) 2001 Havoc Pennington - * Copyright (C) 2003 Red Hat, Inc. + * Copyright (C) 2003, 2004 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -26,6 +26,12 @@ #include "errors.h" #include "keybindings.h" +#include + +#ifdef HAVE_RENDER +#include +#endif + #define EVENT_MASK (SubstructureRedirectMask | \ StructureNotifyMask | SubstructureNotifyMask | \ ExposureMask | \ @@ -34,6 +40,60 @@ EnterWindowMask | LeaveWindowMask | \ FocusChangeMask | \ ColormapChangeMask) +static Visual* +find_argb_visual (MetaDisplay *display, + int scr) +{ +#ifdef HAVE_RENDER + XVisualInfo *xvi; + XVisualInfo template; + int nvi; + int i; + XRenderPictFormat *format; + Visual *visual; + + if (!META_DISPLAY_HAS_RENDER (display)) + return NULL; + + template.screen = scr; + template.depth = 32; + template.class = TrueColor; + xvi = XGetVisualInfo (display->xdisplay, + VisualScreenMask | + VisualDepthMask | + VisualClassMask, + &template, + &nvi); + if (!xvi) + return 0; + + visual = NULL; + + for (i = 0; i < nvi; i++) + { + format = XRenderFindVisualFormat (display->xdisplay, xvi[i].visual); + if (format->type == PictTypeDirect && format->direct.alphaMask) + { + visual = xvi[i].visual; + break; + } + } + + XFree (xvi); + + if (visual) + meta_topic (META_DEBUG_COMPOSITOR, + "Found ARGB visual 0x%lx\n", + (long) visual->visualid); + else + meta_topic (META_DEBUG_COMPOSITOR, + "No ARGB visual found\n"); + + return visual; +#else /* RENDER */ + return NULL; +#endif /* !RENDER */ +} void meta_window_ensure_frame (MetaWindow *window) @@ -77,13 +137,20 @@ meta_window_ensure_frame (MetaWindow *window) /* Default depth/visual handles clients with weird visuals; they can * always be children of the root depth/visual obviously, but * e.g. DRI games can't be children of a parent that has the same - * visual as the client. + * visual as the client. NULL means default visual. + * + * We look for an ARGB visual if we can find one, otherwise use + * the default of NULL. + */ + + /* Special case for depth 32 windows (assumed to be ARGB), + * we use the window's visual */ - - visual = 0; - /* XXX special case for depth 32 windows (assumed to be ARGB) */ if (window->depth == 32) - visual = window->xvisual; + visual = window->xvisual; + else + visual = find_argb_visual(window->display, + window->screen->number); frame->xwindow = meta_ui_create_frame_window (window->screen->ui, window->display->xdisplay, diff --git a/src/frames.c b/src/frames.c index d1622cbe2..409f2a397 100644 --- a/src/frames.c +++ b/src/frames.c @@ -268,10 +268,13 @@ queue_recalc_func (gpointer key, gpointer value, gpointer data) /* If a resize occurs it will cause a redraw, but the * resize may not actually be needed so we always redraw - * in case of color change. + * in case of color change. Don't change color if this is + * an ARGB visual */ - gtk_style_set_background (GTK_WIDGET (frames)->style, - frame->window, GTK_STATE_NORMAL); + if (gdk_window_get_visual (frame->window)->depth != 32) + gtk_style_set_background (GTK_WIDGET (frames)->style, + frame->window, GTK_STATE_NORMAL); + gdk_window_invalidate_rect (frame->window, NULL, FALSE); meta_core_queue_frame_resize (gdk_display, frame->xwindow); @@ -313,10 +316,14 @@ queue_draw_func (gpointer key, gpointer value, gpointer data) /* If a resize occurs it will cause a redraw, but the * resize may not actually be needed so we always redraw - * in case of color change. + * in case of color change. Only redraw if it is not + * an ARGB visual however since we always want background + * in this case to be transparent. */ - gtk_style_set_background (GTK_WIDGET (frames)->style, - frame->window, GTK_STATE_NORMAL); + if (gdk_window_get_visual (frame->window)->depth != 32) + gtk_style_set_background (GTK_WIDGET (frames)->style, + frame->window, GTK_STATE_NORMAL); + gdk_window_invalidate_rect (frame->window, NULL, FALSE); } @@ -469,6 +476,7 @@ meta_frames_manage_window (MetaFrames *frames, GdkWindow *window) { MetaUIFrame *frame; + GdkColor col; g_assert (window); @@ -477,8 +485,20 @@ meta_frames_manage_window (MetaFrames *frames, frame->window = window; gdk_window_set_user_data (frame->window, frames); - gtk_style_set_background (GTK_WIDGET (frames)->style, - frame->window, GTK_STATE_NORMAL); + + /* Set the window background to the current style if not ARGB and + * transparent otherwise + */ + if (gdk_window_get_visual (frame->window)->depth != 32) + { + gtk_style_set_background (GTK_WIDGET (frames)->style, + frame->window, GTK_STATE_NORMAL); + } + else + { + col.pixel = 0; + gdk_window_set_background (window, &col); + } /* Don't set event mask here, it's in frame.c */ @@ -613,7 +633,9 @@ meta_frames_reset_bg (MetaFrames *frames, frame = meta_frames_lookup_window (frames, xwindow); - gtk_style_set_background (widget->style, frame->window, GTK_STATE_NORMAL); + if (gdk_window_get_visual (frame->window)->depth != 32) + gtk_style_set_background (GTK_WIDGET (frames)->style, + frame->window, GTK_STATE_NORMAL); } static void diff --git a/src/theme.c b/src/theme.c index 25e569575..7ed48277f 100644 --- a/src/theme.c +++ b/src/theme.c @@ -2663,7 +2663,7 @@ get_gc_for_primitive (GtkWidget *widget, meta_color_spec_render (color_spec, widget, &color); values.foreground = color; - gdk_rgb_find_color (widget->style->colormap, &values.foreground); + gdk_rgb_find_color (gdk_drawable_get_colormap (drawable), &values.foreground); values.line_width = line_width; gc = gdk_gc_new_with_values (drawable, &values,