1 #ifdef HAVE_CONFIG_H
2 #include "clutter-build-config.h"
3 #endif
4
5 #include <glib-object.h>
6
7 #include "clutter-actor.h"
8 #include "clutter-stage-window.h"
9 #include "clutter-private.h"
10
11 #define clutter_stage_window_get_type _clutter_stage_window_get_type
12
13 typedef ClutterStageWindowIface ClutterStageWindowInterface;
14
15 G_DEFINE_INTERFACE (ClutterStageWindow, clutter_stage_window, G_TYPE_OBJECT);
16
17 static void
clutter_stage_window_default_init(ClutterStageWindowInterface * iface)18 clutter_stage_window_default_init (ClutterStageWindowInterface *iface)
19 {
20 GParamSpec *pspec;
21
22 pspec = g_param_spec_object ("backend",
23 "Backend",
24 "Back pointer to the Backend instance",
25 CLUTTER_TYPE_BACKEND,
26 G_PARAM_WRITABLE |
27 G_PARAM_CONSTRUCT_ONLY |
28 G_PARAM_STATIC_STRINGS);
29 g_object_interface_install_property (iface, pspec);
30
31 pspec = g_param_spec_object ("wrapper",
32 "Wrapper",
33 "Back pointer to the Stage actor",
34 CLUTTER_TYPE_STAGE,
35 G_PARAM_WRITABLE |
36 G_PARAM_CONSTRUCT_ONLY |
37 G_PARAM_STATIC_STRINGS);
38 g_object_interface_install_property (iface, pspec);
39 }
40
41 ClutterActor *
_clutter_stage_window_get_wrapper(ClutterStageWindow * window)42 _clutter_stage_window_get_wrapper (ClutterStageWindow *window)
43 {
44 return CLUTTER_STAGE_WINDOW_GET_IFACE (window)->get_wrapper (window);
45 }
46
47 void
_clutter_stage_window_set_title(ClutterStageWindow * window,const gchar * title)48 _clutter_stage_window_set_title (ClutterStageWindow *window,
49 const gchar *title)
50 {
51 ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
52
53 if (iface->set_title)
54 iface->set_title (window, title);
55 }
56
57 void
_clutter_stage_window_set_fullscreen(ClutterStageWindow * window,gboolean is_fullscreen)58 _clutter_stage_window_set_fullscreen (ClutterStageWindow *window,
59 gboolean is_fullscreen)
60 {
61 ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
62
63 if (iface->set_fullscreen)
64 iface->set_fullscreen (window, is_fullscreen);
65 }
66
67 void
_clutter_stage_window_set_cursor_visible(ClutterStageWindow * window,gboolean is_visible)68 _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window,
69 gboolean is_visible)
70 {
71 ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
72
73 if (iface->set_cursor_visible)
74 iface->set_cursor_visible (window, is_visible);
75 }
76
77 void
_clutter_stage_window_set_user_resizable(ClutterStageWindow * window,gboolean is_resizable)78 _clutter_stage_window_set_user_resizable (ClutterStageWindow *window,
79 gboolean is_resizable)
80 {
81 CLUTTER_STAGE_WINDOW_GET_IFACE (window)->set_user_resizable (window,
82 is_resizable);
83 }
84
85 gboolean
_clutter_stage_window_realize(ClutterStageWindow * window)86 _clutter_stage_window_realize (ClutterStageWindow *window)
87 {
88 return CLUTTER_STAGE_WINDOW_GET_IFACE (window)->realize (window);
89 }
90
91 void
_clutter_stage_window_unrealize(ClutterStageWindow * window)92 _clutter_stage_window_unrealize (ClutterStageWindow *window)
93 {
94 CLUTTER_STAGE_WINDOW_GET_IFACE (window)->unrealize (window);
95 }
96
97 void
_clutter_stage_window_show(ClutterStageWindow * window,gboolean do_raise)98 _clutter_stage_window_show (ClutterStageWindow *window,
99 gboolean do_raise)
100 {
101 CLUTTER_STAGE_WINDOW_GET_IFACE (window)->show (window, do_raise);
102 }
103
104 void
_clutter_stage_window_hide(ClutterStageWindow * window)105 _clutter_stage_window_hide (ClutterStageWindow *window)
106 {
107 CLUTTER_STAGE_WINDOW_GET_IFACE (window)->hide (window);
108 }
109
110 void
_clutter_stage_window_resize(ClutterStageWindow * window,gint width,gint height)111 _clutter_stage_window_resize (ClutterStageWindow *window,
112 gint width,
113 gint height)
114 {
115 CLUTTER_STAGE_WINDOW_GET_IFACE (window)->resize (window, width, height);
116 }
117
118 void
_clutter_stage_window_get_geometry(ClutterStageWindow * window,cairo_rectangle_int_t * geometry)119 _clutter_stage_window_get_geometry (ClutterStageWindow *window,
120 cairo_rectangle_int_t *geometry)
121 {
122 CLUTTER_STAGE_WINDOW_GET_IFACE (window)->get_geometry (window, geometry);
123 }
124
125 void
_clutter_stage_window_schedule_update(ClutterStageWindow * window,int sync_delay)126 _clutter_stage_window_schedule_update (ClutterStageWindow *window,
127 int sync_delay)
128 {
129 ClutterStageWindowIface *iface;
130
131 g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
132
133 iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
134 if (iface->schedule_update == NULL)
135 {
136 g_assert (!clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS));
137 return;
138 }
139
140 iface->schedule_update (window, sync_delay);
141 }
142
143 gint64
_clutter_stage_window_get_update_time(ClutterStageWindow * window)144 _clutter_stage_window_get_update_time (ClutterStageWindow *window)
145 {
146 ClutterStageWindowIface *iface;
147
148 g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), 0);
149
150 iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
151 if (iface->get_update_time == NULL)
152 {
153 g_assert (!clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS));
154 return 0;
155 }
156
157 return iface->get_update_time (window);
158 }
159
160 void
_clutter_stage_window_clear_update_time(ClutterStageWindow * window)161 _clutter_stage_window_clear_update_time (ClutterStageWindow *window)
162 {
163 ClutterStageWindowIface *iface;
164
165 g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
166
167 iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
168 if (iface->clear_update_time == NULL)
169 {
170 g_assert (!clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS));
171 return;
172 }
173
174 iface->clear_update_time (window);
175 }
176
177 void
_clutter_stage_window_add_redraw_clip(ClutterStageWindow * window,cairo_rectangle_int_t * stage_clip)178 _clutter_stage_window_add_redraw_clip (ClutterStageWindow *window,
179 cairo_rectangle_int_t *stage_clip)
180 {
181 ClutterStageWindowIface *iface;
182
183 g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
184
185 iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
186 if (iface->add_redraw_clip != NULL)
187 iface->add_redraw_clip (window, stage_clip);
188 }
189
190 /* Determines if the backend will clip the rendering of the next
191 * frame.
192 *
193 * Note: at the start of each new frame there is an implied clip that
194 * clips everything (i.e. nothing would be drawn) so this function
195 * will return True at the start of a new frame if the backend
196 * supports clipped redraws.
197 */
198 gboolean
_clutter_stage_window_has_redraw_clips(ClutterStageWindow * window)199 _clutter_stage_window_has_redraw_clips (ClutterStageWindow *window)
200 {
201 ClutterStageWindowIface *iface;
202
203 g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
204
205 iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
206 if (iface->has_redraw_clips != NULL)
207 return iface->has_redraw_clips (window);
208
209 return FALSE;
210 }
211
212 /* Determines if the backend will discard any additional redraw clips
213 * and instead promote them to a full stage redraw.
214 *
215 * The ideas is that backend may have some heuristics that cause it to
216 * give up tracking redraw clips so this can be used to avoid the cost
217 * of calculating a redraw clip when we know it's going to be ignored
218 * anyway.
219 */
220 gboolean
_clutter_stage_window_ignoring_redraw_clips(ClutterStageWindow * window)221 _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window)
222 {
223 ClutterStageWindowIface *iface;
224
225 g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
226
227 iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
228 if (iface->ignoring_redraw_clips != NULL)
229 return iface->ignoring_redraw_clips (window);
230
231 return TRUE;
232 }
233
234 gboolean
_clutter_stage_window_get_redraw_clip_bounds(ClutterStageWindow * window,cairo_rectangle_int_t * stage_clip)235 _clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window,
236 cairo_rectangle_int_t *stage_clip)
237 {
238 ClutterStageWindowIface *iface;
239
240 g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
241
242 iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
243 if (iface->get_redraw_clip_bounds != NULL)
244 return iface->get_redraw_clip_bounds (window, stage_clip);
245
246 return FALSE;
247 }
248
249 void
_clutter_stage_window_set_accept_focus(ClutterStageWindow * window,gboolean accept_focus)250 _clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
251 gboolean accept_focus)
252 {
253 ClutterStageWindowIface *iface;
254
255 g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
256
257 iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
258 if (iface->set_accept_focus)
259 iface->set_accept_focus (window, accept_focus);
260 }
261
262 void
_clutter_stage_window_redraw(ClutterStageWindow * window)263 _clutter_stage_window_redraw (ClutterStageWindow *window)
264 {
265 ClutterStageWindowIface *iface;
266
267 g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
268
269 iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
270 if (iface->redraw)
271 iface->redraw (window);
272 }
273
274
275 void
_clutter_stage_window_get_dirty_pixel(ClutterStageWindow * window,ClutterStageView * view,int * x,int * y)276 _clutter_stage_window_get_dirty_pixel (ClutterStageWindow *window,
277 ClutterStageView *view,
278 int *x, int *y)
279 {
280 ClutterStageWindowIface *iface;
281
282 *x = 0;
283 *y = 0;
284
285 g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
286
287 iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
288 if (iface->get_dirty_pixel)
289 iface->get_dirty_pixel (window, view, x, y);
290 }
291
292 gboolean
_clutter_stage_window_can_clip_redraws(ClutterStageWindow * window)293 _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window)
294 {
295 ClutterStageWindowIface *iface;
296
297 g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE);
298
299 iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
300 if (iface->can_clip_redraws != NULL)
301 return iface->can_clip_redraws (window);
302
303 return FALSE;
304 }
305
306 GList *
_clutter_stage_window_get_views(ClutterStageWindow * window)307 _clutter_stage_window_get_views (ClutterStageWindow *window)
308 {
309 ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
310
311 return iface->get_views (window);
312 }
313
314 void
_clutter_stage_window_finish_frame(ClutterStageWindow * window)315 _clutter_stage_window_finish_frame (ClutterStageWindow *window)
316 {
317 ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
318
319 if (iface->finish_frame)
320 iface->finish_frame (window);
321 }
322
323 int64_t
_clutter_stage_window_get_frame_counter(ClutterStageWindow * window)324 _clutter_stage_window_get_frame_counter (ClutterStageWindow *window)
325 {
326 ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
327
328 if (iface->get_frame_counter)
329 return iface->get_frame_counter (window);
330 else
331 return 0;
332 }
333