Commit 5f2d1654 authored by Owen W. Taylor's avatar Owen W. Taylor

Change GdkFrameClock from an interface to a class

It's unlikely that anyone will want to have, say, a GtkWidget that
also acts as a GdkFrameClock, so an abstract base class is as
flexible as making GdkFrameClock an interface, but has advantages:

 - If we decide to never make implementing your own frame clock
   possible, we can remove the virtualization.
 - We can put functionality like history into the base class.
 - Avoids the oddity of a interface without a public interface
   VTable, which may cause problems for language bindings.
parent be22b9fb
......@@ -105,6 +105,7 @@ gdk_private_headers = \
gdkdisplayprivate.h \
gdkdndprivate.h \
gdkframeclockidle.h \
gdkframeclockprivate.h \
gdkscreenprivate.h \
gdkinternals.h \
gdkintl.h \
......
......@@ -26,7 +26,7 @@
#include "config.h"
#include "gdkframeclock.h"
#include "gdkframeclockprivate.h"
/**
* SECTION:frameclock
......@@ -74,7 +74,7 @@
* time that doesn't have a lot to do with wall clock time.
*/
G_DEFINE_INTERFACE (GdkFrameClock, gdk_frame_clock, G_TYPE_OBJECT)
G_DEFINE_ABSTRACT_TYPE (GdkFrameClock, gdk_frame_clock, G_TYPE_OBJECT)
enum {
FRAME_REQUESTED,
......@@ -90,9 +90,28 @@ enum {
static guint signals[LAST_SIGNAL];
struct _GdkFrameClockPrivate
{
GdkFrameHistory *history;
};
static void
gdk_frame_clock_finalize (GObject *object)
{
GdkFrameClockPrivate *priv = GDK_FRAME_CLOCK (object)->priv;
g_object_unref (priv->history);
G_OBJECT_CLASS (gdk_frame_clock_parent_class)->finalize (object);
}
static void
gdk_frame_clock_default_init (GdkFrameClockInterface *iface)
gdk_frame_clock_class_init (GdkFrameClockClass *klass)
{
GObjectClass *gobject_class = (GObjectClass*) klass;
gobject_class->finalize = gdk_frame_clock_finalize;
/**
* GdkFrameClock::frame-requested:
* @clock: the frame clock emitting the signal
......@@ -221,6 +240,21 @@ gdk_frame_clock_default_init (GdkFrameClockInterface *iface)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
g_type_class_add_private (klass, sizeof (GdkFrameClockPrivate));
}
static void
gdk_frame_clock_init (GdkFrameClock *clock)
{
GdkFrameClockPrivate *priv;
clock->priv = G_TYPE_INSTANCE_GET_PRIVATE (clock,
GDK_TYPE_FRAME_CLOCK,
GdkFrameClockPrivate);
priv = clock->priv;
priv->history = gdk_frame_history_new ();
}
/**
......@@ -247,7 +281,7 @@ gdk_frame_clock_get_frame_time (GdkFrameClock *clock)
{
g_return_val_if_fail (GDK_IS_FRAME_CLOCK (clock), 0);
return GDK_FRAME_CLOCK_GET_IFACE (clock)->get_frame_time (clock);
return GDK_FRAME_CLOCK_GET_CLASS (clock)->get_frame_time (clock);
}
/**
......@@ -270,7 +304,7 @@ gdk_frame_clock_request_phase (GdkFrameClock *clock,
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
GDK_FRAME_CLOCK_GET_IFACE (clock)->request_phase (clock, phase);
GDK_FRAME_CLOCK_GET_CLASS (clock)->request_phase (clock, phase);
}
......@@ -279,7 +313,7 @@ gdk_frame_clock_freeze (GdkFrameClock *clock)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
GDK_FRAME_CLOCK_GET_IFACE (clock)->freeze (clock);
GDK_FRAME_CLOCK_GET_CLASS (clock)->freeze (clock);
}
......@@ -288,7 +322,7 @@ gdk_frame_clock_thaw (GdkFrameClock *clock)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
GDK_FRAME_CLOCK_GET_IFACE (clock)->thaw (clock);
GDK_FRAME_CLOCK_GET_CLASS (clock)->thaw (clock);
}
/**
......@@ -303,9 +337,13 @@ gdk_frame_clock_thaw (GdkFrameClock *clock)
GdkFrameHistory *
gdk_frame_clock_get_history (GdkFrameClock *clock)
{
GdkFrameClockPrivate *priv;
g_return_val_if_fail (GDK_IS_FRAME_CLOCK (clock), NULL);
return GDK_FRAME_CLOCK_GET_IFACE (clock)->get_history (clock);
priv = clock->priv;
return priv->history;
}
/**
......@@ -324,7 +362,7 @@ gdk_frame_clock_get_requested (GdkFrameClock *clock)
{
g_return_val_if_fail (GDK_IS_FRAME_CLOCK (clock), FALSE);
return GDK_FRAME_CLOCK_GET_IFACE (clock)->get_requested (clock);
return GDK_FRAME_CLOCK_GET_CLASS (clock)->get_requested (clock);
}
/**
......@@ -350,22 +388,6 @@ gdk_frame_clock_get_frame_time_val (GdkFrameClock *clock,
timeval->tv_usec = (time_ms % 1000) * 1000;
}
/**
* gdk_frame_clock_frame_requested:
* @clock: the clock
*
* Emits the frame-requested signal. Used in implementations of the
* #GdkFrameClock interface.
*/
void
gdk_frame_clock_frame_requested (GdkFrameClock *clock)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
g_signal_emit (G_OBJECT (clock),
signals[FRAME_REQUESTED], 0);
}
GdkFrameTimings *
gdk_frame_clock_get_current_frame_timings (GdkFrameClock *clock)
{
......
......@@ -35,13 +35,16 @@
G_BEGIN_DECLS
typedef struct _GdkFrameClock GdkFrameClock;
typedef struct _GdkFrameClockInterface GdkFrameClockInterface;
#define GDK_TYPE_FRAME_CLOCK (gdk_frame_clock_get_type ())
#define GDK_FRAME_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_FRAME_CLOCK, GdkFrameClock))
#define GDK_FRAME_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_FRAME_CLOCK, GdkFrameClockClass))
#define GDK_IS_FRAME_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_FRAME_CLOCK))
#define GDK_IS_FRAME_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_FRAME_CLOCK))
#define GDK_FRAME_CLOCK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_FRAME_CLOCK, GdkFrameClockClass))
#define GDK_TYPE_FRAME_CLOCK (gdk_frame_clock_get_type ())
#define GDK_FRAME_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_FRAME_CLOCK, GdkFrameClock))
#define GDK_IS_FRAME_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_FRAME_CLOCK))
#define GDK_FRAME_CLOCK_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GDK_TYPE_FRAME_CLOCK, GdkFrameClockInterface))
typedef struct _GdkFrameClock GdkFrameClock;
typedef struct _GdkFrameClockPrivate GdkFrameClockPrivate;
typedef struct _GdkFrameClockClass GdkFrameClockClass;
typedef enum {
GDK_FRAME_CLOCK_PHASE_NONE = 0,
......@@ -54,32 +57,6 @@ typedef enum {
GDK_FRAME_CLOCK_PHASE_AFTER_PAINT = 1 << 6
} GdkFrameClockPhase;
struct _GdkFrameClockInterface
{
GTypeInterface base_iface;
guint64 (* get_frame_time) (GdkFrameClock *clock);
void (* request_phase) (GdkFrameClock *clock,
GdkFrameClockPhase phase);
GdkFrameClockPhase (* get_requested) (GdkFrameClock *clock);
void (* freeze) (GdkFrameClock *clock);
void (* thaw) (GdkFrameClock *clock);
GdkFrameHistory * (* get_history) (GdkFrameClock *clock);
/* signals */
/* void (* frame_requested) (GdkFrameClock *clock); */
/* void (* flush_events) (GdkFrameClock *clock); */
/* void (* before_paint) (GdkFrameClock *clock); */
/* void (* update) (GdkFrameClock *clock); */
/* void (* layout) (GdkFrameClock *clock); */
/* void (* paint) (GdkFrameClock *clock); */
/* void (* after_paint) (GdkFrameClock *clock); */
/* void (* resume_events) (GdkFrameClock *clock); */
};
GType gdk_frame_clock_get_type (void) G_GNUC_CONST;
guint64 gdk_frame_clock_get_frame_time (GdkFrameClock *clock);
......@@ -104,9 +81,6 @@ void gdk_frame_clock_get_refresh_info (GdkFrameClock *clock,
GdkFrameTimings *gdk_frame_clock_get_current_frame_timings (GdkFrameClock *clock);
/* Signal emitters (used in frame clock implementations) */
void gdk_frame_clock_frame_requested (GdkFrameClock *clock);
G_END_DECLS
#endif /* __GDK_FRAME_CLOCK_H__ */
......@@ -27,6 +27,7 @@
#include "config.h"
#include "gdkinternals.h"
#include "gdkframeclockprivate.h"
#include "gdkframeclockidle.h"
#include "gdk.h"
......@@ -34,7 +35,6 @@
struct _GdkFrameClockIdlePrivate
{
GdkFrameHistory *history;
GTimer *timer;
/* timer_base is used to avoid ever going backward */
guint64 timer_base;
......@@ -56,11 +56,8 @@ static gboolean gdk_frame_clock_flush_idle (void *data);
static gboolean gdk_frame_clock_paint_idle (void *data);
static void gdk_frame_clock_idle_finalize (GObject *object);
static void gdk_frame_clock_idle_interface_init (GdkFrameClockInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GdkFrameClockIdle, gdk_frame_clock_idle, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_FRAME_CLOCK,
gdk_frame_clock_idle_interface_init))
G_DEFINE_TYPE (GdkFrameClockIdle, gdk_frame_clock_idle, GDK_TYPE_FRAME_CLOCK)
static gint64 sleep_serial;
static gint64 sleep_source_prepare_time;
......@@ -114,16 +111,6 @@ get_sleep_serial (void)
return sleep_serial;
}
static void
gdk_frame_clock_idle_class_init (GdkFrameClockIdleClass *klass)
{
GObjectClass *gobject_class = (GObjectClass*) klass;
gobject_class->finalize = gdk_frame_clock_idle_finalize;
g_type_class_add_private (klass, sizeof (GdkFrameClockIdlePrivate));
}
static void
gdk_frame_clock_idle_init (GdkFrameClockIdle *frame_clock_idle)
{
......@@ -134,7 +121,6 @@ gdk_frame_clock_idle_init (GdkFrameClockIdle *frame_clock_idle)
GdkFrameClockIdlePrivate);
priv = frame_clock_idle->priv;
priv->history = gdk_frame_history_new ();
priv->timer = g_timer_new ();
priv->freeze_count = 0;
}
......@@ -235,7 +221,7 @@ maybe_start_idle (GdkFrameClockIdle *clock_idle)
g_object_ref (clock_idle),
(GDestroyNotify) g_object_unref);
gdk_frame_clock_frame_requested (GDK_FRAME_CLOCK (clock_idle));
g_signal_emit_by_name (clock_idle, "frame-requested");
}
}
}
......@@ -288,6 +274,7 @@ gdk_frame_clock_paint_idle (void *data)
GdkFrameClock *clock = GDK_FRAME_CLOCK (data);
GdkFrameClockIdle *clock_idle = GDK_FRAME_CLOCK_IDLE (clock);
GdkFrameClockIdlePrivate *priv = clock_idle->priv;
GdkFrameHistory *history = gdk_frame_clock_get_history (clock);
gboolean skip_to_resume_events;
GdkFrameTimings *timings = NULL;
gint64 frame_counter = 0;
......@@ -301,8 +288,8 @@ gdk_frame_clock_paint_idle (void *data)
if (priv->phase > GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT)
{
frame_counter = gdk_frame_history_get_frame_counter (priv->history);
timings = gdk_frame_history_get_timings (priv->history, frame_counter);
frame_counter = gdk_frame_history_get_frame_counter (history);
timings = gdk_frame_history_get_timings (history, frame_counter);
}
if (!skip_to_resume_events)
......@@ -317,9 +304,9 @@ gdk_frame_clock_paint_idle (void *data)
{
priv->frame_time = compute_frame_time (clock_idle);
gdk_frame_history_begin_frame (priv->history);
frame_counter = gdk_frame_history_get_frame_counter (priv->history);
timings = gdk_frame_history_get_timings (priv->history, frame_counter);
gdk_frame_history_begin_frame (history);
frame_counter = gdk_frame_history_get_frame_counter (history);
timings = gdk_frame_history_get_timings (history, frame_counter);
gdk_frame_timings_set_frame_time (timings, priv->frame_time);
......@@ -406,7 +393,7 @@ gdk_frame_clock_paint_idle (void *data)
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
{
if (gdk_frame_timings_get_complete (timings))
_gdk_frame_history_debug_print (priv->history, timings);
_gdk_frame_history_debug_print (history, timings);
}
#endif /* G_ENABLE_DEBUG */
......@@ -501,24 +488,21 @@ gdk_frame_clock_idle_thaw (GdkFrameClock *clock)
}
}
static GdkFrameHistory *
gdk_frame_clock_idle_get_history (GdkFrameClock *clock)
static void
gdk_frame_clock_idle_class_init (GdkFrameClockIdleClass *klass)
{
GdkFrameClockIdle *clock_idle = GDK_FRAME_CLOCK_IDLE (clock);
GdkFrameClockIdlePrivate *priv = clock_idle->priv;
GObjectClass *gobject_class = (GObjectClass*) klass;
GdkFrameClockClass *frame_clock_class = (GdkFrameClockClass *)klass;
return priv->history;
}
gobject_class->finalize = gdk_frame_clock_idle_finalize;
static void
gdk_frame_clock_idle_interface_init (GdkFrameClockInterface *iface)
{
iface->get_frame_time = gdk_frame_clock_idle_get_frame_time;
iface->request_phase = gdk_frame_clock_idle_request_phase;
iface->get_requested = gdk_frame_clock_idle_get_requested;
iface->freeze = gdk_frame_clock_idle_freeze;
iface->thaw = gdk_frame_clock_idle_thaw;
iface->get_history = gdk_frame_clock_idle_get_history;
frame_clock_class->get_frame_time = gdk_frame_clock_idle_get_frame_time;
frame_clock_class->request_phase = gdk_frame_clock_idle_request_phase;
frame_clock_class->get_requested = gdk_frame_clock_idle_get_requested;
frame_clock_class->freeze = gdk_frame_clock_idle_freeze;
frame_clock_class->thaw = gdk_frame_clock_idle_thaw;
g_type_class_add_private (klass, sizeof (GdkFrameClockIdlePrivate));
}
GdkFrameClock *
......
......@@ -29,7 +29,7 @@
#ifndef __GDK_FRAME_CLOCK_IDLE_H__
#define __GDK_FRAME_CLOCK_IDLE_H__
#include <gdk/gdkframeclock.h>
#include "gdkframeclockprivate.h"
G_BEGIN_DECLS
......@@ -47,7 +47,7 @@ typedef struct _GdkFrameClockIdleClass GdkFrameClockIdleClass;
struct _GdkFrameClockIdle
{
GObject parent_instance;
GdkFrameClock parent_instance;
/*< private >*/
GdkFrameClockIdlePrivate *priv;
......@@ -55,7 +55,7 @@ struct _GdkFrameClockIdle
struct _GdkFrameClockIdleClass
{
GObjectClass parent_class;
GdkFrameClockClass parent_class;
};
GType gdk_frame_clock_idle_get_type (void) G_GNUC_CONST;
......
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-2010. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
/* Uninstalled header, internal to GDK */
#ifndef __GDK_FRAME_CLOCK_PRIVATE_H__
#define __GDK_FRAME_CLOCK_PRIVATE_H__
#include <gdk/gdkframeclock.h>
G_BEGIN_DECLS
typedef struct _GdkFrameClockIdlePrivate GdkFrameClockIdlePrivate;
struct _GdkFrameClock
{
GObject parent_instance;
/*< private >*/
GdkFrameClockPrivate *priv;
};
struct _GdkFrameClockClass
{
GObjectClass parent_class;
guint64 (* get_frame_time) (GdkFrameClock *clock);
void (* request_phase) (GdkFrameClock *clock,
GdkFrameClockPhase phase);
GdkFrameClockPhase (* get_requested) (GdkFrameClock *clock);
void (* freeze) (GdkFrameClock *clock);
void (* thaw) (GdkFrameClock *clock);
/* signals */
/* void (* frame_requested) (GdkFrameClock *clock); */
/* void (* flush_events) (GdkFrameClock *clock); */
/* void (* before_paint) (GdkFrameClock *clock); */
/* void (* update) (GdkFrameClock *clock); */
/* void (* layout) (GdkFrameClock *clock); */
/* void (* paint) (GdkFrameClock *clock); */
/* void (* after_paint) (GdkFrameClock *clock); */
/* void (* resume_events) (GdkFrameClock *clock); */
};
G_END_DECLS
#endif /* __GDK_FRAME_CLOCK_PRIVATE_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment