gnome-shell-3.6.3.1/src/st/st-theme-node-transition.c

Location Tool Test ID Function Issue
st/st-theme-node-transition.c:94:3 gcc deprecated-declarations st_theme_node_transition_new 'clutter_alpha_new' is deprecated (declared at /usr/include/clutter-1.0/clutter/deprecated/clutter-alpha.h:105)
st/st-theme-node-transition.c:104:3 gcc deprecated-declarations st_theme_node_transition_new 'clutter_alpha_set_mode' is deprecated (declared at /usr/include/clutter-1.0/clutter/deprecated/clutter-alpha.h:131)
st/st-theme-node-transition.c:105:3 gcc deprecated-declarations st_theme_node_transition_new 'clutter_alpha_set_timeline' is deprecated (declared at /usr/include/clutter-1.0/clutter/deprecated/clutter-alpha.h:126)
st/st-theme-node-transition.c:337:27 gcc deprecated-declarations st_theme_node_transition_paint 'clutter_alpha_get_alpha' is deprecated (declared at /usr/include/clutter-1.0/clutter/deprecated/clutter-alpha.h:116)
  1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
  2 /*
  3  * st-theme-node-transition.c: Theme node transitions for StWidget.
  4  *
  5  * Copyright 2010 Florian Mç«Żllner
  6  * Copyright 2010 Adel Gadllah
  7  *
  8  * This program is free software; you can redistribute it and/or modify
  9  * it under the terms of the GNU Lesser General Public License as
 10  * published by the Free Software Foundation, either version 2.1 of
 11  * the License, or (at your option) any later version.
 12  *
 13  * This program is distributed in the hope it will be useful, but WITHOUT ANY
 14  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 15  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 16  * more details.
 17  *
 18  * You should have received a copy of the GNU Lesser General Public License
 19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
 20  */
 21 
 22 #include "st-theme-node-transition.h"
 23 
 24 enum {
 25   COMPLETED,
 26   NEW_FRAME,
 27   LAST_SIGNAL
 28 };
 29 
 30 #define ST_THEME_NODE_TRANSITION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ST_TYPE_THEME_NODE_TRANSITION, StThemeNodeTransitionPrivate))
 31 
 32 struct _StThemeNodeTransitionPrivate {
 33   StThemeNode *old_theme_node;
 34   StThemeNode *new_theme_node;
 35 
 36   CoglHandle old_texture;
 37   CoglHandle new_texture;
 38 
 39   CoglHandle old_offscreen;
 40   CoglHandle new_offscreen;
 41 
 42   CoglHandle material;
 43 
 44   ClutterAlpha    *alpha;
 45   ClutterTimeline *timeline;
 46 
 47   guint timeline_completed_id;
 48   guint timeline_new_frame_id;
 49 
 50   ClutterActorBox last_allocation;
 51   ClutterActorBox offscreen_box;
 52 
 53   gboolean needs_setup;
 54 };
 55 
 56 static guint signals[LAST_SIGNAL] = { 0 };
 57 
 58 G_DEFINE_TYPE (StThemeNodeTransition, st_theme_node_transition, G_TYPE_OBJECT);
 59 
 60 
 61 static void
 62 on_timeline_completed (ClutterTimeline       *timeline,
 63                        StThemeNodeTransition *transition)
 64 {
 65   g_signal_emit (transition, signals[COMPLETED], 0);
 66 }
 67 
 68 static void
 69 on_timeline_new_frame (ClutterTimeline       *timeline,
 70                        gint                   frame_num,
 71                        StThemeNodeTransition *transition)
 72 {
 73   g_signal_emit (transition, signals[NEW_FRAME], 0);
 74 }
 75 
 76 StThemeNodeTransition *
 77 st_theme_node_transition_new (StThemeNode *from_node,
 78                               StThemeNode *to_node,
 79                               guint        duration)
 80 {
 81   StThemeNodeTransition *transition;
 82 
 83   g_return_val_if_fail (ST_IS_THEME_NODE (from_node), NULL);
 84   g_return_val_if_fail (ST_IS_THEME_NODE (to_node), NULL);
 85 
 86   duration = st_theme_node_get_transition_duration (to_node);
 87 
 88   transition = g_object_new (ST_TYPE_THEME_NODE_TRANSITION,
 89                              NULL);
 90 
 91   transition->priv->old_theme_node = g_object_ref (from_node);
 92   transition->priv->new_theme_node = g_object_ref (to_node);
 93 
 94   transition->priv->alpha = clutter_alpha_new ();
'clutter_alpha_new' is deprecated (declared at /usr/include/clutter-1.0/clutter/deprecated/clutter-alpha.h:105)
(emitted by gcc)
95 transition->priv->timeline = clutter_timeline_new (duration); 96 97 transition->priv->timeline_completed_id = 98 g_signal_connect (transition->priv->timeline, "completed", 99 G_CALLBACK (on_timeline_completed), transition); 100 transition->priv->timeline_new_frame_id = 101 g_signal_connect (transition->priv->timeline, "new-frame", 102 G_CALLBACK (on_timeline_new_frame), transition); 103 104 clutter_alpha_set_mode (transition->priv->alpha, CLUTTER_EASE_IN_OUT_QUAD);
'clutter_alpha_set_mode' is deprecated (declared at /usr/include/clutter-1.0/clutter/deprecated/clutter-alpha.h:131)
(emitted by gcc)
105 clutter_alpha_set_timeline (transition->priv->alpha,
'clutter_alpha_set_timeline' is deprecated (declared at /usr/include/clutter-1.0/clutter/deprecated/clutter-alpha.h:126)
(emitted by gcc)
106 transition->priv->timeline); 107 108 clutter_timeline_start (transition->priv->timeline); 109 110 return transition; 111 } 112 113 void 114 st_theme_node_transition_update (StThemeNodeTransition *transition, 115 StThemeNode *new_node) 116 { 117 StThemeNodeTransitionPrivate *priv = transition->priv; 118 StThemeNode *old_node; 119 ClutterTimelineDirection direction; 120 121 g_return_if_fail (ST_IS_THEME_NODE_TRANSITION (transition)); 122 g_return_if_fail (ST_IS_THEME_NODE (new_node)); 123 124 direction = clutter_timeline_get_direction (priv->timeline); 125 old_node = (direction == CLUTTER_TIMELINE_FORWARD) ? priv->old_theme_node 126 : priv->new_theme_node; 127 128 /* If the update is the reversal of the current transition, 129 * we reverse the timeline. 130 * Otherwise, we should initiate a new transition from the 131 * current state to the new one; this is hard to do if the 132 * transition is in an intermediate state, so we just cancel 133 * the ongoing transition in that case. 134 * Note that reversing a timeline before any time elapsed 135 * results in the timeline's time position being set to the 136 * full duration - this is not what we want, so we cancel the 137 * transition as well in that case. 138 */ 139 if (st_theme_node_equal (new_node, old_node)) 140 { 141 if (clutter_timeline_get_elapsed_time (priv->timeline) > 0) 142 { 143 if (direction == CLUTTER_TIMELINE_FORWARD) 144 clutter_timeline_set_direction (priv->timeline, 145 CLUTTER_TIMELINE_BACKWARD); 146 else 147 clutter_timeline_set_direction (priv->timeline, 148 CLUTTER_TIMELINE_FORWARD); 149 } 150 else 151 { 152 clutter_timeline_stop (priv->timeline); 153 g_signal_emit (transition, signals[COMPLETED], 0); 154 } 155 } 156 else 157 { 158 if (clutter_timeline_get_elapsed_time (priv->timeline) > 0) 159 { 160 clutter_timeline_stop (priv->timeline); 161 g_signal_emit (transition, signals[COMPLETED], 0); 162 } 163 else 164 { 165 guint new_duration = st_theme_node_get_transition_duration (new_node); 166 167 clutter_timeline_set_duration (priv->timeline, new_duration); 168 169 /* If the change doesn't affect painting, we don't need to redraw, 170 * but we still need to replace the node so that we properly share 171 * caching with the painting that happens after the transition finishes. 172 */ 173 if (!st_theme_node_paint_equal (priv->new_theme_node, new_node)) 174 priv->needs_setup = TRUE; 175 176 g_object_unref (priv->new_theme_node); 177 priv->new_theme_node = g_object_ref (new_node); 178 } 179 } 180 } 181 182 static void 183 calculate_offscreen_box (StThemeNodeTransition *transition, 184 const ClutterActorBox *allocation) 185 { 186 ClutterActorBox paint_box; 187 188 st_theme_node_transition_get_paint_box (transition, 189 allocation, 190 &paint_box); 191 transition->priv->offscreen_box.x1 = paint_box.x1 - allocation->x1; 192 transition->priv->offscreen_box.y1 = paint_box.y1 - allocation->y1; 193 transition->priv->offscreen_box.x2 = paint_box.x2 - allocation->x1; 194 transition->priv->offscreen_box.y2 = paint_box.y2 - allocation->y1; 195 } 196 197 void 198 st_theme_node_transition_get_paint_box (StThemeNodeTransition *transition, 199 const ClutterActorBox *allocation, 200 ClutterActorBox *paint_box) 201 { 202 StThemeNodeTransitionPrivate *priv = transition->priv; 203 ClutterActorBox old_node_box, new_node_box; 204 205 st_theme_node_get_paint_box (priv->old_theme_node, 206 allocation, 207 &old_node_box); 208 209 st_theme_node_get_paint_box (priv->new_theme_node, 210 allocation, 211 &new_node_box); 212 213 paint_box->x1 = MIN (old_node_box.x1, new_node_box.x1); 214 paint_box->y1 = MIN (old_node_box.y1, new_node_box.y1); 215 paint_box->x2 = MAX (old_node_box.x2, new_node_box.x2); 216 paint_box->y2 = MAX (old_node_box.y2, new_node_box.y2); 217 } 218 219 static gboolean 220 setup_framebuffers (StThemeNodeTransition *transition, 221 const ClutterActorBox *allocation) 222 { 223 StThemeNodeTransitionPrivate *priv = transition->priv; 224 CoglColor clear_color = { 0, 0, 0, 0 }; 225 guint width, height; 226 227 /* template material to avoid unnecessary shader compilation */ 228 static CoglHandle material_template = COGL_INVALID_HANDLE; 229 230 width = priv->offscreen_box.x2 - priv->offscreen_box.x1; 231 height = priv->offscreen_box.y2 - priv->offscreen_box.y1; 232 233 g_return_val_if_fail (width > 0, FALSE); 234 g_return_val_if_fail (height > 0, FALSE); 235 236 if (priv->old_texture) 237 cogl_handle_unref (priv->old_texture); 238 priv->old_texture = cogl_texture_new_with_size (width, height, 239 COGL_TEXTURE_NO_SLICING, 240 COGL_PIXEL_FORMAT_ANY); 241 242 if (priv->new_texture) 243 cogl_handle_unref (priv->new_texture); 244 priv->new_texture = cogl_texture_new_with_size (width, height, 245 COGL_TEXTURE_NO_SLICING, 246 COGL_PIXEL_FORMAT_ANY); 247 248 g_return_val_if_fail (priv->old_texture != COGL_INVALID_HANDLE, FALSE); 249 g_return_val_if_fail (priv->new_texture != COGL_INVALID_HANDLE, FALSE); 250 251 if (priv->old_offscreen) 252 cogl_handle_unref (priv->old_offscreen); 253 priv->old_offscreen = cogl_offscreen_new_to_texture (priv->old_texture); 254 255 if (priv->new_offscreen) 256 cogl_handle_unref (priv->new_offscreen); 257 priv->new_offscreen = cogl_offscreen_new_to_texture (priv->new_texture); 258 259 g_return_val_if_fail (priv->old_offscreen != COGL_INVALID_HANDLE, FALSE); 260 g_return_val_if_fail (priv->new_offscreen != COGL_INVALID_HANDLE, FALSE); 261 262 if (priv->material == NULL) 263 { 264 if (G_UNLIKELY (material_template == COGL_INVALID_HANDLE)) 265 { 266 material_template = cogl_material_new (); 267 268 cogl_material_set_layer_combine (material_template, 0, 269 "RGBA = REPLACE (TEXTURE)", 270 NULL); 271 cogl_material_set_layer_combine (material_template, 1, 272 "RGBA = INTERPOLATE (PREVIOUS, " 273 "TEXTURE, " 274 "CONSTANT[A])", 275 NULL); 276 cogl_material_set_layer_combine (material_template, 2, 277 "RGBA = MODULATE (PREVIOUS, " 278 "PRIMARY)", 279 NULL); 280 } 281 priv->material = cogl_material_copy (material_template); 282 } 283 284 cogl_material_set_layer (priv->material, 0, priv->new_texture); 285 cogl_material_set_layer (priv->material, 1, priv->old_texture); 286 287 cogl_push_framebuffer (priv->old_offscreen); 288 cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); 289 cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2, 290 priv->offscreen_box.y2, priv->offscreen_box.y1, 291 0.0, 1.0); 292 st_theme_node_paint (priv->old_theme_node, allocation, 255); 293 cogl_pop_framebuffer (); 294 295 cogl_push_framebuffer (priv->new_offscreen); 296 cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); 297 cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2, 298 priv->offscreen_box.y2, priv->offscreen_box.y1, 299 0.0, 1.0); 300 st_theme_node_paint (priv->new_theme_node, allocation, 255); 301 cogl_pop_framebuffer (); 302 303 return TRUE; 304 } 305 306 void 307 st_theme_node_transition_paint (StThemeNodeTransition *transition, 308 ClutterActorBox *allocation, 309 guint8 paint_opacity) 310 { 311 StThemeNodeTransitionPrivate *priv = transition->priv; 312 313 CoglColor constant; 314 float tex_coords[] = { 315 0.0, 0.0, 1.0, 1.0, 316 0.0, 0.0, 1.0, 1.0, 317 }; 318 319 g_return_if_fail (ST_IS_THEME_NODE (priv->old_theme_node)); 320 g_return_if_fail (ST_IS_THEME_NODE (priv->new_theme_node)); 321 322 if (!clutter_actor_box_equal (allocation, &priv->last_allocation)) 323 priv->needs_setup = TRUE; 324 325 if (priv->needs_setup) 326 { 327 priv->last_allocation = *allocation; 328 329 calculate_offscreen_box (transition, allocation); 330 priv->needs_setup = !setup_framebuffers (transition, allocation); 331 332 if (priv->needs_setup) /* setting up framebuffers failed */ 333 return; 334 } 335 336 cogl_color_set_from_4f (&constant, 0., 0., 0., 337 clutter_alpha_get_alpha (priv->alpha));
'clutter_alpha_get_alpha' is deprecated (declared at /usr/include/clutter-1.0/clutter/deprecated/clutter-alpha.h:116)
(emitted by gcc)
338 cogl_material_set_layer_combine_constant (priv->material, 1, &constant); 339 340 cogl_material_set_color4ub (priv->material, 341 paint_opacity, paint_opacity, 342 paint_opacity, paint_opacity); 343 344 cogl_set_source (priv->material); 345 cogl_rectangle_with_multitexture_coords (priv->offscreen_box.x1, 346 priv->offscreen_box.y1, 347 priv->offscreen_box.x2, 348 priv->offscreen_box.y2, 349 tex_coords, 8); 350 } 351 352 static void 353 st_theme_node_transition_dispose (GObject *object) 354 { 355 StThemeNodeTransitionPrivate *priv = ST_THEME_NODE_TRANSITION (object)->priv; 356 357 if (priv->old_theme_node) 358 { 359 g_object_unref (priv->old_theme_node); 360 priv->old_theme_node = NULL; 361 } 362 363 if (priv->new_theme_node) 364 { 365 g_object_unref (priv->new_theme_node); 366 priv->new_theme_node = NULL; 367 } 368 369 if (priv->old_texture) 370 { 371 cogl_handle_unref (priv->old_texture); 372 priv->old_texture = NULL; 373 } 374 375 if (priv->new_texture) 376 { 377 cogl_handle_unref (priv->new_texture); 378 priv->new_texture = NULL; 379 } 380 381 if (priv->old_offscreen) 382 { 383 cogl_handle_unref (priv->old_offscreen); 384 priv->old_offscreen = NULL; 385 } 386 387 if (priv->new_offscreen) 388 { 389 cogl_handle_unref (priv->new_offscreen); 390 priv->new_offscreen = NULL; 391 } 392 393 if (priv->material) 394 { 395 cogl_handle_unref (priv->material); 396 priv->material = NULL; 397 } 398 399 if (priv->timeline) 400 { 401 if (priv->timeline_completed_id != 0) 402 g_signal_handler_disconnect (priv->timeline, 403 priv->timeline_completed_id); 404 if (priv->timeline_new_frame_id != 0) 405 g_signal_handler_disconnect (priv->timeline, 406 priv->timeline_new_frame_id); 407 408 g_object_unref (priv->timeline); 409 priv->timeline = NULL; 410 } 411 412 priv->timeline_completed_id = 0; 413 priv->timeline_new_frame_id = 0; 414 415 if (priv->alpha) 416 { 417 g_object_unref (priv->alpha); 418 priv->alpha = NULL; 419 } 420 421 G_OBJECT_CLASS (st_theme_node_transition_parent_class)->dispose (object); 422 } 423 424 static void 425 st_theme_node_transition_init (StThemeNodeTransition *transition) 426 { 427 transition->priv = ST_THEME_NODE_TRANSITION_GET_PRIVATE (transition); 428 429 transition->priv->old_theme_node = NULL; 430 transition->priv->new_theme_node = NULL; 431 432 transition->priv->old_texture = NULL; 433 transition->priv->new_texture = NULL; 434 435 transition->priv->old_offscreen = NULL; 436 transition->priv->new_offscreen = NULL; 437 438 transition->priv->needs_setup = TRUE; 439 440 transition->priv->alpha = NULL; 441 } 442 443 static void 444 st_theme_node_transition_class_init (StThemeNodeTransitionClass *klass) 445 { 446 GObjectClass *object_class = G_OBJECT_CLASS (klass); 447 448 g_type_class_add_private (klass, sizeof (StThemeNodeTransitionPrivate)); 449 450 object_class->dispose = st_theme_node_transition_dispose; 451 452 signals[COMPLETED] = 453 g_signal_new ("completed", 454 G_TYPE_FROM_CLASS (klass), 455 G_SIGNAL_RUN_LAST, 456 G_STRUCT_OFFSET (StThemeNodeTransitionClass, completed), 457 NULL, NULL, NULL, 458 G_TYPE_NONE, 0); 459 460 signals[NEW_FRAME] = 461 g_signal_new ("new-frame", 462 G_TYPE_FROM_CLASS (klass), 463 G_SIGNAL_RUN_LAST, 464 G_STRUCT_OFFSET (StThemeNodeTransitionClass, new_frame), 465 NULL, NULL, NULL, 466 G_TYPE_NONE, 0); 467 }