patches/control-center-03-compiz-integration.diff
author yippi
Mon, 27 Sep 2010 21:07:51 +0000
changeset 20108 51df67ca9307
parent 17569 c00759bc4834
child 20370 f2c879959270
permissions -rw-r--r--
I had these modules listed as being owned by me, but they are really owned by wangke, correcting.

diff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' gnome-control-center-2.28.0/capplets/appearance/Makefile.am ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/Makefile.am
--- gnome-control-center-2.28.0/capplets/appearance/Makefile.am	2009-07-16 16:33:13.000000000 +0200
+++ ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/Makefile.am	2009-10-16 09:52:28.248513437 +0200
@@ -9,6 +9,8 @@ gnome_appearance_properties_SOURCES = \
 	appearance.h \
 	appearance-desktop.c \
 	appearance-desktop.h \
+	appearance-effects.c\
+	appearance-effects.h\
 	appearance-font.c \
 	appearance-font.h \
 	appearance-main.c \
diff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' gnome-control-center-2.28.0/capplets/appearance/appearance-effects.c ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/appearance-effects.c
--- gnome-control-center-2.28.0/capplets/appearance/appearance-effects.c	1970-01-01 01:00:00.000000000 +0100
+++ ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/appearance-effects.c	2009-10-16 09:52:50.817685824 +0200
@@ -0,0 +1,1234 @@
+/*
+ * Copyright (C) 2007 Canonical
+ * Written by Michael Vogt <[email protected]>
+ * and Mirco Müller <[email protected]>
+ * All Rights Reserved
+ *
+ * Based on desktop-effects.c:
+ *   Desktop Effects. A preference panel for compiz.
+ *   Copyright (C) 2006   Red Hat, Inc.
+ * Author: Soren Sandmann ([email protected]) *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <gdk/gdkx.h>
+#include <X11/extensions/Xcomposite.h>
+#include <math.h>
+
+#include "appearance.h"
+
+#include "gconf-property-editor.h"
+
+typedef enum {
+	COMPIZ,
+	METACITY
+} WindowManager;
+
+#define WINDOW_MANAGER_KEY "/desktop/gnome/session/required_components/windowmanager"
+#define COMPIZ_BIN	   "compiz"
+#define METACITY_BIN	   "metacity"
+#define REVERT_COUNT	   40
+#define SECONDS_WE_WILL_WAIT_FOR_COMPIZ_TO_START 8
+#define PLUGIN_LIST_KEY	   "/apps/compiz/general/allscreens/options/active_plugins"
+#define NUM_WORKSPACES	   "/apps/metacity/general/num_workspaces"
+
+/* helper structure to pass pager data around */
+typedef struct _TraversalChunk {
+	GConfClient *client;
+	GArray	    *numRowsArray;
+	gint	    rows;
+} TraversalChunk;
+
+/* possible effects level */
+enum {
+	NO_EFFECTS, 
+	NORMAL_EFFECTS, 
+	EXTRA_EFFECTS, 
+	CUSTOM_EFFECTS
+};
+
+/* radio-button names in glade-file */
+static const char *effect_choices[] =  {
+	"no_effects_button",
+	"normal_effects_button", 
+	"extra_effects_button",
+	"custom_effects_button"
+};
+
+/* plugin-set for extra-effects level */
+static const gchar* extra_effects[] = {
+
+"dbus",
+"move",
+"place",
+"png",
+"regex",
+"resize",
+"svg",
+"water",
+"imgjpeg",
+"mousepoll",
+"resizeinfo",
+"session",
+"text",
+"thumbnail",
+"workarounds",
+"firepaint",
+"shelf",
+"decoration",
+"wobbly",
+"animation",
+"shift",
+"fade",
+"group",
+"cube",
+"rotate",
+"scale",
+"3d",
+"cubeaddon",
+"scalefilter",
+"expo",
+"ezoom",
+NULL
+};
+
+static gboolean
+check_compiz (void)
+{
+	return g_file_test ("/usr/bin/compiz", G_FILE_TEST_IS_EXECUTABLE);
+}
+
+static gboolean
+check_ccsm (void)
+{
+	return g_file_test ("/usr/bin/ccsm", G_FILE_TEST_IS_EXECUTABLE);
+}
+static void
+run_ccsm (GtkButton *widget,
+	  gpointer  data)
+{
+	g_spawn_command_line_async ("/usr/bin/ccsm", NULL);
+}
+static gboolean
+check_compiz_configure (void)
+{
+	return g_file_test ("/usr/lib/compiz/compiz-configure", G_FILE_TEST_IS_EXECUTABLE);
+}
+static void
+run_compiz_configure (GtkButton *widget,
+		      gpointer  data)
+{
+	g_spawn_command_line_async ("/usr/lib/compiz/compiz-configure", NULL);
+}
+
+
+static GSList *
+get_plugins (AppearanceData *app,
+	     GError	    **err)
+{
+	return gconf_client_get_list (app->client,
+				      PLUGIN_LIST_KEY,
+				      GCONF_VALUE_STRING,
+				      err);
+}
+
+static gboolean
+contains_string (GSList	     *plugins,
+		 const gchar *needle)
+{
+	GSList *slist;
+
+	for (slist = plugins; slist != NULL; slist = slist->next)
+	{
+		const char *s = slist->data;
+
+		if (s && strcmp (s, needle) == 0)
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
+
+static void
+show_info (const char *text)
+{
+	GtkWidget *dialog;
+
+	dialog = gtk_message_dialog_new (NULL,
+					 GTK_DIALOG_MODAL,
+					 GTK_MESSAGE_INFO,
+					 GTK_BUTTONS_OK,
+					 text);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+}
+
+static gchar*
+get_string_value (GConfClient* client,
+		  const gchar* key)
+{
+	gchar  *value = NULL;
+	GError *error = NULL;
+
+	g_assert (client != NULL);
+	g_assert (key    != NULL);
+
+	value = gconf_client_get_string (client, key, &error);
+	if (error)
+		return NULL;
+
+	return value;
+}
+
+static gint
+get_int_value (GConfClient* client,
+	       const gchar* key)
+{
+	gint	value = 0;
+	GError*	error = NULL;
+
+	g_assert (client != NULL);
+	g_assert (key    != NULL);
+
+	value = gconf_client_get_int (client, key, &error);
+	if (error)
+		return 0;
+
+	return value;
+}
+
+static void
+check_for_wnck_entry (gpointer data,
+		      gpointer user_data)
+{
+	gchar		*appletId	= (gchar*) data;
+	TraversalChunk	*chunk		= (TraversalChunk*) user_data;
+	GString		*propertyPath	= NULL;
+	gchar		*value		= NULL;
+	gint		rows		= 0;
+	gint		position	= 0;
+
+	/* get bonobo-id of applet */
+	propertyPath = g_string_new ("/apps/panel/applets/");
+	propertyPath = g_string_append (propertyPath, appletId);
+	propertyPath = g_string_append (propertyPath, "/bonobo_iid");
+	value = get_string_value (chunk->client, propertyPath->str);
+
+	/* just exit if no bonobo-id was found */
+	if (!value)
+	{
+		g_string_free (propertyPath, TRUE);
+		return;
+	}
+
+	/* test if it is actually a switcher */
+	if (!g_ascii_strncasecmp (value,
+				  "OAFIID:GNOME_WorkspaceSwitcherApplet",
+				  36))
+	{
+		/* assemble new gconf-path for num_rows gconf-key */
+		g_string_free (propertyPath, TRUE);
+		propertyPath = g_string_new ("/apps/panel/applets/");
+		propertyPath = g_string_append (propertyPath, appletId);
+		propertyPath = g_string_append (propertyPath, "/position");
+
+		/* get the value of position */
+		position = get_int_value (chunk->client, propertyPath->str);
+
+		if (position > 1)
+		{
+			/* assemble new gconf-path for num_rows gconf-key */
+			g_string_free (propertyPath, TRUE);
+			propertyPath = g_string_new ("/apps/panel/applets/");
+			propertyPath = g_string_append (propertyPath, appletId);
+			propertyPath = g_string_append (propertyPath,
+							"/prefs/num_rows");
+
+			/* get the value of rows */
+			rows = get_int_value (chunk->client, propertyPath->str);
+
+			if (!chunk->numRowsArray)
+				chunk->numRowsArray = g_array_new (TRUE,
+								   TRUE,
+								   sizeof (gint));
+
+			g_array_append_val (chunk->numRowsArray, rows);
+		}
+	}
+
+	g_string_free (propertyPath, TRUE);
+}
+
+gboolean
+set_int_value (GConfClient *client,
+               const gchar *key,
+               gint        value)
+{
+	gboolean result = FALSE;
+	GError   *error = NULL;
+
+	g_assert (client != NULL);
+	g_assert (key    != NULL);
+
+	result = gconf_client_set_int (client,
+				       key,
+				       value,
+				       &error);
+
+	if (error)
+		return FALSE;
+
+	return result;
+}
+
+static void
+set_wnck_entry (gpointer data,
+                gpointer user_data)
+{
+	gchar		*appletId	= (gchar*) data;
+	TraversalChunk	*chunk		= (TraversalChunk*) user_data;
+	GString		*propertyPath	= NULL;
+	gchar		*value		= NULL;
+	gint		position	= 0;
+
+	/* get bonobo-id of applet */
+	propertyPath = g_string_new ("/apps/panel/applets/");
+	propertyPath = g_string_append (propertyPath, appletId);
+	propertyPath = g_string_append (propertyPath, "/bonobo_iid");
+	value = get_string_value (chunk->client, propertyPath->str);
+
+	/* just exit if no bonobo-id was found */
+	if (!value)
+	{
+		g_string_free (propertyPath, TRUE);
+		return;
+	}
+
+	/* test if it is actually a switcher */
+	if (!g_ascii_strncasecmp (value,
+				  "OAFIID:GNOME_WorkspaceSwitcherApplet",
+				  36))
+	{
+		/* assemble new gconf-path for applets position gconf-key */
+		g_string_free (propertyPath, TRUE);
+		propertyPath = g_string_new ("/apps/panel/applets/");
+		propertyPath = g_string_append (propertyPath, appletId);
+		propertyPath = g_string_append (propertyPath, "/position");
+
+		/* get the value of position */
+		position = get_int_value (chunk->client, propertyPath->str);
+
+		/* not the best way to test, if this applet is really active */
+		if (position > 1)
+		{
+			/* assemble new gconf-path for num_rows gconf-key */
+			g_string_free (propertyPath, TRUE);
+			propertyPath = g_string_new ("/apps/panel/applets/");
+			propertyPath = g_string_append (propertyPath, appletId);
+			propertyPath = g_string_append (propertyPath,
+							"/prefs/num_rows");
+
+			/* set the value of rows */
+			set_int_value (chunk->client,
+				       propertyPath->str,
+				       chunk->rows);
+		}
+	}
+
+	/* cleanup */
+	g_string_free (propertyPath, TRUE);
+}
+
+static gint
+get_pager_num_rows (GConfClient *client)
+{
+	GSList         *idList = NULL;
+	TraversalChunk *chunk  = NULL;
+	gint           rows    = 0;
+
+	/* get ids of all used applets */
+	idList = gconf_client_get_list (client,
+					"/apps/panel/general/applet_id_list",
+					GCONF_VALUE_STRING,
+					NULL);
+
+	if (!idList)
+		return 1;
+
+	/* create and initialize helper-structure */
+	chunk = g_new0 (TraversalChunk, 1);
+	if (!chunk)
+	{
+		g_slist_free (idList);
+		return 1;
+	}
+
+	chunk->client = client;
+
+	/* search list of applets for wnck-applet */
+	g_slist_foreach (idList,
+			 check_for_wnck_entry,
+			 (gpointer) chunk);
+
+	if (chunk->numRowsArray == NULL)
+		rows = 1;
+	else
+		rows = g_array_index (chunk->numRowsArray, gint, 0);
+
+	/* clean up */
+	g_slist_free (idList);
+	g_array_free (chunk->numRowsArray, TRUE);
+	g_free (chunk);
+
+	return rows;
+}
+
+/* sets the number of rows of the first pager-applet found */
+void static
+set_pager_num_rows (GConfClient *client,
+                    gint        rows)
+{
+	GSList         *idList = NULL;
+	TraversalChunk *chunk  = NULL;
+
+	/* get ids of all used applets */
+	idList = gconf_client_get_list (client,
+					"/apps/panel/general/applet_id_list",
+					GCONF_VALUE_STRING,
+					NULL);
+
+	/* if nothing is found at least return 1 to avoid a div. by 0 later */
+	if (!idList)
+		return;
+
+	/* create and initialize helper-structure */
+	chunk = g_new0 (TraversalChunk, 1);
+	if (!chunk)
+	{
+		g_slist_free (idList);
+		return;
+	}
+
+	chunk->client = client;
+	chunk->rows = rows;
+
+	/* search list of applets for wnck-applet */
+	g_slist_foreach (idList,
+			 set_wnck_entry,
+			 (gpointer) chunk);
+
+	/* clean up */
+	g_slist_free (idList);
+	g_array_free (chunk->numRowsArray, TRUE);
+	g_free (chunk);
+}
+
+static void
+apply_settings (AppearanceData	*app,
+		gboolean	effects_enabled)
+{
+	const char *str = effects_enabled? COMPIZ_BIN : METACITY_BIN;
+	char	   *session_file;
+	gint	   vsize;
+	gint	   hsize;
+	gint	   workspaces;
+	gint	   rows;
+
+	gconf_client_set_string (app->client,
+				 WINDOW_MANAGER_KEY,
+				 str,
+				 NULL);
+
+	session_file = g_build_filename (g_get_home_dir (),
+					 ".gnome2",
+					 "session",
+					 NULL);
+
+	g_unlink (session_file);
+	g_free (session_file);
+
+	/* here the whole logic for mapping any N:M workspace-layout from
+	 * metacity to compiz or vice versa is handled, currently only
+	 * implemented for one-screen setups */
+	if (effects_enabled)
+	{
+		workspaces = get_int_value (app->client,
+				            "/apps/metacity/general/num_workspaces");
+		rows = get_pager_num_rows (app->client);
+		set_int_value (app->client,
+			       "/apps/compiz/general/screen0/options/vsize",
+			       rows);
+		set_int_value (app->client,
+			       "/apps/compiz/general/screen0/options/hsize",
+			       (gint) ceilf ((gfloat) workspaces / (gfloat) rows));
+		set_pager_num_rows (app->client, 1);
+	}
+	else if (app->compiz_was_running)
+	{
+		vsize = get_int_value (app->client,
+				       "/apps/compiz/general/screen0/options/vsize");
+		hsize = get_int_value (app->client,
+				       "/apps/compiz/general/screen0/options/hsize");
+		set_int_value (app->client,
+			       "/apps/metacity/general/num_workspaces",
+			       vsize * hsize);
+		set_pager_num_rows (app->client, vsize);
+	}
+}
+
+static void
+set_busy (GtkWidget *widget,
+	  gboolean  busy)
+{
+	GdkCursor *cursor;
+
+	if (busy)
+		cursor = gdk_cursor_new (GDK_WATCH);
+	else
+		cursor = NULL;
+
+	gdk_window_set_cursor (widget->window, cursor);
+
+	if (cursor)
+		gdk_cursor_unref (cursor);
+
+	gdk_flush ();
+}
+
+/* get_wm_window() and current_window_manager() are essentially cutted and
+ * pasted from gnome-wm.c from gnome-control-center. */
+static Window
+get_wm_window (void)
+{
+	Window	*xwindow;
+	Atom	type;
+	gint	format;
+	gulong	nitems;
+	gulong	bytes_after;
+	Window	result;
+
+	XGetWindowProperty (GDK_DISPLAY (),
+			    GDK_ROOT_WINDOW (),
+			    XInternAtom (GDK_DISPLAY (),
+			    		 "_NET_SUPPORTING_WM_CHECK",
+			    		 False),
+			    0,
+			    G_MAXLONG,
+			    False,
+			    XA_WINDOW,
+			    &type,
+			    &format,
+			    &nitems,
+			    &bytes_after,
+			    (guchar **) &xwindow);
+
+	if (type != XA_WINDOW)
+		return None;
+
+	gdk_error_trap_push ();
+	XSelectInput (GDK_DISPLAY (),
+		      *xwindow,
+		      StructureNotifyMask | PropertyChangeMask);
+	XSync (GDK_DISPLAY (), False);
+
+	if (gdk_error_trap_pop ())
+	{
+		XFree (xwindow);
+		return None;
+	}
+
+	result = *xwindow;
+	XFree (xwindow);
+
+	return result;
+}
+
+static char*
+get_current_window_manager (void)
+{
+	Atom	utf8_string;
+	Atom	atom;
+	Atom	type;
+	int	result;
+	char	*retval;
+	int	format;
+	gulong	nitems;
+	gulong	bytes_after;
+	gchar	*val;
+	Window	wm_window = get_wm_window ();
+
+	utf8_string = XInternAtom (GDK_DISPLAY (), "UTF8_STRING", False);
+	atom = XInternAtom (GDK_DISPLAY (), "_NET_WM_NAME", False);
+
+	gdk_error_trap_push ();
+
+	result = XGetWindowProperty (GDK_DISPLAY (),
+				     wm_window,
+				     atom,
+				     0,
+				     G_MAXLONG,
+				     False,
+				     utf8_string,
+				     &type,
+				     &format,
+				     &nitems,
+				     &bytes_after,
+				     (guchar **)&val);
+
+	if (gdk_error_trap_pop () || result != Success)
+		return NULL;
+
+	if (type != utf8_string || format != 8 || nitems == 0)
+	{
+		if (val)
+			XFree (val);
+
+		return NULL;
+	}
+    
+	if (!g_utf8_validate (val, nitems, NULL))
+	{
+		XFree (val);
+		return NULL;
+	}
+
+	retval = g_strndup (val, nitems);
+
+	XFree (val);
+
+	return retval;
+}
+
+static gboolean
+compiz_started (void)
+{
+	gboolean result;
+	char	 *wm = get_current_window_manager ();
+
+	result = wm && strcmp (wm, "compiz") == 0;
+
+	g_free (wm);
+
+	return result;
+}
+
+typedef struct TimedDialogInfo {
+	AppearanceData	*app;
+	GTimer		*timer;
+	GtkWidget	*button;
+} TimedDialogInfo;
+
+static WindowManager
+current_configured_wm (AppearanceData *app,
+		       GError	      **err)
+{
+	GError *tmp = NULL;
+
+	const char *str = gconf_client_get_string (app->client,
+						   WINDOW_MANAGER_KEY,
+						   &tmp);
+
+	if (tmp)
+	{
+		g_propagate_error (err, tmp);
+		return METACITY;
+	}
+
+	if (str && strcmp (str, COMPIZ_BIN) == 0)
+		return COMPIZ;
+	else
+		return METACITY;
+}
+
+static void
+show_error (const GError *err)
+{
+	GtkWidget *dialog;
+
+	if (!err)
+		return;
+
+	dialog = gtk_message_dialog_new (NULL,
+					 GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_WARNING,
+					 GTK_BUTTONS_OK,
+					 err->message);
+
+	gtk_window_set_title (GTK_WINDOW (dialog), "");
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+}
+
+struct TimeoutData {
+	int	  time;
+	GtkLabel  *label;
+	GtkDialog *dialog;
+	gboolean  timed_out;
+};
+
+static gboolean
+free_at_idle (gpointer data)
+{
+	g_free (data);
+	return FALSE;
+}
+
+static char*
+idle_free (char *str)
+{
+	g_idle_add (free_at_idle, str);
+	return str;
+}
+
+static char *
+timeout_string (int time)
+{
+	/* SUN_BRANDING */
+	char *str = g_strdup_printf (ngettext ("Testing the new settings. If you don't respond in %d second the previous settings will be restored.", "Testing the new settings. If you don't respond in %d seconds the previous settings will be restored.", time), time);
+
+	return idle_free (str);
+}
+
+static gboolean
+save_timeout_callback (gpointer data)
+{
+	struct TimeoutData *timeData = data;
+
+	timeData->time--;
+
+	if (timeData->time == 0)
+	{
+		gtk_dialog_response (timeData->dialog, GTK_RESPONSE_NO);
+		timeData->timed_out = TRUE;
+		return FALSE;
+	}
+
+	gtk_label_set_text (timeData->label, timeout_string (timeData->time));
+
+	return TRUE;
+}
+
+static gboolean
+run_timed_dialog (AppearanceData *app)
+{
+	GtkWidget	   *dialog;
+	GtkWidget	   *hbox;
+	GtkWidget	   *vbox;
+	GtkWidget	   *label;
+	GtkWidget	   *label_sec;
+	GtkWidget	   *image;
+	int		   res;
+	struct TimeoutData timeout_data;
+	guint		   timeout;
+
+	dialog = gtk_dialog_new ();
+	gtk_window_set_transient_for (GTK_WINDOW (dialog),
+				      GTK_WINDOW (app->dialog));
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
+	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+	gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
+	gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+	/* SUN_BRANDING */
+	gtk_window_set_title (GTK_WINDOW (dialog), _("Keep Settings"));
+	gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ALWAYS);
+
+	label = gtk_label_new (NULL);
+	gtk_label_set_markup (GTK_LABEL (label),
+			      idle_free (g_strdup_printf ("<b>%s</b>",
+							  /* SUN_BRANDING */
+							  _("Do you want to keep these settings?"))));
+	image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION,
+					  GTK_ICON_SIZE_DIALOG);
+	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
+
+	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+	gtk_label_set_selectable (GTK_LABEL (label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+	label_sec = gtk_label_new (timeout_string (REVERT_COUNT));
+	gtk_label_set_line_wrap (GTK_LABEL (label_sec), TRUE);
+	gtk_label_set_selectable (GTK_LABEL (label_sec), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (label_sec), 0.0, 0.5);
+
+	hbox = gtk_hbox_new (FALSE, 6);
+	vbox = gtk_vbox_new (FALSE, 6);
+
+	gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), label_sec, TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+			    hbox,
+			    FALSE,
+			    FALSE,
+			    0);
+	gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+				/* SUN_BRANDING */
+				_("Use _previous settings"),
+				GTK_RESPONSE_NO,
+				/* SUN_BRANDING */
+				_("_Keep settings"),
+				GTK_RESPONSE_YES,
+				NULL);
+
+	gtk_widget_show_all (hbox);
+
+	timeout_data.time = REVERT_COUNT;
+	timeout_data.label = GTK_LABEL (label_sec);
+	timeout_data.dialog = GTK_DIALOG (dialog);
+	timeout_data.timed_out = FALSE;
+
+	timeout = g_timeout_add (1000, save_timeout_callback, &timeout_data);
+	res = gtk_dialog_run (GTK_DIALOG (dialog));
+
+	if (!timeout_data.timed_out)
+		g_source_remove (timeout);
+
+	gtk_widget_destroy (dialog);
+
+	return (res == GTK_RESPONSE_YES);
+}
+
+static gboolean
+show_dialog_timeout (gpointer data)
+{
+	TimedDialogInfo	*info = data;
+	gboolean	has_compiz;
+
+	gtk_window_present (GTK_WINDOW (info->app->dialog));
+
+	has_compiz = compiz_started ();
+
+	if (has_compiz ||
+	    g_timer_elapsed (info->timer,
+	    		     NULL) > SECONDS_WE_WILL_WAIT_FOR_COMPIZ_TO_START)
+	{
+		if (has_compiz)
+		{
+			set_busy (info->app->dialog, FALSE);
+
+			if (run_timed_dialog (info->app))
+				apply_settings (info->app,
+						info->app->desktop_effects_level >= 1);
+			else
+				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (info->button),
+							      TRUE);
+		}
+		else
+		{
+			GtkWidget *dialog;
+
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (info->button),
+						      TRUE);
+
+			set_busy (info->app->dialog, FALSE);
+
+			dialog = gtk_message_dialog_new ((GtkWindow*) info->app->dialog,
+							 GTK_DIALOG_DESTROY_WITH_PARENT,
+							 GTK_MESSAGE_WARNING,
+							 GTK_BUTTONS_OK,
+							 /* SUN_BRANDING */
+							 _("Desktop effects could not be enabled"));
+
+			gtk_window_set_title (GTK_WINDOW (dialog), "");
+			gtk_dialog_run (GTK_DIALOG (dialog));
+			gtk_widget_destroy (dialog);
+		}
+
+		gtk_widget_set_sensitive (info->app->dialog, TRUE);
+
+		g_timer_destroy (info->timer);
+		g_free (info);
+
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean
+start_compiz (AppearanceData *app,
+	      GError **err)
+{
+	if (!g_spawn_command_line_async ("compiz", err))
+		return FALSE;
+
+	app->compiz_running = TRUE;
+
+	return TRUE;
+}
+
+static gboolean
+start_metacity (AppearanceData *app, GError **err)
+{
+	if (!g_spawn_command_line_async ("metacity --replace", err))
+		return FALSE;
+
+	app->compiz_running = FALSE;
+
+	return TRUE;
+}
+
+static gboolean 
+has_texture_from_pixmap ()
+{
+#ifdef HAVE_GL && HAVE_GL_GLX_H
+#include <GL/gl.h>
+#include <GL/glx.h>
+	const char  *glxServerExtensions = glXQueryServerString (GDK_DISPLAY (), 0, GLX_EXTENSIONS);
+	if (glxServerExtensions == NULL || !strstr (glxServerExtensions, "GLX_EXT_texture_from_pixmap"))
+	  return FALSE;
+	return TRUE;
+#else
+	return FALSE;
+#endif
+}
+
+	
+static gboolean
+has_composite ()
+{
+	int dummy1;
+	int dummy2;
+
+	if (XCompositeQueryExtension (GDK_DISPLAY (), &dummy1, &dummy2))
+		return TRUE;
+
+	return FALSE;
+}
+
+static void
+show_alert (const char *text)
+{
+	GtkWidget *dialog;
+
+	dialog = gtk_message_dialog_new (NULL,
+					 GTK_DIALOG_MODAL,
+					 GTK_MESSAGE_ERROR,
+					 GTK_BUTTONS_OK,
+					 text);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+}
+
+static gboolean
+are_effects_enabled (AppearanceData* app,
+		     const gchar**   effects_list)
+{
+	int	 i;
+	gboolean res = TRUE;
+	GError	 *tmp = NULL;
+	GSList	 *plugins;
+
+	plugins = get_plugins (app, &tmp);
+	for (i = 0; effects_list[i] != NULL; i++)
+		res &= contains_string (plugins, effects_list[i]);
+
+	return res;
+}
+
+static gboolean
+reset_plugins (AppearanceData *app)
+{
+	GError *error = NULL;
+
+	return gconf_client_unset (app->client, PLUGIN_LIST_KEY, &error);
+}
+
+static gboolean
+are_normal_effects_enabled (AppearanceData *app)
+{
+   gboolean res = TRUE;
+   GError *err = NULL;
+   GSList *plugins, *default_plugins;
+
+   default_plugins = gconf_value_get_list ( gconf_client_get_default_from_schema (app->client,  PLUGIN_LIST_KEY, &err));
+
+   err = NULL;
+   plugins = get_plugins (app, &err);
+   for(;default_plugins; default_plugins = g_slist_next(default_plugins))
+      res &= contains_string(plugins, gconf_value_get_string(default_plugins->data));
+
+   return res;
+}
+
+static gboolean
+are_extra_effects_enabled (AppearanceData *app)
+{
+   return are_effects_enabled (app, extra_effects);
+}
+
+static gint
+get_effects_level (AppearanceData *data)
+{
+	if (data->compiz_running)
+	{
+	        if (are_extra_effects_enabled (data))
+		        return EXTRA_EFFECTS;
+		else if (are_normal_effects_enabled (data))
+			return NORMAL_EFFECTS;
+		else
+			return CUSTOM_EFFECTS;
+        }
+        else
+		return NO_EFFECTS;       
+}
+
+static gboolean
+enable_normal_effects (AppearanceData* app)
+{
+   return reset_plugins (app);
+}
+
+static gboolean
+enable_extra_effects (AppearanceData* app)
+{
+	GError	*err = NULL;
+	GSList	*plugins = NULL;
+	int	i;
+
+	reset_plugins (app);
+
+	for (i = 0; extra_effects[i] != NULL; i++)
+		plugins = g_slist_append (plugins,
+					  (gchar*) extra_effects[i]);
+
+	err = NULL;
+	gconf_client_set_list (app->client,
+			       PLUGIN_LIST_KEY,
+			       GCONF_VALUE_STRING,
+			       plugins,
+			       &err);
+
+	return TRUE;
+}
+
+static void
+on_effects_toggle (GtkWidget *widget,
+		   gpointer  user_data)
+{
+	AppearanceData	*appdata = user_data;
+	GtkWidget	*previously_selected_button;
+	static gint	old_effects_level;
+	static gboolean	do_init = TRUE;
+	gint		i;
+	GError		*err = NULL;
+
+	if (do_init == TRUE)
+	{
+		old_effects_level = get_effects_level (appdata);
+		do_init = FALSE;
+	}
+
+	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) 
+		return;
+
+	previously_selected_button = appearance_capplet_get_widget(appdata,
+							   effect_choices [old_effects_level]);
+
+	/* Look for the button which has been selected */
+	for (i = 0; i < G_N_ELEMENTS (effect_choices); i++) 
+	{
+		if (widget == appearance_capplet_get_widget(appdata,
+						   effect_choices [i]))
+			break;
+	}
+
+	appdata->desktop_effects_level = i;
+
+	if (appdata->desktop_effects_level >= 1)
+	{		
+		if (!has_composite ())
+		{
+			show_alert ("The Composite extension is not available");
+			return;
+		}
+
+		if (old_effects_level == 0)
+			start_compiz (appdata, &err);
+
+		if (appdata->desktop_effects_level == NORMAL_EFFECTS)
+		        enable_normal_effects (appdata);
+
+		if (appdata->desktop_effects_level == EXTRA_EFFECTS)
+		        enable_extra_effects (appdata);
+	}
+	else 
+	{
+		apply_settings (appdata, FALSE);
+		start_metacity (appdata, &err);
+	}
+	
+	if (err)
+	{
+		show_error (err);
+		
+		g_signal_handlers_block_by_func (widget,
+						 (gpointer)on_effects_toggle,
+						 appdata);
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appearance_capplet_get_widget(appdata,
+										       effect_choices [old_effects_level])),
+										       TRUE);		
+		g_signal_handlers_unblock_by_func (widget,
+						   (gpointer)on_effects_toggle,
+						   appdata);
+	}
+	else
+	{
+		if (appdata->desktop_effects_level >= 1 &&
+		    old_effects_level == 0)
+		{
+			TimedDialogInfo *info = g_new0 (TimedDialogInfo, 1);
+			
+			info->app = appdata;
+			info->button = previously_selected_button;
+			info->timer = g_timer_new ();
+			
+			set_busy (info->app->dialog, TRUE);
+			gtk_widget_set_sensitive (appdata->dialog, FALSE);
+			
+			g_timeout_add (250, show_dialog_timeout, info);
+		}
+	}
+
+	old_effects_level = i;  
+}
+
+void
+effects_init (AppearanceData *data)
+{
+	GError	      *error = NULL;
+	GtkWidget     *level_effects_button = NULL;
+	GtkWidget     *hbox_custom_effects = NULL;
+	WindowManager wm = METACITY;
+	gint	      i;
+	const char *str = get_current_window_manager ();
+	if (str && strcmp (str, "compiz") == 0)
+		wm = COMPIZ;
+
+	data->compiz_running = (wm == COMPIZ);
+	data->compiz_was_running = (wm == COMPIZ);
+	data->dialog = appearance_capplet_get_widget(data, "appearance_window");
+
+	data->desktop_effects_level = get_effects_level (data);
+
+	if (!has_composite () || !has_texture_from_pixmap () || !check_compiz ())
+	{
+	  GtkWidget *vbox = appearance_capplet_get_widget(data, "effects_vbox");
+	  GList *children = gtk_container_get_children (GTK_CONTAINER (vbox));
+	  GtkWidget *label = gtk_label_new (NULL);
+	  GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
+	  GtkWidget *image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
+	  /* SUN_BRANDING */
+	  GString *message = g_string_new (_("<b>Visual effects cannot be enabled</b>\n\nDetails :\n"));
+
+	  gtk_container_add (GTK_CONTAINER (vbox), hbox);
+	  gtk_container_add (GTK_CONTAINER (hbox), image);
+
+	  while (children)
+	  {
+	      GtkWidget *child = (GtkWidget*) children->data;
+	      gtk_container_remove (GTK_CONTAINER (vbox), child);
+	      children = children->next;
+	  }
+	  if (!has_composite ())
+	    /* SUN_BRANDING */
+	    g_string_append (message, _("\nComposite extension is not enabled"));
+	  
+	  if (!has_texture_from_pixmap ())
+	  {
+	    #ifndef HAVE_GL && HAVE_GL_GLX_H
+	    /* SUN_BRANDING */
+	    g_string_append (message, _("\nThis application was compiled without the OpenGL extension"));
+	    #else
+	    /* SUN_BRANDING */
+	    g_string_append (message, _("\nThe OpenGL extension TextureFromPixmap is not enabled"));
+	    #endif
+	  }
+
+	  if (!check_compiz ())
+	    /* SUN_BRANDING */
+	    g_string_append (message, _("\nCompiz is not installed on the system"));
+	      
+
+	  gtk_label_set_markup (GTK_LABEL (label), message->str);
+	  gtk_container_add (GTK_CONTAINER (hbox), label);
+	  gtk_widget_show (label);
+	  g_string_free (message, TRUE);
+	  if (check_compiz_configure () && check_compiz ())
+	    {
+	      /* SUN_BRANDING */
+	      GtkWidget* button = gtk_button_new_with_label (_("Check if visual effects can be enabled"));
+	      GtkWidget* align = gtk_alignment_new (0.5, 0.5, 0, 0);
+	      g_signal_connect (button,
+				  "clicked",
+				  G_CALLBACK (run_compiz_configure),
+				  NULL);
+
+	      gtk_container_add (GTK_CONTAINER (align), button);
+	      gtk_container_add (GTK_CONTAINER (vbox), align);
+	      gtk_box_set_child_packing (GTK_BOX (vbox),
+					 button,
+					 FALSE,
+					 FALSE,
+					 0,
+					 GTK_PACK_END);
+	      gtk_widget_show (button);
+	    }
+	  return;
+	}
+
+
+	for (i = 0; i < G_N_ELEMENTS (effect_choices); i++) 
+	{
+		level_effects_button = appearance_capplet_get_widget(data,
+							     effect_choices[i]);
+		if (i == data->desktop_effects_level)
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (level_effects_button),
+						      TRUE);
+
+		g_signal_connect (level_effects_button,
+				  "toggled",
+				  G_CALLBACK (on_effects_toggle),
+				  data);
+	}
+
+	hbox_custom_effects = appearance_capplet_get_widget(data,
+						    "hbox_custom_effects");
+	if (check_ccsm ())
+	{
+		GtkWidget *button = NULL;
+
+		gtk_widget_show (hbox_custom_effects);
+		button = appearance_capplet_get_widget(data,
+					       "custom_effects_edit_button");
+		g_signal_connect (button,
+				  "clicked",
+				  G_CALLBACK (run_ccsm),
+				  NULL);
+	}
+	else
+		gtk_widget_hide (hbox_custom_effects);
+}
+
diff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' gnome-control-center-2.28.0/capplets/appearance/appearance-effects.h ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/appearance-effects.h
--- gnome-control-center-2.28.0/capplets/appearance/appearance-effects.h	1970-01-01 01:00:00.000000000 +0100
+++ ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/appearance-effects.h	2009-10-16 09:52:28.249534159 +0200
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2007 Canonical
+ * Written by Michael Vogt <[email protected]>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+void effects_init (AppearanceData *data);
diff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' gnome-control-center-2.28.0/capplets/appearance/appearance.h ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/appearance.h
--- gnome-control-center-2.28.0/capplets/appearance/appearance.h	2009-09-07 13:19:06.000000000 +0200
+++ ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/appearance.h	2009-10-16 09:52:28.250095799 +0200
@@ -75,6 +75,12 @@ typedef struct
   gchar *revert_windowtitle_font;
   gchar *revert_monospace_font;
 
+  /* effects */
+  gboolean compiz_running;
+  gboolean compiz_was_running;
+  gint desktop_effects_level;
+  GtkWidget *dialog;
+
   /* style */
   GdkPixbuf *gtk_theme_icon;
   GdkPixbuf *window_theme_icon;
diff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' gnome-control-center-2.28.0/capplets/appearance/data/Makefile.am ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/data/Makefile.am
--- gnome-control-center-2.28.0/capplets/appearance/data/Makefile.am	2009-09-07 13:19:06.000000000 +0200
+++ ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/data/Makefile.am	2009-10-16 09:52:28.250288191 +0200
@@ -15,7 +15,11 @@ dist_pixmap_DATA = \
         mouse-cursor-normal.png \
         mouse-cursor-normal-large.png \
         mouse-cursor-white.png \
-        mouse-cursor-white-large.png
+        mouse-cursor-white-large.png \
+	visual-effects_custom.svg \
+	visual-effects_extra.svg  \
+	visual-effects_none.svg	\
+	visual-effects_normal.svg
 
 cursorfontdir   = $(datadir)/gnome/cursor-fonts
 dist_cursorfont_DATA = \
diff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' gnome-control-center-2.28.0/capplets/appearance/data/appearance.ui ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/data/appearance.ui
--- gnome-control-center-2.28.0/capplets/appearance/data/appearance.ui	2009-09-21 12:44:55.000000000 +0200
+++ ../SUNWgnome-desktop-prefs-2.28.0.fix/gnome-control-center-2.28.0/capplets/appearance/data/appearance.ui	2009-10-16 09:52:28.252549269 +0200
@@ -1913,6 +1913,272 @@
                 <property name="tab_fill">False</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkVBox" id="effects_vbox">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="border_width">6</property>
+                <property name="spacing">18</property>
+                <property name="homogeneous">True</property>
+                <child>
+                  <object class="GtkRadioButton" id="no_effects_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                    <accelerator key="n" modifiers="" signal="activate"/>
+                    <child>
+                      <object class="GtkHBox" id="hbox_no_effects">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <child>
+                          <object class="GtkImage" id="image_no_effects">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="xpad">6</property>
+                            <property name="pixbuf">/usr/share/gnome-control-center/pixmaps/visual-effects_none.svg</property>
+                            <property name="icon_size">6</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_desc_no_effects">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="xpad">6</property>
+                            <property name="label" translatable="yes" comments="SUN_BRANDING">&lt;b&gt;_None:&lt;/b&gt; Provides a simple desktop environment without any effects.</property>
+                            <property name="use_markup">True</property>
+                            <property name="use_underline">True</property>
+                            <property name="wrap">True</property>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="padding">6</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkRadioButton" id="normal_effects_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">no_effects_button</property>
+                    <accelerator key="o" modifiers="" signal="activate"/>
+                    <child>
+                      <object class="GtkHBox" id="hbox_normal_effects">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <child>
+                          <object class="GtkImage" id="image_normal_effects">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="xpad">6</property>
+                            <property name="pixbuf">/usr/share/gnome-control-center/pixmaps/visual-effects_normal.svg</property>
+                            <property name="icon_size">6</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_desc_normal_effects">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="xpad">6</property>
+                            <property name="label" translatable="yes" comments="SUN_BRANDING">&lt;b&gt;N_ormal:&lt;/b&gt; Provides improved usability and good balance between attractiveness and moderate performance-requirements.</property>
+                            <property name="use_markup">True</property>
+                            <property name="use_underline">True</property>
+                            <property name="wrap">True</property>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="padding">6</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkRadioButton" id="extra_effects_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">no_effects_button</property>
+                    <accelerator key="x" modifiers="" signal="activate"/>
+                    <child>
+                      <object class="GtkHBox" id="hbox_extra_effects">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <child>
+                          <object class="GtkImage" id="image_extra_effects">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="xpad">6</property>
+                            <property name="pixbuf">/usr/share/gnome-control-center/pixmaps/visual-effects_extra.svg</property>
+                            <property name="icon_size">6</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_desc_extra_effects">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="xpad">6</property>
+                            <property name="label" translatable="yes" comments="SUN_BRANDING">&lt;b&gt;E_xtra:&lt;/b&gt; Provides more aesthetically pleasing set of effects. Requires faster graphics-card.</property>
+                            <property name="use_markup">True</property>
+                            <property name="use_underline">True</property>
+                            <property name="wrap">True</property>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="padding">6</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkHBox" id="hbox_custom_effects">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="no_show_all">True</property>
+                    <child>
+                      <object class="GtkRadioButton" id="custom_effects_button">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                        <property name="group">no_effects_button</property>
+                        <accelerator key="u" modifiers="" signal="activate"/>
+                        <child>
+                          <object class="GtkHBox" id="hbox_custom_effects_2">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="spacing">6</property>
+                            <child>
+                              <object class="GtkImage" id="image_custom_effects">
+                                <property name="visible">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="xpad">6</property>
+                                <property name="pixbuf">/usr/share/gnome-control-center/pixmaps/visual-effects_custom.svg</property>
+                                <property name="icon_size">6</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label_desc_custom_effects">
+                                <property name="visible">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="label" translatable="yes" comments="SUN_BRANDING">&lt;b&gt;C_ustom:&lt;/b&gt; Uses custom set of effects.</property>
+                                <property name="use_markup">True</property>
+                                <property name="use_underline">True</property>
+                                <property name="wrap">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkVBox" id="vbox_custom_effects">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <child>
+                          <object class="GtkLabel" id="label_dummy_1">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkButton" id="custom_effects_edit_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">gtk-preferences</property>
+                            <property name="use_stock">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_dummy_2">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="padding">6</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="effects_label">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="label" translatable="yes" comments="SUN_BRANDING">Visual Effects</property>
+              </object>
+              <packing>
+                <property name="position">4</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="position">1</property>
@@ -1964,6 +2230,11 @@
       </object>
     </child>
     <action-widgets>
+      <action-widget response="0">no_effects_button</action-widget>
+      <action-widget response="0">normal_effects_button</action-widget>
+      <action-widget response="0">extra_effects_button</action-widget>
+      <action-widget response="0">custom_effects_button</action-widget>
+      <action-widget response="0">custom_effects_edit_button</action-widget>
       <action-widget response="-11">help_button</action-widget>
       <action-widget response="-7">close_button</action-widget>
     </action-widgets>
diff -ruN gnome-control-center-2.29.6.orig/configure.ac gnome-control-center-2.29.6/configure.ac
--- gnome-control-center-2.29.6.orig/configure.ac	2010-02-02 20:43:08.328661566 +0000
+++ gnome-control-center-2.29.6/configure.ac	2010-02-02 20:43:37.866991531 +0000
@@ -174,6 +174,22 @@
 GNOMECC_LIBS="$GNOMECC_LIBS $x_libs"
 
 dnl
+dnl Check for OpenGL support
+dnl
+have_gl=0
+have_libgl=0
+AC_CHECK_HEADERS(GL/glx.h)
+if test $ac_cv_header_GL_glx_h = yes ; then
+       AC_CHECK_FUNC(glXQueryExtension,[have_gl=1],AC_CHECK_LIB(GL,glXQueryExtension,[have_gl=1;have_libgl=1]))
+fi
+if test $have_gl = 1 ; then
+       AC_DEFINE(HAVE_GL,1,[Whether we have GL and glX.])
+fi
+if test $have_libgl = 1 ; then
+       LIBS="-lGL $LIBS"
+fi
+
+dnl
 dnl Check for XCursor support.  If it exists, then we compile the
 dnl mouse capplet with support for it turned on
 dnl
diff -ruN gnome-control-center-2.29.6.orig/capplets/appearance/appearance-main.c gnome-control-center-2.29.6/capplets/appearance/appearance-main.c
--- gnome-control-center-2.29.6.orig/capplets/appearance/appearance-main.c	2010-02-02 20:45:20.834726490 +0000
+++ gnome-control-center-2.29.6/capplets/appearance/appearance-main.c	2010-02-02 20:46:36.657848187 +0000
@@ -164,6 +164,7 @@
   desktop_init (data, (const gchar **) wallpaper_files);
   g_strfreev (wallpaper_files);
   font_init (data);
+  effects_init (data);
 
   /* prepare the main window */
   w = appearance_capplet_get_widget (data, "appearance_window");