1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gdk.FrameClock;
26 
27 private import gdk.FrameTimings;
28 private import gobject.ObjectG;
29 private import gobject.Signals;
30 private import gtkc.gdk;
31 public  import gtkc.gdktypes;
32 
33 
34 /**
35  * A #GdkFrameClock tells the application when to update and repaint a
36  * window. This may be synced to the vertical refresh rate of the
37  * monitor, for example. Even when the frame clock uses a simple timer
38  * rather than a hardware-based vertical sync, the frame clock helps
39  * because it ensures everything paints at the same time (reducing the
40  * total number of frames). The frame clock can also automatically
41  * stop painting when it knows the frames will not be visible, or
42  * scale back animation framerates.
43  * 
44  * #GdkFrameClock is designed to be compatible with an OpenGL-based
45  * implementation or with mozRequestAnimationFrame in Firefox,
46  * for example.
47  * 
48  * A frame clock is idle until someone requests a frame with
49  * gdk_frame_clock_request_phase(). At some later point that makes
50  * sense for the synchronization being implemented, the clock will
51  * process a frame and emit signals for each phase that has been
52  * requested. (See the signals of the #GdkFrameClock class for
53  * documentation of the phases. %GDK_FRAME_CLOCK_PHASE_UPDATE and the
54  * #GdkFrameClock::update signal are most interesting for application
55  * writers, and are used to update the animations, using the frame time
56  * given by gdk_frame_clock_get_frame_time().
57  * 
58  * The frame time is reported in microseconds and generally in the same
59  * timescale as g_get_monotonic_time(), however, it is not the same
60  * as g_get_monotonic_time(). The frame time does not advance during
61  * the time a frame is being painted, and outside of a frame, an attempt
62  * is made so that all calls to gdk_frame_clock_get_frame_time() that
63  * are called at a “similar” time get the same value. This means that
64  * if different animations are timed by looking at the difference in
65  * time between an initial value from gdk_frame_clock_get_frame_time()
66  * and the value inside the #GdkFrameClock::update signal of the clock,
67  * they will stay exactly synchronized.
68  */
69 public class FrameClock : ObjectG
70 {
71 	/** the main Gtk struct */
72 	protected GdkFrameClock* gdkFrameClock;
73 
74 	/** Get the main Gtk struct */
75 	public GdkFrameClock* getFrameClockStruct()
76 	{
77 		return gdkFrameClock;
78 	}
79 
80 	/** the main Gtk struct as a void* */
81 	protected override void* getStruct()
82 	{
83 		return cast(void*)gdkFrameClock;
84 	}
85 
86 	protected override void setStruct(GObject* obj)
87 	{
88 		gdkFrameClock = cast(GdkFrameClock*)obj;
89 		super.setStruct(obj);
90 	}
91 
92 	/**
93 	 * Sets our main struct and passes it to the parent class.
94 	 */
95 	public this (GdkFrameClock* gdkFrameClock, bool ownedRef = false)
96 	{
97 		this.gdkFrameClock = gdkFrameClock;
98 		super(cast(GObject*)gdkFrameClock, ownedRef);
99 	}
100 
101 
102 	/** */
103 	public static GType getType()
104 	{
105 		return gdk_frame_clock_get_type();
106 	}
107 
108 	/**
109 	 * Starts updates for an animation. Until a matching call to
110 	 * gdk_frame_clock_end_updating() is made, the frame clock will continually
111 	 * request a new frame with the %GDK_FRAME_CLOCK_PHASE_UPDATE phase.
112 	 * This function may be called multiple times and frames will be
113 	 * requested until gdk_frame_clock_end_updating() is called the same
114 	 * number of times.
115 	 *
116 	 * Since: 3.8
117 	 */
118 	public void beginUpdating()
119 	{
120 		gdk_frame_clock_begin_updating(gdkFrameClock);
121 	}
122 
123 	/**
124 	 * Stops updates for an animation. See the documentation for
125 	 * gdk_frame_clock_begin_updating().
126 	 *
127 	 * Since: 3.8
128 	 */
129 	public void endUpdating()
130 	{
131 		gdk_frame_clock_end_updating(gdkFrameClock);
132 	}
133 
134 	/**
135 	 * Gets the frame timings for the current frame.
136 	 *
137 	 * Return: the #GdkFrameTimings for the frame currently
138 	 *     being processed, or even no frame is being processed, for the
139 	 *     previous frame. Before any frames have been procesed, returns
140 	 *     %NULL.
141 	 *
142 	 * Since: 3.8
143 	 */
144 	public FrameTimings getCurrentTimings()
145 	{
146 		auto p = gdk_frame_clock_get_current_timings(gdkFrameClock);
147 		
148 		if(p is null)
149 		{
150 			return null;
151 		}
152 		
153 		return ObjectG.getDObject!(FrameTimings)(cast(GdkFrameTimings*) p, true);
154 	}
155 
156 	/**
157 	 * A #GdkFrameClock maintains a 64-bit counter that increments for
158 	 * each frame drawn.
159 	 *
160 	 * Return: inside frame processing, the value of the frame counter
161 	 *     for the current frame. Outside of frame processing, the frame
162 	 *     counter for the last frame.
163 	 *
164 	 * Since: 3.8
165 	 */
166 	public long getFrameCounter()
167 	{
168 		return gdk_frame_clock_get_frame_counter(gdkFrameClock);
169 	}
170 
171 	/**
172 	 * Gets the time that should currently be used for animations.  Inside
173 	 * the processing of a frame, it’s the time used to compute the
174 	 * animation position of everything in a frame. Outside of a frame, it's
175 	 * the time of the conceptual “previous frame,” which may be either
176 	 * the actual previous frame time, or if that’s too old, an updated
177 	 * time.
178 	 *
179 	 * Return: a timestamp in microseconds, in the timescale of
180 	 *     of g_get_monotonic_time().
181 	 *
182 	 * Since: 3.8
183 	 */
184 	public long getFrameTime()
185 	{
186 		return gdk_frame_clock_get_frame_time(gdkFrameClock);
187 	}
188 
189 	/**
190 	 * #GdkFrameClock internally keeps a history of #GdkFrameTimings
191 	 * objects for recent frames that can be retrieved with
192 	 * gdk_frame_clock_get_timings(). The set of stored frames
193 	 * is the set from the counter values given by
194 	 * gdk_frame_clock_get_history_start() and
195 	 * gdk_frame_clock_get_frame_counter(), inclusive.
196 	 *
197 	 * Return: the frame counter value for the oldest frame
198 	 *     that is available in the internal frame history of the
199 	 *     #GdkFrameClock.
200 	 *
201 	 * Since: 3.8
202 	 */
203 	public long getHistoryStart()
204 	{
205 		return gdk_frame_clock_get_history_start(gdkFrameClock);
206 	}
207 
208 	/**
209 	 * Using the frame history stored in the frame clock, finds the last
210 	 * known presentation time and refresh interval, and assuming that
211 	 * presentation times are separated by the refresh interval,
212 	 * predicts a presentation time that is a multiple of the refresh
213 	 * interval after the last presentation time, and later than @base_time.
214 	 *
215 	 * Params:
216 	 *     baseTime = base time for determining a presentaton time
217 	 *     refreshIntervalReturn = a location to store the determined refresh
218 	 *         interval, or %NULL. A default refresh interval of 1/60th of
219 	 *         a second will be stored if no history is present.
220 	 *     presentationTimeReturn = a location to store the next
221 	 *         candidate presentation time after the given base time.
222 	 *         0 will be will be stored if no history is present.
223 	 *
224 	 * Since: 3.8
225 	 */
226 	public void getRefreshInfo(long baseTime, long* refreshIntervalReturn, long* presentationTimeReturn)
227 	{
228 		gdk_frame_clock_get_refresh_info(gdkFrameClock, baseTime, refreshIntervalReturn, presentationTimeReturn);
229 	}
230 
231 	/**
232 	 * Retrieves a #GdkFrameTimings object holding timing information
233 	 * for the current frame or a recent frame. The #GdkFrameTimings
234 	 * object may not yet be complete: see gdk_frame_timings_get_complete().
235 	 *
236 	 * Params:
237 	 *     frameCounter = the frame counter value identifying the frame to
238 	 *         be received.
239 	 *
240 	 * Return: the #GdkFrameTimings object for the specified
241 	 *     frame, or %NULL if it is not available. See
242 	 *     gdk_frame_clock_get_history_start().
243 	 *
244 	 * Since: 3.8
245 	 */
246 	public FrameTimings getTimings(long frameCounter)
247 	{
248 		auto p = gdk_frame_clock_get_timings(gdkFrameClock, frameCounter);
249 		
250 		if(p is null)
251 		{
252 			return null;
253 		}
254 		
255 		return ObjectG.getDObject!(FrameTimings)(cast(GdkFrameTimings*) p, true);
256 	}
257 
258 	/**
259 	 * Asks the frame clock to run a particular phase. The signal
260 	 * corresponding the requested phase will be emitted the next
261 	 * time the frame clock processes. Multiple calls to
262 	 * gdk_frame_clock_request_phase() will be combined together
263 	 * and only one frame processed. If you are displaying animated
264 	 * content and want to continually request the
265 	 * %GDK_FRAME_CLOCK_PHASE_UPDATE phase for a period of time,
266 	 * you should use gdk_frame_clock_begin_updating() instead, since
267 	 * this allows GTK+ to adjust system parameters to get maximally
268 	 * smooth animations.
269 	 *
270 	 * Params:
271 	 *     phase = the phase that is requested
272 	 *
273 	 * Since: 3.8
274 	 */
275 	public void requestPhase(GdkFrameClockPhase phase)
276 	{
277 		gdk_frame_clock_request_phase(gdkFrameClock, phase);
278 	}
279 
280 	int[string] connectedSignals;
281 
282 	void delegate(FrameClock)[] onAfterPaintListeners;
283 	/**
284 	 * This signal ends processing of the frame. Applications
285 	 * should generally not handle this signal.
286 	 */
287 	void addOnAfterPaint(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
288 	{
289 		if ( "after-paint" !in connectedSignals )
290 		{
291 			Signals.connectData(
292 				this,
293 				"after-paint",
294 				cast(GCallback)&callBackAfterPaint,
295 				cast(void*)this,
296 				null,
297 				connectFlags);
298 			connectedSignals["after-paint"] = 1;
299 		}
300 		onAfterPaintListeners ~= dlg;
301 	}
302 	extern(C) static void callBackAfterPaint(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
303 	{
304 		foreach ( void delegate(FrameClock) dlg; _frameclock.onAfterPaintListeners )
305 		{
306 			dlg(_frameclock);
307 		}
308 	}
309 
310 	void delegate(FrameClock)[] onBeforePaintListeners;
311 	/**
312 	 * This signal begins processing of the frame. Applications
313 	 * should generally not handle this signal.
314 	 */
315 	void addOnBeforePaint(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
316 	{
317 		if ( "before-paint" !in connectedSignals )
318 		{
319 			Signals.connectData(
320 				this,
321 				"before-paint",
322 				cast(GCallback)&callBackBeforePaint,
323 				cast(void*)this,
324 				null,
325 				connectFlags);
326 			connectedSignals["before-paint"] = 1;
327 		}
328 		onBeforePaintListeners ~= dlg;
329 	}
330 	extern(C) static void callBackBeforePaint(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
331 	{
332 		foreach ( void delegate(FrameClock) dlg; _frameclock.onBeforePaintListeners )
333 		{
334 			dlg(_frameclock);
335 		}
336 	}
337 
338 	void delegate(FrameClock)[] onFlushEventsListeners;
339 	/**
340 	 * This signal is used to flush pending motion events that
341 	 * are being batched up and compressed together. Applications
342 	 * should not handle this signal.
343 	 */
344 	void addOnFlushEvents(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
345 	{
346 		if ( "flush-events" !in connectedSignals )
347 		{
348 			Signals.connectData(
349 				this,
350 				"flush-events",
351 				cast(GCallback)&callBackFlushEvents,
352 				cast(void*)this,
353 				null,
354 				connectFlags);
355 			connectedSignals["flush-events"] = 1;
356 		}
357 		onFlushEventsListeners ~= dlg;
358 	}
359 	extern(C) static void callBackFlushEvents(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
360 	{
361 		foreach ( void delegate(FrameClock) dlg; _frameclock.onFlushEventsListeners )
362 		{
363 			dlg(_frameclock);
364 		}
365 	}
366 
367 	void delegate(FrameClock)[] onLayoutListeners;
368 	/**
369 	 * This signal is emitted as the second step of toolkit and
370 	 * application processing of the frame. Any work to update
371 	 * sizes and positions of application elements should be
372 	 * performed. GTK+ normally handles this internally.
373 	 */
374 	void addOnLayout(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
375 	{
376 		if ( "layout" !in connectedSignals )
377 		{
378 			Signals.connectData(
379 				this,
380 				"layout",
381 				cast(GCallback)&callBackLayout,
382 				cast(void*)this,
383 				null,
384 				connectFlags);
385 			connectedSignals["layout"] = 1;
386 		}
387 		onLayoutListeners ~= dlg;
388 	}
389 	extern(C) static void callBackLayout(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
390 	{
391 		foreach ( void delegate(FrameClock) dlg; _frameclock.onLayoutListeners )
392 		{
393 			dlg(_frameclock);
394 		}
395 	}
396 
397 	void delegate(FrameClock)[] onPaintListeners;
398 	/**
399 	 * This signal is emitted as the third step of toolkit and
400 	 * application processing of the frame. The frame is
401 	 * repainted. GDK normally handles this internally and
402 	 * produces expose events, which are turned into GTK+
403 	 * #GtkWidget::draw signals.
404 	 */
405 	void addOnPaint(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
406 	{
407 		if ( "paint" !in connectedSignals )
408 		{
409 			Signals.connectData(
410 				this,
411 				"paint",
412 				cast(GCallback)&callBackPaint,
413 				cast(void*)this,
414 				null,
415 				connectFlags);
416 			connectedSignals["paint"] = 1;
417 		}
418 		onPaintListeners ~= dlg;
419 	}
420 	extern(C) static void callBackPaint(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
421 	{
422 		foreach ( void delegate(FrameClock) dlg; _frameclock.onPaintListeners )
423 		{
424 			dlg(_frameclock);
425 		}
426 	}
427 
428 	void delegate(FrameClock)[] onResumeEventsListeners;
429 	/**
430 	 * This signal is emitted after processing of the frame is
431 	 * finished, and is handled internally by GTK+ to resume normal
432 	 * event processing. Applications should not handle this signal.
433 	 */
434 	void addOnResumeEvents(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
435 	{
436 		if ( "resume-events" !in connectedSignals )
437 		{
438 			Signals.connectData(
439 				this,
440 				"resume-events",
441 				cast(GCallback)&callBackResumeEvents,
442 				cast(void*)this,
443 				null,
444 				connectFlags);
445 			connectedSignals["resume-events"] = 1;
446 		}
447 		onResumeEventsListeners ~= dlg;
448 	}
449 	extern(C) static void callBackResumeEvents(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
450 	{
451 		foreach ( void delegate(FrameClock) dlg; _frameclock.onResumeEventsListeners )
452 		{
453 			dlg(_frameclock);
454 		}
455 	}
456 
457 	void delegate(FrameClock)[] onUpdateListeners;
458 	/**
459 	 * This signal is emitted as the first step of toolkit and
460 	 * application processing of the frame. Animations should
461 	 * be updated using gdk_frame_clock_get_frame_time().
462 	 * Applications can connect directly to this signal, or
463 	 * use gtk_widget_add_tick_callback() as a more convenient
464 	 * interface.
465 	 */
466 	void addOnUpdate(void delegate(FrameClock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
467 	{
468 		if ( "update" !in connectedSignals )
469 		{
470 			Signals.connectData(
471 				this,
472 				"update",
473 				cast(GCallback)&callBackUpdate,
474 				cast(void*)this,
475 				null,
476 				connectFlags);
477 			connectedSignals["update"] = 1;
478 		}
479 		onUpdateListeners ~= dlg;
480 	}
481 	extern(C) static void callBackUpdate(GdkFrameClock* frameclockStruct, FrameClock _frameclock)
482 	{
483 		foreach ( void delegate(FrameClock) dlg; _frameclock.onUpdateListeners )
484 		{
485 			dlg(_frameclock);
486 		}
487 	}
488 }