Пример #1
0
static void
mate_bg_crossfade_set_property (GObject      *object,
				 guint         property_id,
				 const GValue *value,
				 GParamSpec   *pspec)
{
	MateBGCrossfade *fade;

	g_assert (MATE_IS_BG_CROSSFADE (object));

	fade = MATE_BG_CROSSFADE (object);

	switch (property_id)
	{
	case PROP_WIDTH:
		fade->priv->width = g_value_get_int (value);
		break;
	case PROP_HEIGHT:
		fade->priv->height = g_value_get_int (value);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}
Пример #2
0
/**
 * mate_bg_crossfade_is_started:
 * @fade: a #MateBGCrossfade
 *
 * This function reveals whether or not @fade is currently
 * running on a window.  See mate_bg_crossfade_start() for
 * information on how to initiate a crossfade.
 *
 * Return value: %TRUE if fading, or %FALSE if not fading
 **/
gboolean
mate_bg_crossfade_is_started (MateBGCrossfade *fade)
{
	g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE);

	return fade->priv->timeout_id != 0;
}
/**
 * mate_bg_crossfade_start:
 * @fade: a #MateBGCrossfade
 * @window: The #GdkWindow to draw crossfade on
 *
 * This function initiates a quick crossfade between two pixmaps on
 * the background of @window.  Before initiating the crossfade both
 * mate_bg_crossfade_start() and mate_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 pixmap.
 **/
void
mate_bg_crossfade_start (MateBGCrossfade *fade,
			  GdkWindow        *window)
{
	GSource *source;
	GMainContext *context;

	g_return_if_fail (MATE_IS_BG_CROSSFADE (fade));
	g_return_if_fail (window != NULL);
	g_return_if_fail (fade->priv->fading_pixmap != NULL);
	g_return_if_fail (fade->priv->end_pixmap != NULL);
	g_return_if_fail (!mate_bg_crossfade_is_started (fade));
	g_return_if_fail (GDK_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;
	gdk_window_set_back_pixmap (fade->priv->window,
				    fade->priv->fading_pixmap,
				    FALSE);
	draw_background (fade);

	fade->priv->is_first_frame = TRUE;
	fade->priv->total_duration = .75;
	fade->priv->start_time = get_current_time ();
}
Пример #4
0
static gboolean
on_tick (MateBGCrossfade *fade)
{
	gdouble now, percent_done;
	cairo_t *cr;
	cairo_status_t status;

	g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE);

	now = get_current_time ();

	percent_done = (now - fade->priv->start_time) / fade->priv->total_duration;
	percent_done = CLAMP (percent_done, 0.0, 1.0);

	/* If it's taking a long time to get to the first frame,
	 * then lengthen the duration, so the user will get to see
	 * the effect.
	 */
	if (fade->priv->is_first_frame && percent_done > .33) {
		fade->priv->is_first_frame = FALSE;
		fade->priv->total_duration *= 1.5;
		return on_tick (fade);
	}

	if (fade->priv->fading_surface == NULL ||
	    fade->priv->end_surface == NULL) {
		return FALSE;
	}

	if (animations_are_disabled (fade)) {
		return FALSE;
	}

	/* We accumulate the results in place for performance reasons.
	 *
	 * This means 1) The fade is exponential, not linear (looks good!)
	 * 2) The rate of fade is not independent of frame rate. Slower machines
	 * will get a slower fade (but never longer than .75 seconds), and
	 * even the fastest machines will get *some* fade because the framerate
	 * is capped.
	 */
	cr = cairo_create (fade->priv->fading_surface);

	cairo_set_source_surface (cr, fade->priv->end_surface,
				  0.0, 0.0);
	cairo_paint_with_alpha (cr, percent_done);

	status = cairo_status (cr);
	cairo_destroy (cr);

	if (status == CAIRO_STATUS_SUCCESS) {
		draw_background (fade);
	}
	return percent_done <= .99;
}
Пример #5
0
/**
 * mate_bg_crossfade_stop:
 * @fade: a #MateBGCrossfade
 *
 * This function stops any in progress crossfades that may be
 * happening.  It's harmless to call this function if @fade is
 * already stopped.
 **/
void
mate_bg_crossfade_stop (MateBGCrossfade *fade)
{
	g_return_if_fail (MATE_IS_BG_CROSSFADE (fade));

	if (!mate_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;
}
Пример #6
0
/**
 * mate_bg_crossfade_start_widget:
 * @fade: a #MateBGCrossfade
 * @widget: The #GtkWidget to draw crossfade on
 *
 * This function initiates a quick crossfade between two surfaces on
 * the background of @widget. Before initiating the crossfade both
 * mate_bg_crossfade_set_start_surface() and
 * mate_bg_crossfade_set_end_surface() need to be called. If animations
 * are disabled, the crossfade is skipped, and the window background is
 * set immediately to the end surface.
 **/
void
mate_bg_crossfade_start_widget (MateBGCrossfade *fade,
                                GtkWidget       *widget)
{
	GdkWindow *window;

	g_return_if_fail (MATE_IS_BG_CROSSFADE (fade));
	g_return_if_fail (widget != NULL);

	fade->priv->widget = widget;
	gtk_widget_realize (fade->priv->widget);
	window = gtk_widget_get_window (fade->priv->widget);

	mate_bg_crossfade_start (fade, window);
}
Пример #7
0
mate_bg_crossfade_set_start_pixmap (MateBGCrossfade* fade, GdkPixmap *surface)
#endif
{
	g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE);

	if (fade->priv->fading_surface != NULL)
	{
		cairo_surface_destroy (fade->priv->fading_surface);
		fade->priv->fading_surface = NULL;
	}

	fade->priv->fading_surface = tile_surface (surface,
						   fade->priv->width,
						   fade->priv->height);

	return fade->priv->fading_surface != NULL;
}
/**
 * mate_bg_crossfade_set_start_pixmap:
 * @fade: a #MateBGCrossfade
 * @pixmap: The #GdkPixmap to fade from
 *
 * Before initiating a crossfade with mate_bg_crossfade_start()
 * a start and end pixmap have to be set.  This function sets
 * the pixmap shown at the beginning of the crossfade effect.
 *
 * Return value: %TRUE if successful, or %FALSE if the pixmap
 * could not be copied.
 **/
gboolean
mate_bg_crossfade_set_start_pixmap (MateBGCrossfade *fade,
				     GdkPixmap        *pixmap)
{
	g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE);

	if (fade->priv->fading_pixmap != NULL) {
		g_object_unref (fade->priv->fading_pixmap);
		fade->priv->fading_pixmap = NULL;
	}

	fade->priv->fading_pixmap = tile_pixmap (pixmap,
						 fade->priv->width,
						 fade->priv->height);

	return fade->priv->fading_pixmap != NULL;
}
Пример #9
0
/**
 * mate_bg_crossfade_set_start_surface:
 * @fade: a #MateBGCrossfade
 * @surface: The cairo surface to fade from
 *
 * Before initiating a crossfade with mate_bg_crossfade_start()
 * a start and end surface have to be set.  This function sets
 * the surface shown at the beginning of the crossfade effect.
 *
 * Return value: %TRUE if successful, or %FALSE if the surface
 * could not be copied.
 **/
gboolean
mate_bg_crossfade_set_start_surface (MateBGCrossfade* fade, cairo_surface_t *surface)
{
	g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE);

	if (fade->priv->start_surface != NULL)
	{
		cairo_surface_destroy (fade->priv->start_surface);
		fade->priv->start_surface = NULL;
	}

	fade->priv->start_surface = tile_surface (surface,
						  fade->priv->width,
						  fade->priv->height);

	return fade->priv->start_surface != NULL;
}
Пример #10
0
mate_bg_crossfade_set_end_pixmap (MateBGCrossfade* fade, GdkPixmap *surface)
#endif
{
	g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE);

	if (fade->priv->end_surface != NULL) {
		cairo_surface_destroy (fade->priv->end_surface);
		fade->priv->end_surface = NULL;
	}

	fade->priv->end_surface = tile_surface (surface,
					        fade->priv->width,
					        fade->priv->height);

	/* Reset timer in case we're called while animating
	 */
	fade->priv->start_time = get_current_time ();
	return fade->priv->end_surface != NULL;
}
Пример #11
0
	gboolean mate_bg_crossfade_set_end_pixmap(MateBGCrossfade* fade, GdkPixmap* pixmap)
#endif
{
	g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE);

	if (fade->priv->end_pixmap != NULL) {
		g_object_unref (fade->priv->end_pixmap);
		fade->priv->end_pixmap = NULL;
	}

	fade->priv->end_pixmap = tile_pixmap (pixmap,
					      fade->priv->width,
					      fade->priv->height);

	/* Reset timer in case we're called while animating
	 */
	fade->priv->start_time = get_current_time ();
	return fade->priv->end_pixmap != NULL;
}
Пример #12
0
/**
 * mate_bg_crossfade_start:
 * @fade: a #MateBGCrossfade
 * @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
 * mate_bg_crossfade_start() and mate_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
mate_bg_crossfade_start (MateBGCrossfade *fade,
			  GdkWindow        *window)
{
	GSource *source;
	GMainContext *context;

	g_return_if_fail (MATE_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 (!mate_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;
#if GTK_CHECK_VERSION (3, 0, 0)
	cairo_pattern_t *pattern;
	pattern = cairo_pattern_create_for_surface (fade->priv->fading_surface);
	gdk_window_set_background_pattern (fade->priv->window, pattern);
	cairo_pattern_destroy (pattern);
#else
	gdk_window_set_back_pixmap (fade->priv->window,
				    fade->priv->fading_surface,
				    FALSE);
#endif
	draw_background (fade);

	fade->priv->is_first_frame = TRUE;
	fade->priv->total_duration = .75;
	fade->priv->start_time = get_current_time ();
}
Пример #13
0
	gboolean mate_bg_crossfade_set_start_pixmap(MateBGCrossfade* fade, GdkPixmap* pixmap)
#endif
{
/* I am disabling this because background fade break the mate-file-manager
 * Estoy deshabilitando esto por que el efecto de desvanecimiento del fondo de pantalla, hace
 * el mate-file-manager se cierre por un evento de BadDrawing enviado por Xorg.
 * Y hasta que no sea solucionado, no es tan indispensable esta funcion.
 * Pero sospecho que la funcion tile_pixmap tiene algo que ver...
 */
return FALSE;

	g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE);

	if (fade->priv->fading_pixmap != NULL) {
		g_object_unref (fade->priv->fading_pixmap);
		fade->priv->fading_pixmap = NULL;
	}

	fade->priv->fading_pixmap = tile_pixmap (pixmap,
						 fade->priv->width,
						 fade->priv->height);

	return fade->priv->fading_pixmap != NULL;
}
Пример #14
0
/**
 * mate_bg_crossfade_start:
 * @fade: a #MateBGCrossfade
 * @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
 * mate_bg_crossfade_set_start_surface() and
 * mate_bg_crossfade_set_end_surface() need to be called. If animations
 * are disabled, the crossfade is skipped, and the window background is
 * set immediately to the end surface.
 **/
void
mate_bg_crossfade_start (MateBGCrossfade *fade,
                         GdkWindow       *window)
{
	GSource *source;
	GMainContext *context;

	g_return_if_fail (MATE_IS_BG_CROSSFADE (fade));
	g_return_if_fail (window != NULL);
	g_return_if_fail (fade->priv->start_surface != NULL);
	g_return_if_fail (fade->priv->end_surface != NULL);
	g_return_if_fail (!mate_bg_crossfade_is_started (fade));
	g_return_if_fail (gdk_window_get_window_type (window) != GDK_WINDOW_FOREIGN);

	/* If drawing is done on the root window,
	 * it is essential to have the root pixmap.
	 */
	if (gdk_window_get_window_type (window) == GDK_WINDOW_ROOT) {
		GdkDisplay *display = gdk_window_get_display (window);
		cairo_surface_t *surface = get_root_pixmap_id_surface (display);

		g_return_if_fail (surface != NULL);
		cairo_surface_destroy (surface);
	}

	if (fade->priv->fading_surface != NULL) {
		cairo_surface_destroy (fade->priv->fading_surface);
		fade->priv->fading_surface = NULL;
	}

	fade->priv->window = window;
	if (gdk_window_get_window_type (fade->priv->window) != GDK_WINDOW_ROOT) {
		fade->priv->fading_surface = tile_surface (fade->priv->start_surface,
		                                           fade->priv->width,
		                                           fade->priv->height);
		if (fade->priv->widget != NULL) {
			g_signal_connect (fade->priv->widget, "draw",
			                  (GCallback) on_widget_draw, fade);
		}
	} else {
		cairo_t   *cr;
		GdkDisplay *display = gdk_window_get_display (fade->priv->window);

		fade->priv->fading_surface = get_root_pixmap_id_surface (display);
		cr = cairo_create (fade->priv->fading_surface);
		cairo_set_source_surface (cr, fade->priv->start_surface, 0, 0);
		cairo_paint (cr);
		cairo_destroy (cr);
	}
	draw_background (fade);

	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->is_first_frame = TRUE;
	fade->priv->total_duration = .75;
	fade->priv->start_time = get_current_time ();
}