2 * Copyright (C) 2003-2006 David Schleef <ds@schleef.org>
3 * 2005-2006 Eric Anholt <eric@anholt.net>
4 * 2006-2007 Benjamin Otte <otte@gnome.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
28 #include "swfdec_movie.h"
29 #include "swfdec_as_internal.h"
30 #include "swfdec_as_strings.h"
31 #include "swfdec_bits.h"
32 #include "swfdec_debug.h"
33 #include "swfdec_decoder.h"
34 #include "swfdec_internal.h"
35 #include "swfdec_player_internal.h"
36 #include "swfdec_sprite.h"
37 #include "swfdec_sprite_movie.h"
38 #include "swfdec_resource.h"
41 mc_x_get (SwfdecMovie
*movie
)
46 swfdec_movie_update (movie
);
47 d
= SWFDEC_TWIPS_TO_DOUBLE (movie
->matrix
.x0
);
48 rval
= swfdec_as_value_from_number (swfdec_gc_object_get_context (movie
), d
);
53 mc_x_set (SwfdecMovie
*movie
, SwfdecAsValue val
)
57 if (!swfdec_as_value_to_twips (swfdec_gc_object_get_context (movie
), &val
, FALSE
, &x
))
59 movie
->modified
= TRUE
;
60 if (x
!= movie
->matrix
.x0
) {
61 swfdec_movie_begin_update_matrix (movie
);
63 swfdec_movie_end_update_matrix (movie
);
68 mc_y_get (SwfdecMovie
*movie
)
72 swfdec_movie_update (movie
);
73 d
= SWFDEC_TWIPS_TO_DOUBLE (movie
->matrix
.y0
);
74 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie
), d
);
78 mc_y_set (SwfdecMovie
*movie
, SwfdecAsValue val
)
82 if (!swfdec_as_value_to_twips (swfdec_gc_object_get_context (movie
), &val
, FALSE
, &y
))
84 movie
->modified
= TRUE
;
85 if (y
!= movie
->matrix
.y0
) {
86 swfdec_movie_begin_update_matrix (movie
);
88 swfdec_movie_end_update_matrix (movie
);
93 mc_xscale_get (SwfdecMovie
*movie
)
95 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie
), movie
->xscale
);
99 mc_xscale_set (SwfdecMovie
*movie
, SwfdecAsValue val
)
103 d
= swfdec_as_value_to_number (swfdec_gc_object_get_context (movie
), val
);
105 SWFDEC_WARNING ("trying to set xscale to a non-finite value, ignoring");
108 movie
->modified
= TRUE
;
109 if (movie
->xscale
!= d
) {
110 swfdec_movie_begin_update_matrix (movie
);
112 swfdec_movie_end_update_matrix (movie
);
117 mc_yscale_get (SwfdecMovie
*movie
)
119 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie
), movie
->yscale
);
123 mc_yscale_set (SwfdecMovie
*movie
, SwfdecAsValue val
)
127 d
= swfdec_as_value_to_number (swfdec_gc_object_get_context (movie
), val
);
129 SWFDEC_WARNING ("trying to set yscale to a non-finite value, ignoring");
132 movie
->modified
= TRUE
;
133 if (movie
->yscale
!= d
) {
134 swfdec_movie_begin_update_matrix (movie
);
136 swfdec_movie_end_update_matrix (movie
);
141 mc_name_get (SwfdecMovie
*movie
)
143 return SWFDEC_AS_VALUE_FROM_STRING (movie
->name
);
147 mc_name_set (SwfdecMovie
*movie
, SwfdecAsValue val
)
149 movie
->name
= swfdec_as_value_to_string (swfdec_gc_object_get_context (movie
), val
);
153 mc_alpha_get (SwfdecMovie
*movie
)
155 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie
),
156 movie
->color_transform
.aa
* 100.0 / 256.0);
160 mc_alpha_set (SwfdecMovie
*movie
, SwfdecAsValue val
)
165 d
= swfdec_as_value_to_number (swfdec_gc_object_get_context (movie
), val
);
167 SWFDEC_WARNING ("trying to set alpha to a non-finite value, ignoring");
170 alpha
= d
* 256.0 / 100.0;
171 if (alpha
!= movie
->color_transform
.aa
) {
172 movie
->color_transform
.aa
= alpha
;
173 swfdec_movie_invalidate_last (movie
);
178 mc_visible_get (SwfdecMovie
*movie
)
180 return SWFDEC_AS_VALUE_FROM_BOOLEAN (movie
->visible
);
184 mc_visible_set (SwfdecMovie
*movie
, SwfdecAsValue val
)
188 b
= swfdec_as_value_to_boolean (swfdec_gc_object_get_context (movie
), val
);
189 if (b
!= movie
->visible
) {
191 swfdec_movie_invalidate_last (movie
);
196 mc_width_get (SwfdecMovie
*movie
)
200 swfdec_movie_update (movie
);
201 d
= rint (movie
->extents
.x1
- movie
->extents
.x0
);
202 d
= SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) d
);
203 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie
), d
);
207 mc_width_set (SwfdecMovie
*movie
, SwfdecAsValue val
)
211 /* property was readonly in Flash 4 and before */
212 if (swfdec_gc_object_get_context (movie
)->version
< 5)
214 d
= swfdec_as_value_to_number (swfdec_gc_object_get_context (movie
), val
);
216 SWFDEC_WARNING ("trying to set width to a non-finite value, ignoring");
219 swfdec_movie_update (movie
);
220 movie
->modified
= TRUE
;
221 cur
= rint (movie
->original_extents
.x1
- movie
->original_extents
.x0
);
222 cur
= SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) cur
);
225 if (d
== movie
->xscale
)
227 swfdec_movie_begin_update_matrix (movie
);
230 swfdec_movie_begin_update_matrix (movie
);
234 swfdec_movie_end_update_matrix (movie
);
238 mc_height_get (SwfdecMovie
*movie
)
242 swfdec_movie_update (movie
);
243 d
= rint (movie
->extents
.y1
- movie
->extents
.y0
);
244 d
= SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) d
);
245 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie
), d
);
249 mc_height_set (SwfdecMovie
*movie
, SwfdecAsValue val
)
253 /* property was readonly in Flash 4 and before */
254 if (swfdec_gc_object_get_context (movie
)->version
< 5)
256 d
= swfdec_as_value_to_number (swfdec_gc_object_get_context (movie
), val
);
258 SWFDEC_WARNING ("trying to set height to a non-finite value, ignoring");
261 swfdec_movie_update (movie
);
262 movie
->modified
= TRUE
;
263 cur
= rint (movie
->original_extents
.y1
- movie
->original_extents
.y0
);
264 cur
= SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) cur
);
267 if (d
== movie
->yscale
)
269 swfdec_movie_begin_update_matrix (movie
);
272 swfdec_movie_begin_update_matrix (movie
);
276 swfdec_movie_end_update_matrix (movie
);
280 mc_rotation_get (SwfdecMovie
*movie
)
282 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie
), movie
->rotation
);
286 mc_rotation_set (SwfdecMovie
*movie
, SwfdecAsValue val
)
290 /* FIXME: Flash 4 handles this differently */
291 d
= swfdec_as_value_to_number (swfdec_gc_object_get_context (movie
), val
);
293 SWFDEC_WARNING ("setting rotation to NaN - not allowed");
301 if (swfdec_gc_object_get_context (movie
)->version
< 5) {
304 SWFDEC_FIXME ("implement correct rounding errors here");
306 movie
->modified
= TRUE
;
307 if (movie
->rotation
!= d
) {
308 swfdec_movie_begin_update_matrix (movie
);
310 swfdec_movie_end_update_matrix (movie
);
315 mc_xmouse_get (SwfdecMovie
*movie
)
319 swfdec_movie_get_mouse (movie
, &x
, &y
);
320 x
= SWFDEC_TWIPS_TO_DOUBLE (rint (x
));
321 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie
), x
);
325 mc_ymouse_get (SwfdecMovie
*movie
)
329 swfdec_movie_get_mouse (movie
, &x
, &y
);
330 y
= SWFDEC_TWIPS_TO_DOUBLE (rint (y
));
331 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie
), y
);
335 mc_parent (SwfdecMovie
*movie
)
338 return SWFDEC_AS_VALUE_FROM_MOVIE (movie
->parent
);
340 return SWFDEC_AS_VALUE_UNDEFINED
;
345 mc_root (SwfdecMovie
*movie
)
347 movie
= swfdec_movie_get_root (movie
);
348 return SWFDEC_AS_VALUE_FROM_MOVIE (movie
);
352 mc_target_get (SwfdecMovie
*movie
)
356 s
= g_string_new ("");
357 while (movie
->parent
) {
358 g_string_prepend (s
, movie
->name
);
359 g_string_prepend_c (s
, '/');
360 movie
= movie
->parent
;
363 g_string_free (s
, TRUE
);
364 return SWFDEC_AS_VALUE_FROM_STRING (SWFDEC_AS_STR_SLASH
);
366 return SWFDEC_AS_VALUE_FROM_STRING (swfdec_as_context_give_string (
367 swfdec_gc_object_get_context (movie
), g_string_free (s
, FALSE
)));
372 mc_url_get (SwfdecMovie
*movie
)
374 return SWFDEC_AS_VALUE_FROM_STRING (swfdec_as_context_get_string (
375 swfdec_gc_object_get_context (movie
),
376 swfdec_url_get_url (swfdec_loader_get_url (movie
->resource
->loader
))));
380 mc_focusrect_get (SwfdecMovie
*movie
)
385 if (!SWFDEC_IS_ACTOR (movie
)) {
386 SWFDEC_FIXME ("should not be possible to get _focusrect on non-actors");
387 return SWFDEC_AS_VALUE_UNDEFINED
;
389 actor
= SWFDEC_ACTOR (movie
);
390 cx
= swfdec_gc_object_get_context (actor
);
392 switch (actor
->focusrect
) {
393 case SWFDEC_FLASH_YES
:
395 return SWFDEC_AS_VALUE_TRUE
;
397 return swfdec_as_value_from_integer (cx
, 1);
399 case SWFDEC_FLASH_NO
:
401 return SWFDEC_AS_VALUE_FALSE
;
403 return swfdec_as_value_from_integer (cx
, 0);
405 case SWFDEC_FLASH_MAYBE
:
406 return SWFDEC_AS_VALUE_NULL
;
409 g_assert_not_reached();
410 return SWFDEC_AS_VALUE_UNDEFINED
;
415 mc_focusrect_set (SwfdecMovie
*movie
, SwfdecAsValue val
)
421 if (!SWFDEC_IS_ACTOR (movie
)) {
422 SWFDEC_FIXME ("should not be possible to get _focusrect on non-actors");
425 cx
= swfdec_gc_object_get_context (movie
);
426 actor
= SWFDEC_ACTOR (movie
);
428 if (SWFDEC_AS_VALUE_IS_UNDEFINED (val
) ||
429 SWFDEC_AS_VALUE_IS_NULL (val
)) {
430 if (movie
->parent
== NULL
)
432 b
= SWFDEC_FLASH_MAYBE
;
434 if (movie
->parent
== NULL
) {
435 double d
= swfdec_as_value_to_number (cx
, val
);
438 b
= d
? SWFDEC_FLASH_YES
: SWFDEC_FLASH_NO
;
440 b
= swfdec_as_value_to_boolean (cx
, val
) ? SWFDEC_FLASH_YES
: SWFDEC_FLASH_NO
;
444 if (b
!= actor
->focusrect
) {
445 SwfdecPlayerPrivate
*priv
= SWFDEC_PLAYER (cx
)->priv
;
446 gboolean had_focusrect
= priv
->focus
? swfdec_actor_has_focusrect (priv
->focus
) : FALSE
;
447 actor
->focusrect
= b
;
448 if (priv
->focus
&& had_focusrect
!= swfdec_actor_has_focusrect (priv
->focus
))
449 swfdec_player_invalidate_focusrect (SWFDEC_PLAYER (cx
));
455 SwfdecAsValue (* get
) (SwfdecMovie
*movie
);
456 void (* set
) (SwfdecMovie
*movie
, SwfdecAsValue val
);
457 } swfdec_movieclip_props
[] = {
458 { SWFDEC_AS_STR__x
, mc_x_get
, mc_x_set
},
459 { SWFDEC_AS_STR__y
, mc_y_get
, mc_y_set
},
460 { SWFDEC_AS_STR__xscale
, mc_xscale_get
, mc_xscale_set
},
461 { SWFDEC_AS_STR__yscale
, mc_yscale_get
, mc_yscale_set
},
462 { SWFDEC_AS_STR__currentframe
,NULL
, NULL
},
463 { SWFDEC_AS_STR__totalframes
, NULL
, NULL
},
464 { SWFDEC_AS_STR__alpha
, mc_alpha_get
, mc_alpha_set
},
465 { SWFDEC_AS_STR__visible
, mc_visible_get
, mc_visible_set
},
466 { SWFDEC_AS_STR__width
, mc_width_get
, mc_width_set
},
467 { SWFDEC_AS_STR__height
, mc_height_get
, mc_height_set
},
468 { SWFDEC_AS_STR__rotation
, mc_rotation_get
, mc_rotation_set
},
469 { SWFDEC_AS_STR__target
, mc_target_get
, NULL
},
470 { SWFDEC_AS_STR__framesloaded
,NULL
, NULL
},
471 { SWFDEC_AS_STR__name
, mc_name_get
, mc_name_set
},
472 { SWFDEC_AS_STR__droptarget
, NULL
, NULL
}, //"_droptarget"
473 { SWFDEC_AS_STR__url
, mc_url_get
, NULL
},
474 { SWFDEC_AS_STR__highquality
, NULL
, NULL
}, //"_highquality"
475 { SWFDEC_AS_STR__focusrect
, mc_focusrect_get
, mc_focusrect_set
}, //"_focusrect"
476 { SWFDEC_AS_STR__soundbuftime
,NULL
, NULL
}, //"_soundbuftime"
477 { SWFDEC_AS_STR__quality
, NULL
, NULL
}, //"_quality"
478 { SWFDEC_AS_STR__xmouse
, mc_xmouse_get
, NULL
},
479 { SWFDEC_AS_STR__ymouse
, mc_ymouse_get
, NULL
},
480 { SWFDEC_AS_STR__parent
, mc_parent
, NULL
},
481 { SWFDEC_AS_STR__root
, mc_root
, NULL
},
485 swfdec_movie_property_lookup (const char *name
)
489 for (i
= 0; i
< G_N_ELEMENTS (swfdec_movieclip_props
); i
++) {
490 if (swfdec_movieclip_props
[i
].name
== name
)
497 swfdec_movie_property_do_get (SwfdecMovie
*movie
, guint id
)
499 if (id
>= G_N_ELEMENTS (swfdec_movieclip_props
) ||
500 swfdec_movieclip_props
[id
].get
== NULL
) {
501 return SWFDEC_AS_VALUE_UNDEFINED
;
503 return swfdec_movieclip_props
[id
].get (movie
);
508 swfdec_movie_property_do_set (SwfdecMovie
*movie
, guint id
,
511 if (id
< G_N_ELEMENTS (swfdec_movieclip_props
) &&
512 swfdec_movieclip_props
[id
].set
!= NULL
) {
513 swfdec_movieclip_props
[id
].set (movie
, val
);