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; } }
/** * 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 (); }
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; }
/** * 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; }
/** * 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); }
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; }
/** * 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; }
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; }
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; }
/** * 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 (); }
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; }
/** * 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 (); }