1------------------------------------------------------------------------------
2--                                                                          --
3--      Copyright (C) 1998-2000 E. Briot, J. Brobecker and A. Charlet       --
4--                     Copyright (C) 2000-2015, AdaCore                     --
5--                                                                          --
6-- This library is free software;  you can redistribute it and/or modify it --
7-- under terms of the  GNU General Public License  as published by the Free --
8-- Software  Foundation;  either version 3,  or (at your  option) any later --
9-- version. This library is distributed in the hope that it will be useful, --
10-- but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN- --
11-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE.                            --
12--                                                                          --
13-- As a special exception under Section 7 of GPL version 3, you are granted --
14-- additional permissions described in the GCC Runtime Library Exception,   --
15-- version 3.1, as published by the Free Software Foundation.               --
16--                                                                          --
17-- You should have received a copy of the GNU General Public License and    --
18-- a copy of the GCC Runtime Library Exception along with this program;     --
19-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
20-- <http://www.gnu.org/licenses/>.                                          --
21--                                                                          --
22------------------------------------------------------------------------------
23
24--  <description>
25--  A Gdk.Frame_Clock.Gdk_Frame_Clock tells the application when to update and
26--  repaint a window. This may be synced to the vertical refresh rate of the
27--  monitor, for example. Even when the frame clock uses a simple timer rather
28--  than a hardware-based vertical sync, the frame clock helps because it
29--  ensures everything paints at the same time (reducing the total number of
30--  frames). The frame clock can also automatically stop painting when it knows
31--  the frames will not be visible, or scale back animation framerates.
32--
33--  Gdk.Frame_Clock.Gdk_Frame_Clock is designed to be compatible with an
34--  OpenGL-based implementation or with mozRequestAnimationFrame in Firefox,
35--  for example.
36--
37--  A frame clock is idle until someone requests a frame with
38--  Gdk.Frame_Clock.Request_Phase. At some later point that makes sense for the
39--  synchronization being implemented, the clock will process a frame and emit
40--  signals for each phase that has been requested. (See the signals of the
41--  Gdk.Frame_Clock.Gdk_Frame_Clock class for documentation of the phases.
42--  Gdk.Frame_Clock.Gdk_Frame_Clock_Phase_Update and the
43--  Gdk.Frame_Clock.Gdk_Frame_Clock::update signal are most interesting for
44--  application writers, and are used to update the animations, using the frame
45--  time given by Gdk.Frame_Clock.Get_Frame_Time.
46--
47--  The frame time is reported in microseconds and generally in the same
48--  timescale as g_get_monotonic_time, however, it is not the same as
49--  g_get_monotonic_time. The frame time does not advance during the time a
50--  frame is being painted, and outside of a frame, an attempt is made so that
51--  all calls to Gdk.Frame_Clock.Get_Frame_Time that are called at a "similar"
52--  time get the same value. This means that if different animations are timed
53--  by looking at the difference in time between an initial value from
54--  Gdk.Frame_Clock.Get_Frame_Time and the value inside the
55--  Gdk.Frame_Clock.Gdk_Frame_Clock::update signal of the clock, they will stay
56--  exactly synchronized.
57--
58--  </description>
59pragma Ada_2005;
60
61pragma Warnings (Off, "*is already use-visible*");
62with Gdk.Frame_Timings;       use Gdk.Frame_Timings;
63with Glib;                    use Glib;
64with Glib.Generic_Properties; use Glib.Generic_Properties;
65with Glib.Object;             use Glib.Object;
66
67package Gdk.Frame_Clock is
68
69   type Gdk_Frame_Clock_Record is new GObject_Record with null record;
70   type Gdk_Frame_Clock is access all Gdk_Frame_Clock_Record'Class;
71
72   type Gdk_Frame_Clock_Phase is mod 2 ** Integer'Size;
73   pragma Convention (C, Gdk_Frame_Clock_Phase);
74   --  Gdk.Frame_Clock.Gdk_Frame_Clock_Phase is used to represent the
75   --  different paint clock phases that can be requested. The elements of the
76   --  enumeration correspond to the signals of
77   --  Gdk.Frame_Clock.Gdk_Frame_Clock.
78
79   Gdk_Frame_Clock_Phase_None : constant Gdk_Frame_Clock_Phase := 0;
80   Gdk_Frame_Clock_Phase_Flush_Events : constant Gdk_Frame_Clock_Phase := 1;
81   Gdk_Frame_Clock_Phase_Before_Paint : constant Gdk_Frame_Clock_Phase := 2;
82   Gdk_Frame_Clock_Phase_Update : constant Gdk_Frame_Clock_Phase := 4;
83   Gdk_Frame_Clock_Phase_Layout : constant Gdk_Frame_Clock_Phase := 8;
84   Gdk_Frame_Clock_Phase_Paint : constant Gdk_Frame_Clock_Phase := 16;
85   Gdk_Frame_Clock_Phase_Resume_Events : constant Gdk_Frame_Clock_Phase := 32;
86   Gdk_Frame_Clock_Phase_After_Paint : constant Gdk_Frame_Clock_Phase := 64;
87
88   ----------------------------
89   -- Enumeration Properties --
90   ----------------------------
91
92   package Gdk_Frame_Clock_Phase_Properties is
93      new Generic_Internal_Discrete_Property (Gdk_Frame_Clock_Phase);
94   type Property_Gdk_Frame_Clock_Phase is new Gdk_Frame_Clock_Phase_Properties.Property;
95
96   ------------------
97   -- Constructors --
98   ------------------
99
100   function Get_Type return Glib.GType;
101   pragma Import (C, Get_Type, "gdk_frame_clock_get_type");
102
103   -------------
104   -- Methods --
105   -------------
106
107   procedure Begin_Updating (Self : not null access Gdk_Frame_Clock_Record);
108   --  Starts updates for an animation. Until a matching call to
109   --  Gdk.Frame_Clock.End_Updating is made, the frame clock will continually
110   --  request a new frame with the
111   --  Gdk.Frame_Clock.Gdk_Frame_Clock_Phase_Update phase. This function may be
112   --  called multiple times and frames will be requested until
113   --  Gdk.Frame_Clock.End_Updating is called the same number of times.
114   --  Since: gtk+ 3.8
115
116   procedure End_Updating (Self : not null access Gdk_Frame_Clock_Record);
117   --  Stops updates for an animation. See the documentation for
118   --  Gdk.Frame_Clock.Begin_Updating.
119   --  Since: gtk+ 3.8
120
121   function Get_Current_Timings
122      (Self : not null access Gdk_Frame_Clock_Record)
123       return Gdk.Frame_Timings.Gdk_Frame_Timings;
124   --  Gets the frame timings for the current frame.
125   --  Since: gtk+ 3.8
126
127   function Get_Frame_Counter
128      (Self : not null access Gdk_Frame_Clock_Record) return Gint64;
129   --  A Gdk.Frame_Clock.Gdk_Frame_Clock maintains a 64-bit counter that
130   --  increments for each frame drawn.
131   --  Since: gtk+ 3.8
132
133   function Get_Frame_Time
134      (Self : not null access Gdk_Frame_Clock_Record) return Gint64;
135   --  Gets the time that should currently be used for animations. Inside the
136   --  processing of a frame, it's the time used to compute the animation
137   --  position of everything in a frame. Outside of a frame, it's the time of
138   --  the conceptual "previous frame," which may be either the actual previous
139   --  frame time, or if that's too old, an updated time.
140   --  Since: gtk+ 3.8
141
142   function Get_History_Start
143      (Self : not null access Gdk_Frame_Clock_Record) return Gint64;
144   --  Gdk.Frame_Clock.Gdk_Frame_Clock internally keeps a history of
145   --  Gdk.Frame_Timings.Gdk_Frame_Timings objects for recent frames that can
146   --  be retrieved with Gdk.Frame_Clock.Get_Timings. The set of stored frames
147   --  is the set from the counter values given by
148   --  Gdk.Frame_Clock.Get_History_Start and Gdk.Frame_Clock.Get_Frame_Counter,
149   --  inclusive.
150   --  Since: gtk+ 3.8
151
152   procedure Get_Refresh_Info
153      (Self                     : not null access Gdk_Frame_Clock_Record;
154       Base_Time                : Gint64;
155       Refresh_Interval_Return  : in out Gint64;
156       Presentation_Time_Return : in out Gint64);
157   --  Using the frame history stored in the frame clock, finds the last known
158   --  presentation time and refresh interval, and assuming that presentation
159   --  times are separated by the refresh interval, predicts a presentation
160   --  time that is a multiple of the refresh interval after the last
161   --  presentation time, and later than Base_Time.
162   --  Since: gtk+ 3.8
163   --  "base_time": base time for determining a presentaton time
164   --  "refresh_interval_return": a location to store the determined refresh
165   --  interval, or null. A default refresh interval of 1/60th of a second will
166   --  be stored if no history is present.
167   --  "presentation_time_return": a location to store the next candidate
168   --  presentation time after the given base time. 0 will be will be stored if
169   --  no history is present.
170
171   function Get_Timings
172      (Self          : not null access Gdk_Frame_Clock_Record;
173       Frame_Counter : Gint64) return Gdk.Frame_Timings.Gdk_Frame_Timings;
174   --  Retrieves a Gdk.Frame_Timings.Gdk_Frame_Timings object holding timing
175   --  information for the current frame or a recent frame. The
176   --  Gdk.Frame_Timings.Gdk_Frame_Timings object may not yet be complete: see
177   --  Gdk.Frame_Timings.Get_Complete.
178   --  Since: gtk+ 3.8
179   --  "frame_counter": the frame counter value identifying the frame to be
180   --  received.
181
182   procedure Request_Phase
183      (Self  : not null access Gdk_Frame_Clock_Record;
184       Phase : Gdk_Frame_Clock_Phase);
185   --  Asks the frame clock to run a particular phase. The signal
186   --  corresponding the requested phase will be emitted the next time the
187   --  frame clock processes. Multiple calls to Gdk.Frame_Clock.Request_Phase
188   --  will be combined together and only one frame processed. If you are
189   --  displaying animated content and want to continually request the
190   --  Gdk.Frame_Clock.Gdk_Frame_Clock_Phase_Update phase for a period of time,
191   --  you should use Gdk.Frame_Clock.Begin_Updating instead, since this allows
192   --  GTK+ to adjust system parameters to get maximally smooth animations.
193   --  Since: gtk+ 3.8
194   --  "phase": the phase that is requested
195
196   -------------
197   -- Signals --
198   -------------
199
200   type Cb_Gdk_Frame_Clock_Void is not null access procedure
201     (Self : access Gdk_Frame_Clock_Record'Class);
202
203   type Cb_GObject_Void is not null access procedure
204     (Self : access Glib.Object.GObject_Record'Class);
205
206   Signal_After_Paint : constant Glib.Signal_Name := "after-paint";
207   procedure On_After_Paint
208      (Self  : not null access Gdk_Frame_Clock_Record;
209       Call  : Cb_Gdk_Frame_Clock_Void;
210       After : Boolean := False);
211   procedure On_After_Paint
212      (Self  : not null access Gdk_Frame_Clock_Record;
213       Call  : Cb_GObject_Void;
214       Slot  : not null access Glib.Object.GObject_Record'Class;
215       After : Boolean := False);
216   --  This signal ends processing of the frame. Applications should generally
217   --  not handle this signal.
218
219   Signal_Before_Paint : constant Glib.Signal_Name := "before-paint";
220   procedure On_Before_Paint
221      (Self  : not null access Gdk_Frame_Clock_Record;
222       Call  : Cb_Gdk_Frame_Clock_Void;
223       After : Boolean := False);
224   procedure On_Before_Paint
225      (Self  : not null access Gdk_Frame_Clock_Record;
226       Call  : Cb_GObject_Void;
227       Slot  : not null access Glib.Object.GObject_Record'Class;
228       After : Boolean := False);
229   --  This signal begins processing of the frame. Applications should
230   --  generally not handle this signal.
231
232   Signal_Flush_Events : constant Glib.Signal_Name := "flush-events";
233   procedure On_Flush_Events
234      (Self  : not null access Gdk_Frame_Clock_Record;
235       Call  : Cb_Gdk_Frame_Clock_Void;
236       After : Boolean := False);
237   procedure On_Flush_Events
238      (Self  : not null access Gdk_Frame_Clock_Record;
239       Call  : Cb_GObject_Void;
240       Slot  : not null access Glib.Object.GObject_Record'Class;
241       After : Boolean := False);
242   --  This signal is used to flush pending motion events that are being
243   --  batched up and compressed together. Applications should not handle this
244   --  signal.
245
246   Signal_Layout : constant Glib.Signal_Name := "layout";
247   procedure On_Layout
248      (Self  : not null access Gdk_Frame_Clock_Record;
249       Call  : Cb_Gdk_Frame_Clock_Void;
250       After : Boolean := False);
251   procedure On_Layout
252      (Self  : not null access Gdk_Frame_Clock_Record;
253       Call  : Cb_GObject_Void;
254       Slot  : not null access Glib.Object.GObject_Record'Class;
255       After : Boolean := False);
256   --  This signal is emitted as the second step of toolkit and application
257   --  processing of the frame. Any work to update sizes and positions of
258   --  application elements should be performed. GTK+ normally handles this
259   --  internally.
260
261   Signal_Paint : constant Glib.Signal_Name := "paint";
262   procedure On_Paint
263      (Self  : not null access Gdk_Frame_Clock_Record;
264       Call  : Cb_Gdk_Frame_Clock_Void;
265       After : Boolean := False);
266   procedure On_Paint
267      (Self  : not null access Gdk_Frame_Clock_Record;
268       Call  : Cb_GObject_Void;
269       Slot  : not null access Glib.Object.GObject_Record'Class;
270       After : Boolean := False);
271   --  This signal is emitted as the third step of toolkit and application
272   --  processing of the frame. The frame is repainted. GDK normally handles
273   --  this internally and produces expose events, which are turned into GTK+
274   --  Gtk.Widget.Gtk_Widget::draw signals.
275
276   Signal_Resume_Events : constant Glib.Signal_Name := "resume-events";
277   procedure On_Resume_Events
278      (Self  : not null access Gdk_Frame_Clock_Record;
279       Call  : Cb_Gdk_Frame_Clock_Void;
280       After : Boolean := False);
281   procedure On_Resume_Events
282      (Self  : not null access Gdk_Frame_Clock_Record;
283       Call  : Cb_GObject_Void;
284       Slot  : not null access Glib.Object.GObject_Record'Class;
285       After : Boolean := False);
286   --  This signal is emitted after processing of the frame is finished, and
287   --  is handled internally by GTK+ to resume normal event processing.
288   --  Applications should not handle this signal.
289
290   Signal_Update : constant Glib.Signal_Name := "update";
291   procedure On_Update
292      (Self  : not null access Gdk_Frame_Clock_Record;
293       Call  : Cb_Gdk_Frame_Clock_Void;
294       After : Boolean := False);
295   procedure On_Update
296      (Self  : not null access Gdk_Frame_Clock_Record;
297       Call  : Cb_GObject_Void;
298       Slot  : not null access Glib.Object.GObject_Record'Class;
299       After : Boolean := False);
300   --  This signal is emitted as the first step of toolkit and application
301   --  processing of the frame. Animations should be updated using
302   --  Gdk.Frame_Clock.Get_Frame_Time. Applications can connect directly to
303   --  this signal, or use Gtk.Widget.Add_Tick_Callback as a more convenient
304   --  interface.
305
306end Gdk.Frame_Clock;
307