/**
 * gnome_bg_crossfade_start:
 * @fade: a #GnomeBGCrossfade
 * @window: The #GdkWindow to draw crossfade on
 *
 * This function initiates a quick crossfade between two surfaces on
 * the background of @window.  Before initiating the crossfade both
 * gnome_bg_crossfade_start() and gnome_bg_crossfade_end() need to
 * be called. If animations are disabled, the crossfade is skipped,
 * and the window background is set immediately to the end surface.
 **/
void
gnome_bg_crossfade_start (GnomeBGCrossfade *fade,
			  GdkWindow        *window)
{
	GSource *source;
	GMainContext *context;
        cairo_pattern_t *pattern;

	g_return_if_fail (GNOME_IS_BG_CROSSFADE (fade));
	g_return_if_fail (window != NULL);
	g_return_if_fail (fade->priv->fading_surface != NULL);
	g_return_if_fail (fade->priv->end_surface != NULL);
	g_return_if_fail (!gnome_bg_crossfade_is_started (fade));
	g_return_if_fail (gdk_window_get_window_type (window) != GDK_WINDOW_FOREIGN);

	source = g_timeout_source_new (1000 / 60.0);
	g_source_set_callback (source,
			       (GSourceFunc) on_tick,
			       fade,
			       (GDestroyNotify) on_finished);
	context = g_main_context_default ();
	fade->priv->timeout_id = g_source_attach (source, context);
	g_source_unref (source);

	fade->priv->window = window;
        pattern = cairo_pattern_create_for_surface (fade->priv->fading_surface);
	gdk_window_set_background_pattern (fade->priv->window, pattern);
        cairo_pattern_destroy (pattern);

	draw_background (fade);

	fade->priv->is_first_frame = TRUE;
	fade->priv->total_duration = .75;
	fade->priv->start_time = get_current_time ();
}
static void
init_fade (AthenaDesktopBackground *self)
{
	GtkWidget *widget;
	gboolean do_fade;

	widget = self->details->widget;

	if (widget == NULL || !gtk_widget_get_realized (widget))
		return;

	do_fade = g_settings_get_boolean (athena_desktop_preferences,
					  ATHENA_PREFERENCES_DESKTOP_BACKGROUND_FADE);

	if (!do_fade) {
		return;
	}

	if (self->details->fade == NULL) {
		GdkWindow *window;
		GdkScreen *screen;
		int old_width, old_height, width, height;

		/* If this was the result of a screen size change,
		 * we don't want to crossfade
		 */
		window = gtk_widget_get_window (widget);
		old_width = gdk_window_get_width (window);
		old_height = gdk_window_get_height (window);

		screen = gtk_widget_get_screen (widget);
		width = gdk_screen_get_width (screen);
		height = gdk_screen_get_height (screen);

		if (old_width == width && old_height == height) {
			self->details->fade = gnome_bg_crossfade_new (width, height);
			g_signal_connect_swapped (self->details->fade,
                                                  "finished",
                                                  G_CALLBACK (free_fade),
                                                  self);
		}
	}

	if (self->details->fade != NULL && !gnome_bg_crossfade_is_started (self->details->fade)) {
		cairo_surface_t *start_surface;

		if (self->details->background_surface == NULL) {
			start_surface = gnome_bg_get_surface_from_root (gtk_widget_get_screen (widget));
		} else {
			start_surface = cairo_surface_reference (self->details->background_surface);
		}
		gnome_bg_crossfade_set_start_surface (self->details->fade,
						      start_surface);
                cairo_surface_destroy (start_surface);
	}
}
/**
 * gnome_bg_crossfade_stop:
 * @fade: a #GnomeBGCrossfade
 *
 * This function stops any in progress crossfades that may be
 * happening.  It's harmless to call this function if @fade is
 * already stopped.
 **/
void
gnome_bg_crossfade_stop (GnomeBGCrossfade *fade)
{
	g_return_if_fail (GNOME_IS_BG_CROSSFADE (fade));

	if (!gnome_bg_crossfade_is_started (fade))
		return;

	g_assert (fade->priv->timeout_id != 0);
	g_source_remove (fade->priv->timeout_id);
	fade->priv->timeout_id = 0;
}
static gboolean
fade_to_surface (AthenaDesktopBackground *self,
		 GdkWindow     *window,
		 cairo_surface_t *surface)
{
	if (self->details->fade == NULL) {
		return FALSE;
	}

	if (!gnome_bg_crossfade_set_end_surface (self->details->fade,
				                 surface)) {
		return FALSE;
	}

	if (!gnome_bg_crossfade_is_started (self->details->fade)) {
		gnome_bg_crossfade_start (self->details->fade, window);
		g_signal_connect (self->details->fade,
				  "finished",
				  G_CALLBACK (on_fade_finished), self);
	}

	return gnome_bg_crossfade_is_started (self->details->fade);
}