gnome-settings-daemon r57 - in trunk: . plugins/mouse
- From: carlosg svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-settings-daemon r57 - in trunk: . plugins/mouse
- Date: Tue, 22 Jan 2008 16:15:41 +0000 (GMT)
Author: carlosg
Date: Tue Jan 22 16:15:41 2008
New Revision: 57
URL: http://svn.gnome.org/viewvc/gnome-settings-daemon?rev=57&view=rev
Log:
2008-01-22 Carlos Garnacho <carlosg gnome org>
* plugins/mouse/gsd-locate-pointer.c: Reworked, add a more appealing
animation if there's a composite manager present, also use a similar
animation for the non-composite case, so most of the code is shared.
* plugins/mouse/gsd-timeline.[ch]: New files, object to control the
"locate pointer" animation.
* plugins/mouse/Makefile.am: Added these files to build.
Added:
trunk/plugins/mouse/gsd-timeline.c
trunk/plugins/mouse/gsd-timeline.h
Modified:
trunk/ChangeLog
trunk/plugins/mouse/Makefile.am
trunk/plugins/mouse/gsd-locate-pointer.c
Modified: trunk/plugins/mouse/Makefile.am
==============================================================================
--- trunk/plugins/mouse/Makefile.am (original)
+++ trunk/plugins/mouse/Makefile.am Tue Jan 22 16:15:41 2008
@@ -21,6 +21,8 @@
gsd-mouse-manager.c \
gsd-locate-pointer.h \
gsd-locate-pointer.c \
+ gsd-timeline.h \
+ gsd-timeline.c \
$(NULL)
libmouse_la_LDFLAGS = \
Modified: trunk/plugins/mouse/gsd-locate-pointer.c
==============================================================================
--- trunk/plugins/mouse/gsd-locate-pointer.c (original)
+++ trunk/plugins/mouse/gsd-locate-pointer.c Tue Jan 22 16:15:41 2008
@@ -1,243 +1,293 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/* gsd-locate-pointer.c
*
- * Copyright  2001 Jonathan Blandford <jrb gnome org>
+ * Copyright (C) 2008 Carlos Garnacho <carlos imendio com>
*
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Red Hat not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. Red Hat makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
+ * 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.
*
- * Authors: Jonathan Blandford
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#include <gtk/gtk.h>
-
+#include "gsd-timeline.h"
#include "gsd-locate-pointer.h"
-#define LARGE_SIZE 101
-#define SMALL_SIZE 51
+#define ANIMATION_LENGTH 750
+#define WINDOW_SIZE 101
+#define N_CIRCLES 4
+
+/* All circles are supposed to be moving when progress
+ * reaches 0.5, and each of them are supposed to long
+ * for half of the progress, hence the need of 0.5 to
+ * get the circles interval, and the multiplication
+ * by 2 to know a circle progress */
+#define CIRCLES_PROGRESS_INTERVAL (0.5 / N_CIRCLES)
+#define CIRCLE_PROGRESS(p) (MIN (1., ((gdouble) (p) * 2.)))
+
+typedef struct GsdLocatePointerData GsdLocatePointerData;
-typedef enum {
- STAGE_ONE,
- STAGE_TWO,
- STAGE_THREE,
- STAGE_FOUR,
- STAGE_DONE
-} LocatePointerStage;
-
-static LocatePointerStage stage;
-static GdkWindow *window = NULL;
-static gint cursor_x, cursor_y;
-static guint locate_pointer_id = 0;
-
-static gint
-locate_pointer_expose (GtkWidget *widget,
- GdkEventExpose *event,
- gpointer data)
+struct GsdLocatePointerData
{
- gint size;
- GdkPoint points[4];
+ GsdTimeline *timeline;
+ GtkWidget *widget;
+ GdkWindow *window;
+
+ gdouble progress;
+};
+
+static GsdLocatePointerData *data = NULL;
+
+static void
+locate_pointer_paint (GsdLocatePointerData *data,
+ cairo_t *cr,
+ gboolean composite)
+{
+ GdkColor color;
+ gdouble progress, circle_progress;
+ gint width, height, i;
+
+ progress = data->progress;
+ gdk_drawable_get_size (data->window, &width, &height);
+ color = data->widget->style->bg[GTK_STATE_SELECTED];
+
+ cairo_set_source_rgba (cr, 1., 1., 1., 0.);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ for (i = 0; i <= N_CIRCLES; i++)
+ {
+ if (progress < 0.)
+ break;
+
+ circle_progress = MIN (1., (progress * 2));
+ progress -= CIRCLES_PROGRESS_INTERVAL;
+
+ if (circle_progress >= 1.)
+ continue;
- if (event->window != window)
+ if (composite)
+ {
+ cairo_set_source_rgba (cr,
+ color.red / 65535.,
+ color.green / 65535.,
+ color.blue / 65535.,
+ 1 - circle_progress);
+ cairo_arc (cr,
+ width / 2,
+ height / 2,
+ circle_progress * width / 2,
+ 0, 2 * G_PI);
+
+ cairo_fill (cr);
+ cairo_stroke (cr);
+ }
+ else
+ {
+ cairo_set_source_rgb (cr, 0., 0., 0.);
+ cairo_set_line_width (cr, 3.);
+ cairo_arc (cr,
+ width / 2,
+ height / 2,
+ circle_progress * width / 2,
+ 0, 2 * G_PI);
+ cairo_stroke (cr);
+
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_set_line_width (cr, 1.);
+ cairo_arc (cr,
+ width / 2,
+ height / 2,
+ circle_progress * width / 2,
+ 0, 2 * G_PI);
+ cairo_stroke (cr);
+ }
+ }
+}
+
+static gboolean
+locate_pointer_expose (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data)
+{
+ GsdLocatePointerData *data = (GsdLocatePointerData *) user_data;
+ cairo_t *cr;
+ GdkBitmap *mask;
+
+ if (event->window != data->window)
return FALSE;
- switch (stage)
+ cr = gdk_cairo_create (data->window);
+
+ if (gtk_widget_is_composited (data->widget))
+ locate_pointer_paint (data, cr, TRUE);
+ else
{
- case STAGE_ONE:
- case STAGE_TWO:
- size = LARGE_SIZE;
- break;
- case STAGE_THREE:
- case STAGE_FOUR:
- size = SMALL_SIZE;
- break;
- default:
- return FALSE;
- }
-
- gdk_draw_rectangle (event->window,
- widget->style->black_gc,
- TRUE,
- 0, 0, size, size);
- switch (stage)
- {
- case STAGE_ONE:
- case STAGE_THREE:
- gdk_draw_rectangle (event->window,
- widget->style->white_gc,
- FALSE,
- 1, 1, size - 3, size - 3);
- break;
- case STAGE_TWO:
- case STAGE_FOUR:
- points[0].x = size/2;
- points[0].y = 0 + 1;
- points[1].x = size - 2;
- points[1].y = size/2;
- points[2].x = size/2;
- points[2].y = size - 2;
- points[3].x = 0 + 1;
- points[3].y = size/2;
- gdk_draw_polygon (event->window,
- widget->style->white_gc,
- FALSE, points, 4);
- break;
- default:
- g_assert_not_reached ();
+ locate_pointer_paint (data, cr, FALSE);
+ cairo_destroy (cr);
+
+ /* create a bitmap for the shape, reuse the cairo_t to paint on it */
+ mask = gdk_pixmap_new (data->window, WINDOW_SIZE, WINDOW_SIZE, 1);
+ cr = gdk_cairo_create (mask);
+ locate_pointer_paint (data, cr, FALSE);
+ gdk_window_shape_combine_mask (data->window, mask, 0, 0);
}
+ cairo_destroy (cr);
+
return TRUE;
}
static void
-setup_window (void)
+timeline_frame_cb (GtkTimeline *timeline,
+ gdouble progress,
+ gpointer user_data)
{
- gint size;
- GdkBitmap *mask;
- GdkGC *gc;
- GdkColor col;
- GdkPoint points[4];
+ GsdLocatePointerData *data = (GsdLocatePointerData *) user_data;
- gdk_window_hide (window);
- switch (stage)
+ if (gtk_widget_is_composited (data->widget))
{
- case STAGE_ONE:
- case STAGE_TWO:
- size = LARGE_SIZE;
- break;
- case STAGE_THREE:
- case STAGE_FOUR:
- size = SMALL_SIZE;
- break;
- default:
- return;
- }
-
- gdk_window_move_resize (window,
- cursor_x - size/2,
- cursor_y - size/2,
- size, size);
- mask = gdk_pixmap_new (window, size, size, 1);
- gc = gdk_gc_new (mask);
- switch (stage)
+ gdk_window_invalidate_rect (data->window, NULL, FALSE);
+ data->progress = progress;
+ }
+ else if (progress >= data->progress + CIRCLES_PROGRESS_INTERVAL)
{
- case STAGE_ONE:
- case STAGE_THREE:
- col.pixel = 1;
- gdk_gc_set_foreground (gc, &col);
- gdk_draw_rectangle (mask, gc, TRUE, 0, 0, size, size);
- col.pixel = 0;
- gdk_gc_set_foreground (gc, &col);
- gdk_draw_rectangle (mask, gc, TRUE, 3, 3, size - 6, size - 6);
- break;
- case STAGE_TWO:
- case STAGE_FOUR:
- col.pixel = 0;
- gdk_gc_set_foreground (gc, &col);
- gdk_draw_rectangle (mask, gc, TRUE, 0, 0, size, size);
- col.pixel = 1;
- gdk_gc_set_foreground (gc, &col);
- points[0].x = size/2;
- points[0].y = 0;
- points[1].x = size - 1;
- points[1].y = size/2;
- points[2].x = size/2;
- points[2].y = size - 1;
- points[3].x = 0;
- points[3].y = size/2;
- gdk_draw_polygon (mask, gc, FALSE, points, 4);
- points[0].x = size/2;
- points[0].y = 0 + 1;
- points[1].x = size - 2;
- points[1].y = size/2;
- points[2].x = size/2;
- points[2].y = size - 2;
- points[3].x = 0 + 1;
- points[3].y = size/2;
- gdk_draw_polygon (mask, gc, FALSE, points, 4);
- points[0].x = size/2;
- points[0].y = 0 + 2;
- points[1].x = size - 3;
- points[1].y = size/2;
- points[2].x = size/2;
- points[2].y = size - 3;
- points[3].x = 0 + 2;
- points[3].y = size/2;
- gdk_draw_polygon (mask, gc, FALSE, points, 4);
- break;
- default:
- g_assert_not_reached ();
- }
-
- gdk_window_shape_combine_mask (window, mask, 0, 0);
- g_object_unref (G_OBJECT (gc));
- g_object_unref (G_OBJECT (mask));
- gdk_window_show (window);
+ /* only invalidate window each circle interval */
+ gdk_window_invalidate_rect (data->window, NULL, FALSE);
+ data->progress += CIRCLES_PROGRESS_INTERVAL;
+ }
+}
+
+static void
+timeline_finished_cb (GtkTimeline *timeline,
+ gpointer user_data)
+{
+ GsdLocatePointerData *data = (GsdLocatePointerData *) user_data;
+
+ /* hide window and unset shape */
+ gdk_window_hide (data->window);
+ gdk_window_shape_combine_mask (data->window, NULL, 0, 0);
}
static void
-create_window (GdkScreen *screen)
+create_window (GsdLocatePointerData *data,
+ GdkScreen *screen)
{
+ GdkColormap *colormap;
+ GdkVisual *visual;
GdkWindowAttr attributes;
- GtkWidget *invisible;
- invisible = gtk_invisible_new_for_screen (screen);
+ colormap = gdk_screen_get_rgba_colormap (screen);
+ visual = gdk_screen_get_rgba_visual (screen);
+
+ if (!colormap)
+ {
+ colormap = gdk_screen_get_rgb_colormap (screen);
+ visual = gdk_screen_get_rgb_visual (screen);
+ }
attributes.window_type = GDK_WINDOW_TEMP;
attributes.wclass = GDK_INPUT_OUTPUT;
- attributes.visual = gtk_widget_get_visual (invisible);
- attributes.colormap = gtk_widget_get_colormap (invisible);
+ attributes.visual = visual;
+ attributes.colormap = colormap;
attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK;
attributes.width = 1;
attributes.height = 1;
- window = gdk_window_new (gdk_screen_get_root_window (screen),
- &attributes,
- GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP);
- gdk_window_set_user_data (window, invisible);
- g_signal_connect (G_OBJECT (invisible),
- "expose_event",
- (GCallback) locate_pointer_expose,
- NULL);
+
+ data->window = gdk_window_new (gdk_screen_get_root_window (screen),
+ &attributes,
+ GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP);
+
+ gdk_window_set_user_data (data->window, data->widget);
}
-static gboolean
-locate_pointer_timeout (gpointer data)
+static GsdLocatePointerData *
+gsd_locate_pointer_data_new (GdkScreen *screen)
{
- stage++;
- if (stage == STAGE_DONE)
- {
- gdk_window_hide (window);
- locate_pointer_id = 0;
- return FALSE;
- }
- setup_window ();
- return TRUE;
+ GsdLocatePointerData *data;
+
+ data = g_new0 (GsdLocatePointerData, 1);
+
+ /* this widget will never be shown, it's
+ * mainly used to get signals/events from
+ */
+ data->widget = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_widget_realize (data->widget);
+
+ g_signal_connect (G_OBJECT (data->widget), "expose_event",
+ G_CALLBACK (locate_pointer_expose),
+ data);
+
+ data->timeline = gsd_timeline_new (ANIMATION_LENGTH);
+ g_signal_connect (data->timeline, "frame",
+ G_CALLBACK (timeline_frame_cb), data);
+ g_signal_connect (data->timeline, "finished",
+ G_CALLBACK (timeline_finished_cb), data);
+
+ create_window (data, screen);
+
+ return data;
+}
+
+static void
+move_locate_pointer_window (GsdLocatePointerData *data,
+ GdkScreen *screen)
+{
+ gint cursor_x, cursor_y;
+ GdkBitmap *mask;
+ GdkColor col;
+ GdkGC *gc;
+
+ gdk_window_get_pointer (gdk_screen_get_root_window (screen), &cursor_x, &cursor_y, NULL);
+
+ gdk_window_move_resize (data->window,
+ cursor_x - WINDOW_SIZE / 2,
+ cursor_y - WINDOW_SIZE / 2,
+ WINDOW_SIZE, WINDOW_SIZE);
+
+ col.pixel = 0;
+ mask = gdk_pixmap_new (data->window, WINDOW_SIZE, WINDOW_SIZE, 1);
+
+ gc = gdk_gc_new (mask);
+ gdk_gc_set_foreground (gc, &col);
+ gdk_draw_rectangle (mask, gc, TRUE, 0, 0, WINDOW_SIZE, WINDOW_SIZE);
+
+ /* allow events to happen through the window */
+ gdk_window_input_shape_combine_mask (data->window, mask, 0, 0);
+
+ g_object_unref (mask);
+ g_object_unref (gc);
}
void
gsd_locate_pointer (GdkScreen *screen)
{
- gdk_window_get_pointer (gdk_screen_get_root_window (screen), &cursor_x, &cursor_y, NULL);
+ if (!data)
+ data = gsd_locate_pointer_data_new (screen);
- if (locate_pointer_id)
- gtk_timeout_remove (locate_pointer_id);
+ gsd_timeline_pause (data->timeline);
+ gsd_timeline_rewind (data->timeline);
- /* Create the window if it is not created OR if it is not for the
- * current screen.
- */
+ /* Create again the window if it is not for the current screen */
+ if (gdk_screen_get_number (screen) != gdk_screen_get_number (gdk_drawable_get_screen (data->window)))
+ {
+ gdk_window_set_user_data (data->window, NULL);
+ gdk_window_destroy (data->window);
+
+ create_window (data, screen);
+ }
+
+ data->progress = 0.;
+ gdk_window_show (data->window);
+ move_locate_pointer_window (data, screen);
- if (window == NULL)
- create_window (screen);
- else if( gdk_screen_get_number (screen) != gdk_screen_get_number (gdk_drawable_get_screen (window)))
- create_window (screen);
-
- stage = STAGE_ONE;
- setup_window ();
- gdk_window_show (window);
- locate_pointer_id = gtk_timeout_add (100, locate_pointer_timeout, NULL);
+ gsd_timeline_start (data->timeline);
}
Added: trunk/plugins/mouse/gsd-timeline.c
==============================================================================
--- (empty file)
+++ trunk/plugins/mouse/gsd-timeline.c Tue Jan 22 16:15:41 2008
@@ -0,0 +1,848 @@
+/* gsd-timeline.c
+ *
+ * Copyright (C) 2008 Carlos Garnacho <carlos imendio com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <math.h>
+#include "gsd-timeline.h"
+
+#define GSD_TIMELINE_GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GSD_TYPE_TIMELINE, GsdTimelinePriv))
+#define MSECS_PER_SEC 1000
+#define FRAME_INTERVAL(nframes) (MSECS_PER_SEC / nframes)
+#define DEFAULT_FPS 30
+
+typedef struct GsdTimelinePriv GsdTimelinePriv;
+
+struct GsdTimelinePriv
+{
+ guint duration;
+ guint fps;
+ guint source_id;
+
+ GTimer *timer;
+
+ GdkScreen *screen;
+ GsdTimelineProgressType progress_type;
+ GsdTimelineProgressFunc progress_func;
+
+ guint loop : 1;
+ guint direction : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_FPS,
+ PROP_DURATION,
+ PROP_LOOP,
+ PROP_DIRECTION,
+ PROP_SCREEN,
+ PROP_PROGRESS_TYPE,
+};
+
+enum {
+ STARTED,
+ PAUSED,
+ FINISHED,
+ FRAME,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
+
+static void gsd_timeline_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gsd_timeline_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gsd_timeline_finalize (GObject *object);
+
+
+G_DEFINE_TYPE (GsdTimeline, gsd_timeline, G_TYPE_OBJECT)
+
+
+GType
+gsd_timeline_direction_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0))
+ {
+ static const GEnumValue values[] = {
+ { GSD_TIMELINE_DIRECTION_FORWARD, "GSD_TIMELINE_DIRECTION_FORWARD", "forward" },
+ { GSD_TIMELINE_DIRECTION_BACKWARD, "GSD_TIMELINE_DIRECTION_BACKWARD", "backward" },
+ { 0, NULL, NULL }
+ };
+
+ type = g_enum_register_static (g_intern_static_string ("GsdTimelineDirection"), values);
+ }
+
+ return type;
+}
+
+GType
+gsd_timeline_progress_type_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0))
+ {
+ static const GEnumValue values[] = {
+ { GSD_TIMELINE_PROGRESS_LINEAR, "GSD_TIMELINE_PROGRESS_LINEAR", "linear" },
+ { GSD_TIMELINE_PROGRESS_SINUSOIDAL, "GSD_TIMELINE_PROGRESS_SINUSOIDAL", "sinusoidal" },
+ { GSD_TIMELINE_PROGRESS_EXPONENTIAL, "GSD_TIMELINE_PROGRESS_EXPONENTIAL", "exponential" },
+ { 0, NULL, NULL }
+ };
+
+ type = g_enum_register_static (g_intern_static_string ("GsdTimelineProgressType"), values);
+ }
+
+ return type;
+}
+
+static void
+gsd_timeline_class_init (GsdTimelineClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->set_property = gsd_timeline_set_property;
+ object_class->get_property = gsd_timeline_get_property;
+ object_class->finalize = gsd_timeline_finalize;
+
+ g_object_class_install_property (object_class,
+ PROP_FPS,
+ g_param_spec_uint ("fps",
+ "FPS",
+ "Frames per second for the timeline",
+ 1,
+ G_MAXUINT,
+ DEFAULT_FPS,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_DURATION,
+ g_param_spec_uint ("duration",
+ "Animation Duration",
+ "Animation Duration",
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_LOOP,
+ g_param_spec_boolean ("loop",
+ "Loop",
+ "Whether the timeline loops or not",
+ FALSE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_DIRECTION,
+ g_param_spec_enum ("direction",
+ "Direction",
+ "Whether the timeline moves forward or backward in time",
+ GSD_TYPE_TIMELINE_DIRECTION,
+ GSD_TIMELINE_DIRECTION_FORWARD,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_DIRECTION,
+ g_param_spec_enum ("progress-type",
+ "Progress type",
+ "Type of progress through the timeline",
+ GSD_TYPE_TIMELINE_PROGRESS_TYPE,
+ GSD_TIMELINE_PROGRESS_LINEAR,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_SCREEN,
+ g_param_spec_object ("screen",
+ "Screen",
+ "Screen to get the settings from",
+ GDK_TYPE_SCREEN,
+ G_PARAM_READWRITE));
+
+ signals[STARTED] =
+ g_signal_new ("started",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsdTimelineClass, started),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[PAUSED] =
+ g_signal_new ("paused",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsdTimelineClass, paused),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[FINISHED] =
+ g_signal_new ("finished",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsdTimelineClass, finished),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[FRAME] =
+ g_signal_new ("frame",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsdTimelineClass, frame),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__DOUBLE,
+ G_TYPE_NONE, 1,
+ G_TYPE_DOUBLE);
+
+ g_type_class_add_private (class, sizeof (GsdTimelinePriv));
+}
+
+static void
+gsd_timeline_init (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ priv->fps = DEFAULT_FPS;
+ priv->duration = 0;
+ priv->direction = GSD_TIMELINE_DIRECTION_FORWARD;
+ priv->screen = gdk_screen_get_default ();
+}
+
+static void
+gsd_timeline_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GsdTimeline *timeline;
+ GsdTimelinePriv *priv;
+
+ timeline = GSD_TIMELINE (object);
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ switch (prop_id)
+ {
+ case PROP_FPS:
+ gsd_timeline_set_fps (timeline, g_value_get_uint (value));
+ break;
+ case PROP_DURATION:
+ gsd_timeline_set_duration (timeline, g_value_get_uint (value));
+ break;
+ case PROP_LOOP:
+ gsd_timeline_set_loop (timeline, g_value_get_boolean (value));
+ break;
+ case PROP_DIRECTION:
+ gsd_timeline_set_direction (timeline, g_value_get_enum (value));
+ break;
+ case PROP_SCREEN:
+ gsd_timeline_set_screen (timeline,
+ GDK_SCREEN (g_value_get_object (value)));
+ break;
+ case PROP_PROGRESS_TYPE:
+ gsd_timeline_set_progress_type (timeline, g_value_get_enum (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gsd_timeline_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GsdTimeline *timeline;
+ GsdTimelinePriv *priv;
+
+ timeline = GSD_TIMELINE (object);
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ switch (prop_id)
+ {
+ case PROP_FPS:
+ g_value_set_uint (value, priv->fps);
+ break;
+ case PROP_DURATION:
+ g_value_set_uint (value, priv->duration);
+ break;
+ case PROP_LOOP:
+ g_value_set_boolean (value, priv->loop);
+ break;
+ case PROP_DIRECTION:
+ g_value_set_enum (value, priv->direction);
+ break;
+ case PROP_SCREEN:
+ g_value_set_object (value, priv->screen);
+ break;
+ case PROP_PROGRESS_TYPE:
+ g_value_set_enum (value, priv->progress_type);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gsd_timeline_finalize (GObject *object)
+{
+ GsdTimelinePriv *priv;
+
+ priv = GSD_TIMELINE_GET_PRIV (object);
+
+ if (priv->source_id)
+ {
+ g_source_remove (priv->source_id);
+ priv->source_id = 0;
+ }
+
+ if (priv->timer)
+ g_timer_destroy (priv->timer);
+
+ G_OBJECT_CLASS (gsd_timeline_parent_class)->finalize (object);
+}
+
+/* Sinusoidal progress */
+static gdouble
+sinusoidal_progress (gdouble progress)
+{
+ return (sinf ((progress * G_PI) / 2));
+}
+
+static gdouble
+exponential_progress (gdouble progress)
+{
+ return progress * progress;
+}
+
+static GsdTimelineProgressFunc
+progress_type_to_func (GsdTimelineProgressType type)
+{
+ if (type == GSD_TIMELINE_PROGRESS_SINUSOIDAL)
+ return sinusoidal_progress;
+ else if (type == GSD_TIMELINE_PROGRESS_EXPONENTIAL)
+ return exponential_progress;
+
+ return NULL;
+}
+
+static gboolean
+gsd_timeline_run_frame (GsdTimeline *timeline,
+ gboolean enable_animations)
+{
+ GsdTimelinePriv *priv;
+ gdouble linear_progress, progress;
+ guint elapsed_time;
+ GsdTimelineProgressFunc progress_func = NULL;
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ if (enable_animations)
+ {
+ elapsed_time = (guint) (g_timer_elapsed (priv->timer, NULL) * 1000);
+
+ linear_progress = (gdouble) elapsed_time / priv->duration;
+
+ if (priv->direction == GSD_TIMELINE_DIRECTION_BACKWARD)
+ linear_progress = 1 - linear_progress;
+
+ linear_progress = CLAMP (linear_progress, 0., 1.);
+
+ if (priv->progress_func)
+ progress_func = priv->progress_func;
+ else if (priv->progress_type)
+ progress_func = progress_type_to_func (priv->progress_type);
+
+ if (progress_func)
+ progress = (progress_func) (linear_progress);
+ else
+ progress = linear_progress;
+ }
+ else
+ progress = (priv->direction == GSD_TIMELINE_DIRECTION_FORWARD) ? 1.0 : 0.0;
+
+ g_signal_emit (timeline, signals [FRAME], 0,
+ CLAMP (progress, 0.0, 1.0));
+
+ if ((priv->direction == GSD_TIMELINE_DIRECTION_FORWARD && progress >= 1.0) ||
+ (priv->direction == GSD_TIMELINE_DIRECTION_BACKWARD && progress <= 0.0))
+ {
+ if (!priv->loop)
+ {
+ if (priv->source_id)
+ {
+ g_source_remove (priv->source_id);
+ priv->source_id = 0;
+ }
+
+ g_signal_emit (timeline, signals [FINISHED], 0);
+ return FALSE;
+ }
+ else
+ gsd_timeline_rewind (timeline);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+gsd_timeline_frame_idle_func (GsdTimeline *timeline)
+{
+ return gsd_timeline_run_frame (timeline, TRUE);
+}
+
+/**
+ * gsd_timeline_new:
+ * @duration: duration in milliseconds for the timeline
+ *
+ * Creates a new #GsdTimeline with the specified number of frames.
+ *
+ * Return Value: the newly created #GsdTimeline
+ **/
+GsdTimeline *
+gsd_timeline_new (guint duration)
+{
+ return g_object_new (GSD_TYPE_TIMELINE,
+ "duration", duration,
+ NULL);
+}
+
+GsdTimeline *
+gsd_timeline_new_for_screen (guint duration,
+ GdkScreen *screen)
+{
+ return g_object_new (GSD_TYPE_TIMELINE,
+ "duration", duration,
+ "screen", screen,
+ NULL);
+}
+
+/**
+ * gsd_timeline_start:
+ * @timeline: A #GsdTimeline
+ *
+ * Runs the timeline from the current frame.
+ **/
+void
+gsd_timeline_start (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+ GtkSettings *settings;
+ gboolean enable_animations = FALSE;
+
+ g_return_if_fail (GSD_IS_TIMELINE (timeline));
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ if (priv->screen)
+ {
+ settings = gtk_settings_get_for_screen (priv->screen);
+ g_object_get (settings, "gtk-enable-animations", &enable_animations, NULL);
+ }
+
+ if (enable_animations)
+ {
+ if (!priv->source_id)
+ {
+ if (priv->timer)
+ g_timer_continue (priv->timer);
+ else
+ priv->timer = g_timer_new ();
+
+ /* sanity check */
+ g_assert (priv->fps > 0);
+
+ g_signal_emit (timeline, signals [STARTED], 0);
+
+ priv->source_id = gdk_threads_add_timeout (FRAME_INTERVAL (priv->fps),
+ (GSourceFunc) gsd_timeline_frame_idle_func,
+ timeline);
+ }
+ }
+ else
+ {
+ /* If animations are not enabled, only run the last frame,
+ * it take us instantaneously to the last state of the animation.
+ * The only potential flaw happens when people use the ::finished
+ * signal to trigger another animation, or even worse, finally
+ * loop into this animation again.
+ */
+ g_signal_emit (timeline, signals [STARTED], 0);
+ gsd_timeline_run_frame (timeline, FALSE);
+ }
+}
+
+/**
+ * gsd_timeline_pause:
+ * @timeline: A #GsdTimeline
+ *
+ * Pauses the timeline.
+ **/
+void
+gsd_timeline_pause (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_if_fail (GSD_IS_TIMELINE (timeline));
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ if (priv->source_id)
+ {
+ g_source_remove (priv->source_id);
+ priv->source_id = 0;
+ g_timer_stop (priv->timer);
+ g_signal_emit (timeline, signals [PAUSED], 0);
+ }
+}
+
+/**
+ * gsd_timeline_rewind:
+ * @timeline: A #GsdTimeline
+ *
+ * Rewinds the timeline.
+ **/
+void
+gsd_timeline_rewind (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_if_fail (GSD_IS_TIMELINE (timeline));
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ /* destroy and re-create timer if neccesary */
+ if (priv->timer)
+ {
+ g_timer_destroy (priv->timer);
+
+ if (gsd_timeline_is_running (timeline))
+ priv->timer = g_timer_new ();
+ else
+ priv->timer = NULL;
+ }
+}
+
+/**
+ * gsd_timeline_is_running:
+ * @timeline: A #GsdTimeline
+ *
+ * Returns whether the timeline is running or not.
+ *
+ * Return Value: %TRUE if the timeline is running
+ **/
+gboolean
+gsd_timeline_is_running (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_val_if_fail (GSD_IS_TIMELINE (timeline), FALSE);
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ return (priv->source_id != 0);
+}
+
+/**
+ * gsd_timeline_get_fps:
+ * @timeline: A #GsdTimeline
+ *
+ * Returns the number of frames per second.
+ *
+ * Return Value: frames per second
+ **/
+guint
+gsd_timeline_get_fps (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_val_if_fail (GSD_IS_TIMELINE (timeline), 1);
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+ return priv->fps;
+}
+
+/**
+ * gsd_timeline_set_fps:
+ * @timeline: A #GsdTimeline
+ * @fps: frames per second
+ *
+ * Sets the number of frames per second that
+ * the timeline will play.
+ **/
+void
+gsd_timeline_set_fps (GsdTimeline *timeline,
+ guint fps)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_if_fail (GSD_IS_TIMELINE (timeline));
+ g_return_if_fail (fps > 0);
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ priv->fps = fps;
+
+ if (gsd_timeline_is_running (timeline))
+ {
+ g_source_remove (priv->source_id);
+ priv->source_id = gdk_threads_add_timeout (FRAME_INTERVAL (priv->fps),
+ (GSourceFunc) gsd_timeline_run_frame,
+ timeline);
+ }
+
+ g_object_notify (G_OBJECT (timeline), "fps");
+}
+
+/**
+ * gsd_timeline_get_loop:
+ * @timeline: A #GsdTimeline
+ *
+ * Returns whether the timeline loops to the
+ * beginning when it has reached the end.
+ *
+ * Return Value: %TRUE if the timeline loops
+ **/
+gboolean
+gsd_timeline_get_loop (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_val_if_fail (GSD_IS_TIMELINE (timeline), FALSE);
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+ return priv->loop;
+}
+
+/**
+ * gsd_timeline_set_loop:
+ * @timeline: A #GsdTimeline
+ * @loop: %TRUE to make the timeline loop
+ *
+ * Sets whether the timeline loops to the beginning
+ * when it has reached the end.
+ **/
+void
+gsd_timeline_set_loop (GsdTimeline *timeline,
+ gboolean loop)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_if_fail (GSD_IS_TIMELINE (timeline));
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+ priv->loop = loop;
+
+ g_object_notify (G_OBJECT (timeline), "loop");
+}
+
+void
+gsd_timeline_set_duration (GsdTimeline *timeline,
+ guint duration)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_if_fail (GSD_IS_TIMELINE (timeline));
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ priv->duration = duration;
+
+ g_object_notify (G_OBJECT (timeline), "duration");
+}
+
+guint
+gsd_timeline_get_duration (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_val_if_fail (GSD_IS_TIMELINE (timeline), 0);
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ return priv->duration;
+}
+
+/**
+ * gsd_timeline_get_direction:
+ * @timeline: A #GsdTimeline
+ *
+ * Returns the direction of the timeline.
+ *
+ * Return Value: direction
+ **/
+GsdTimelineDirection
+gsd_timeline_get_direction (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_val_if_fail (GSD_IS_TIMELINE (timeline), GSD_TIMELINE_DIRECTION_FORWARD);
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+ return priv->direction;
+}
+
+/**
+ * gsd_timeline_set_direction:
+ * @timeline: A #GsdTimeline
+ * @direction: direction
+ *
+ * Sets the direction of the timeline.
+ **/
+void
+gsd_timeline_set_direction (GsdTimeline *timeline,
+ GsdTimelineDirection direction)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_if_fail (GSD_IS_TIMELINE (timeline));
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+ priv->direction = direction;
+
+ g_object_notify (G_OBJECT (timeline), "direction");
+}
+
+GdkScreen *
+gsd_timeline_get_screen (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_val_if_fail (GSD_IS_TIMELINE (timeline), NULL);
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+ return priv->screen;
+}
+
+void
+gsd_timeline_set_screen (GsdTimeline *timeline,
+ GdkScreen *screen)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_if_fail (GSD_IS_TIMELINE (timeline));
+ g_return_if_fail (GDK_IS_SCREEN (screen));
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ if (priv->screen)
+ g_object_unref (priv->screen);
+
+ priv->screen = g_object_ref (screen);
+
+ g_object_notify (G_OBJECT (timeline), "screen");
+}
+
+void
+gsd_timeline_set_progress_type (GsdTimeline *timeline,
+ GsdTimelineProgressType type)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_if_fail (GSD_IS_TIMELINE (timeline));
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ priv->progress_type = type;
+
+ g_object_notify (G_OBJECT (timeline), "progress-type");
+}
+
+GsdTimelineProgressType
+gsd_timeline_get_progress_type (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_val_if_fail (GSD_IS_TIMELINE (timeline), GSD_TIMELINE_PROGRESS_LINEAR);
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ if (priv->progress_func)
+ return GSD_TIMELINE_PROGRESS_LINEAR;
+
+ return priv->progress_type;
+}
+
+/**
+ * gsd_timeline_set_progress_func:
+ * @timeline: A #GsdTimeline
+ * @progress_func: progress function
+ *
+ * Sets the progress function. This function will be used to calculate
+ * a different progress to pass to the ::frame signal based on the
+ * linear progress through the timeline. Setting progress_func
+ * to %NULL will make the timeline use the default function,
+ * which is just a linear progress.
+ *
+ * All progresses are in the [0.0, 1.0] range.
+ **/
+void
+gsd_timeline_set_progress_func (GsdTimeline *timeline,
+ GsdTimelineProgressFunc progress_func)
+{
+ GsdTimelinePriv *priv;
+
+ g_return_if_fail (GSD_IS_TIMELINE (timeline));
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+ priv->progress_func = progress_func;
+}
+
+gdouble
+gsd_timeline_get_progress (GsdTimeline *timeline)
+{
+ GsdTimelinePriv *priv;
+ GsdTimelineProgressFunc progress_func = NULL;
+ gdouble linear_progress, progress;
+ guint elapsed_time;
+
+ g_return_val_if_fail (GSD_IS_TIMELINE (timeline), 0.0);
+
+ priv = GSD_TIMELINE_GET_PRIV (timeline);
+
+ if (!priv->timer)
+ return 0.;
+
+ elapsed_time = (guint) (g_timer_elapsed (priv->timer, NULL) * 1000);
+
+ linear_progress = (gdouble) elapsed_time / priv->duration;
+
+ if (priv->direction == GSD_TIMELINE_DIRECTION_BACKWARD)
+ linear_progress = 1 - linear_progress;
+
+ linear_progress = CLAMP (linear_progress, 0., 1.);
+
+ if (priv->progress_func)
+ progress_func = priv->progress_func;
+ else if (priv->progress_type)
+ progress_func = progress_type_to_func (priv->progress_type);
+
+ if (progress_func)
+ progress = (progress_func) (linear_progress);
+ else
+ progress = linear_progress;
+
+ return CLAMP (progress, 0., 1.);
+}
Added: trunk/plugins/mouse/gsd-timeline.h
==============================================================================
--- (empty file)
+++ trunk/plugins/mouse/gsd-timeline.h Tue Jan 22 16:15:41 2008
@@ -0,0 +1,123 @@
+/* gsdtimeline.c
+ *
+ * Copyright (C) 2008 Carlos Garnacho <carlos imendio com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GSD_TIMELINE_H__
+#define __GSD_TIMELINE_H__
+
+#include <glib-object.h>
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+#define GSD_TYPE_TIMELINE_DIRECTION (gsd_timeline_direction_get_type ())
+#define GSD_TYPE_TIMELINE_PROGRESS_TYPE (gsd_timeline_progress_type_get_type ())
+#define GSD_TYPE_TIMELINE (gsd_timeline_get_type ())
+#define GSD_TIMELINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_TIMELINE, GsdTimeline))
+#define GSD_TIMELINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_TIMELINE, GsdTimelineClass))
+#define GSD_IS_TIMELINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_TIMELINE))
+#define GSD_IS_TIMELINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSD_TYPE_TIMELINE))
+#define GSD_TIMELINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSD_TYPE_TIMELINE, GsdTimelineClass))
+
+typedef enum {
+ GSD_TIMELINE_DIRECTION_FORWARD,
+ GSD_TIMELINE_DIRECTION_BACKWARD
+} GsdTimelineDirection;
+
+typedef enum {
+ GSD_TIMELINE_PROGRESS_LINEAR,
+ GSD_TIMELINE_PROGRESS_SINUSOIDAL,
+ GSD_TIMELINE_PROGRESS_EXPONENTIAL
+} GsdTimelineProgressType;
+
+typedef struct GsdTimeline GsdTimeline;
+typedef struct GsdTimelineClass GsdTimelineClass;
+
+struct GsdTimeline
+{
+ GObject parent_instance;
+};
+
+struct GsdTimelineClass
+{
+ GObjectClass parent_class;
+
+ void (* started) (GsdTimeline *timeline);
+ void (* finished) (GsdTimeline *timeline);
+ void (* paused) (GsdTimeline *timeline);
+
+ void (* frame) (GsdTimeline *timeline,
+ gdouble progress);
+
+ void (* __gsd_reserved1) (void);
+ void (* __gsd_reserved2) (void);
+ void (* __gsd_reserved3) (void);
+ void (* __gsd_reserved4) (void);
+};
+
+typedef gdouble (*GsdTimelineProgressFunc) (gdouble progress);
+
+
+GType gsd_timeline_get_type (void) G_GNUC_CONST;
+GType gsd_timeline_direction_get_type (void) G_GNUC_CONST;
+GType gsd_timeline_progress_type_get_type (void) G_GNUC_CONST;
+
+GsdTimeline *gsd_timeline_new (guint duration);
+GsdTimeline *gsd_timeline_new_for_screen (guint duration,
+ GdkScreen *screen);
+
+void gsd_timeline_start (GsdTimeline *timeline);
+void gsd_timeline_pause (GsdTimeline *timeline);
+void gsd_timeline_rewind (GsdTimeline *timeline);
+
+gboolean gsd_timeline_is_running (GsdTimeline *timeline);
+
+guint gsd_timeline_get_fps (GsdTimeline *timeline);
+void gsd_timeline_set_fps (GsdTimeline *timeline,
+ guint fps);
+
+gboolean gsd_timeline_get_loop (GsdTimeline *timeline);
+void gsd_timeline_set_loop (GsdTimeline *timeline,
+ gboolean loop);
+
+guint gsd_timeline_get_duration (GsdTimeline *timeline);
+void gsd_timeline_set_duration (GsdTimeline *timeline,
+ guint duration);
+
+GdkScreen *gsd_timeline_get_screen (GsdTimeline *timeline);
+void gsd_timeline_set_screen (GsdTimeline *timeline,
+ GdkScreen *screen);
+
+GsdTimelineDirection gsd_timeline_get_direction (GsdTimeline *timeline);
+void gsd_timeline_set_direction (GsdTimeline *timeline,
+ GsdTimelineDirection direction);
+
+GsdTimelineProgressType gsd_timeline_get_progress_type (GsdTimeline *timeline);
+void gsd_timeline_set_progress_type (GsdTimeline *timeline,
+ GsdTimelineProgressType type);
+void gsd_timeline_get_progress_func (GsdTimeline *timeline);
+
+void gsd_timeline_set_progress_func (GsdTimeline *timeline,
+ GsdTimelineProgressFunc progress_func);
+
+gdouble gsd_timeline_get_progress (GsdTimeline *timeline);
+
+
+G_END_DECLS
+
+#endif /* __GSD_TIMELINE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]