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_strings.h"
30 #include "swfdec_bits.h"
31 #include "swfdec_debug.h"
32 #include "swfdec_player_internal.h"
33 #include "swfdec_sprite.h"
34 #include "swfdec_sprite_movie.h"
37 mc_x_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
41 swfdec_movie_update (movie
);
42 d
= SWFDEC_TWIPS_TO_DOUBLE (movie
->matrix
.x0
);
43 SWFDEC_AS_VALUE_SET_NUMBER (rval
, d
);
47 mc_x_set (SwfdecMovie
*movie
, const SwfdecAsValue
*val
)
51 d
= swfdec_as_value_to_number (SWFDEC_AS_OBJECT (movie
)->context
, val
);
53 SWFDEC_WARNING ("trying to move %s._x to a non-finite value, ignoring", movie
->name
);
56 movie
->modified
= TRUE
;
57 d
= SWFDEC_DOUBLE_TO_TWIPS (d
);
58 if (d
!= movie
->matrix
.x0
) {
60 swfdec_movie_queue_update (movie
, SWFDEC_MOVIE_INVALID_MATRIX
);
65 mc_y_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
69 swfdec_movie_update (movie
);
70 d
= SWFDEC_TWIPS_TO_DOUBLE (movie
->matrix
.y0
);
71 SWFDEC_AS_VALUE_SET_NUMBER (rval
, d
);
75 mc_y_set (SwfdecMovie
*movie
, const SwfdecAsValue
*val
)
79 d
= swfdec_as_value_to_number (SWFDEC_AS_OBJECT (movie
)->context
, val
);
81 SWFDEC_WARNING ("trying to move %s._y to a non-finite value, ignoring", movie
->name
);
84 movie
->modified
= TRUE
;
85 d
= SWFDEC_DOUBLE_TO_TWIPS (d
);
86 if (d
!= movie
->matrix
.y0
) {
88 swfdec_movie_queue_update (movie
, SWFDEC_MOVIE_INVALID_MATRIX
);
93 mc_xscale_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
95 SWFDEC_AS_VALUE_SET_NUMBER (rval
, movie
->xscale
);
99 mc_xscale_set (SwfdecMovie
*movie
, const SwfdecAsValue
*val
)
103 d
= swfdec_as_value_to_number (SWFDEC_AS_OBJECT (movie
)->context
, val
);
105 SWFDEC_WARNING ("trying to set xscale to a non-finite value, ignoring");
108 movie
->modified
= TRUE
;
110 swfdec_movie_queue_update (movie
, SWFDEC_MOVIE_INVALID_MATRIX
);
114 mc_yscale_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
116 SWFDEC_AS_VALUE_SET_NUMBER (rval
, movie
->yscale
);
120 mc_yscale_set (SwfdecMovie
*movie
, const SwfdecAsValue
*val
)
124 d
= swfdec_as_value_to_number (SWFDEC_AS_OBJECT (movie
)->context
, val
);
126 SWFDEC_WARNING ("trying to set yscale to a non-finite value, ignoring");
129 movie
->modified
= TRUE
;
131 swfdec_movie_queue_update (movie
, SWFDEC_MOVIE_INVALID_MATRIX
);
135 mc_currentframe (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
137 g_assert (SWFDEC_IS_SPRITE_MOVIE (movie
));
138 SWFDEC_AS_VALUE_SET_NUMBER (rval
, SWFDEC_SPRITE_MOVIE (movie
)->frame
);
142 mc_framesloaded (SwfdecMovie
*mov
, SwfdecAsValue
*rval
)
144 SwfdecSpriteMovie
*movie
= SWFDEC_SPRITE_MOVIE (mov
);
146 SWFDEC_AS_VALUE_SET_NUMBER (rval
, movie
->sprite
->parse_frame
);
149 SWFDEC_AS_VALUE_SET_INT (rval
, movie
->n_frames
);
153 mc_name_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
155 SWFDEC_AS_VALUE_SET_STRING (rval
, movie
->name
);
159 mc_name_set (SwfdecMovie
*movie
, const SwfdecAsValue
*val
)
161 movie
->name
= swfdec_as_value_to_string (SWFDEC_AS_OBJECT (movie
)->context
, val
);
165 mc_totalframes (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
167 g_assert (SWFDEC_IS_SPRITE_MOVIE (movie
));
168 SWFDEC_AS_VALUE_SET_INT (rval
, SWFDEC_SPRITE_MOVIE (movie
)->n_frames
);
172 mc_alpha_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
174 SWFDEC_AS_VALUE_SET_NUMBER (rval
,
175 movie
->color_transform
.aa
* 100.0 / 256.0);
179 mc_alpha_set (SwfdecMovie
*movie
, const SwfdecAsValue
*val
)
184 d
= swfdec_as_value_to_number (SWFDEC_AS_OBJECT (movie
)->context
, val
);
186 SWFDEC_WARNING ("trying to set alpha to a non-finite value, ignoring");
189 alpha
= d
* 256.0 / 100.0;
190 if (alpha
!= movie
->color_transform
.aa
) {
191 movie
->color_transform
.aa
= alpha
;
192 swfdec_movie_invalidate (movie
);
197 mc_visible_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
199 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, movie
->visible
);
203 mc_visible_set (SwfdecMovie
*movie
, const SwfdecAsValue
*val
)
207 b
= swfdec_as_value_to_boolean (SWFDEC_AS_OBJECT (movie
)->context
, val
);
208 if (b
!= movie
->visible
) {
210 swfdec_movie_invalidate (movie
);
215 mc_width_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
219 swfdec_movie_update (movie
);
220 d
= rint (movie
->extents
.x1
- movie
->extents
.x0
);
221 d
= SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) d
);
222 SWFDEC_AS_VALUE_SET_NUMBER (rval
, d
);
226 mc_width_set (SwfdecMovie
*movie
, const SwfdecAsValue
*val
)
230 /* property was readonly in Flash 4 and before */
231 if (SWFDEC_AS_OBJECT (movie
)->context
->version
< 5)
233 d
= swfdec_as_value_to_number (SWFDEC_AS_OBJECT (movie
)->context
, val
);
235 SWFDEC_WARNING ("trying to set width to a non-finite value, ignoring");
238 swfdec_movie_update (movie
);
239 movie
->modified
= TRUE
;
240 cur
= rint (movie
->original_extents
.x1
- movie
->original_extents
.x0
);
241 cur
= SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) cur
);
243 movie
->xscale
= 100 * d
/ cur
;
248 swfdec_movie_queue_update (movie
, SWFDEC_MOVIE_INVALID_MATRIX
);
252 mc_height_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
256 swfdec_movie_update (movie
);
257 d
= rint (movie
->extents
.y1
- movie
->extents
.y0
);
258 d
= SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) d
);
259 SWFDEC_AS_VALUE_SET_NUMBER (rval
, d
);
263 mc_height_set (SwfdecMovie
*movie
, const SwfdecAsValue
*val
)
267 /* property was readonly in Flash 4 and before */
268 if (SWFDEC_AS_OBJECT (movie
)->context
->version
< 5)
270 d
= swfdec_as_value_to_number (SWFDEC_AS_OBJECT (movie
)->context
, val
);
272 SWFDEC_WARNING ("trying to set height to a non-finite value, ignoring");
275 swfdec_movie_update (movie
);
276 movie
->modified
= TRUE
;
277 cur
= rint (movie
->original_extents
.y1
- movie
->original_extents
.y0
);
278 cur
= SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) cur
);
280 movie
->yscale
= 100 * d
/ cur
;
285 swfdec_movie_queue_update (movie
, SWFDEC_MOVIE_INVALID_MATRIX
);
289 mc_rotation_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
291 SWFDEC_AS_VALUE_SET_NUMBER (rval
, movie
->rotation
);
295 mc_rotation_set (SwfdecMovie
*movie
, const SwfdecAsValue
*val
)
299 /* FIXME: Flash 4 handles this differently */
300 d
= swfdec_as_value_to_number (SWFDEC_AS_OBJECT (movie
)->context
, val
);
302 SWFDEC_WARNING ("setting rotation to NaN - not allowed");
310 if (SWFDEC_AS_OBJECT (movie
)->context
->version
< 5) {
313 SWFDEC_ERROR ("FIXME: implement correct rounding errors here");
315 movie
->modified
= TRUE
;
317 swfdec_movie_queue_update (movie
, SWFDEC_MOVIE_INVALID_MATRIX
);
321 mc_xmouse_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
325 swfdec_movie_get_mouse (movie
, &x
, &y
);
326 x
= SWFDEC_TWIPS_TO_DOUBLE (rint (x
));
327 SWFDEC_AS_VALUE_SET_NUMBER (rval
, x
);
331 mc_ymouse_get (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
335 swfdec_movie_get_mouse (movie
, &x
, &y
);
336 y
= SWFDEC_TWIPS_TO_DOUBLE (rint (y
));
337 SWFDEC_AS_VALUE_SET_NUMBER (rval
, y
);
341 mc_parent (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
344 SWFDEC_AS_VALUE_SET_OBJECT (rval
, SWFDEC_AS_OBJECT (movie
->parent
));
346 SWFDEC_AS_VALUE_SET_UNDEFINED (rval
);
351 mc_root (SwfdecMovie
*movie
, SwfdecAsValue
*rval
)
353 while (movie
->parent
)
354 movie
= movie
->parent
;
355 SWFDEC_AS_VALUE_SET_OBJECT (rval
, SWFDEC_AS_OBJECT (movie
));
359 gboolean needs_movie
;
361 void (* get
) (SwfdecMovie
*movie
, SwfdecAsValue
*ret
);
362 void (* set
) (SwfdecMovie
*movie
, const SwfdecAsValue
*val
);
363 } swfdec_movieclip_props
[] = {
364 { 0, SWFDEC_AS_STR__x
, mc_x_get
, mc_x_set
},
365 { 0, SWFDEC_AS_STR__y
, mc_y_get
, mc_y_set
},
366 { 0, SWFDEC_AS_STR__xscale
, mc_xscale_get
, mc_xscale_set
},
367 { 0, SWFDEC_AS_STR__yscale
, mc_yscale_get
, mc_yscale_set
},
368 { 1, SWFDEC_AS_STR__currentframe
,mc_currentframe
, NULL
},
369 { 1, SWFDEC_AS_STR__totalframes
, mc_totalframes
, NULL
},
370 { 0, SWFDEC_AS_STR__alpha
, mc_alpha_get
, mc_alpha_set
},
371 { 0, SWFDEC_AS_STR__visible
, mc_visible_get
, mc_visible_set
},
372 { 0, SWFDEC_AS_STR__width
, mc_width_get
, mc_width_set
},
373 { 0, SWFDEC_AS_STR__height
, mc_height_get
, mc_height_set
},
374 { 0, SWFDEC_AS_STR__rotation
, mc_rotation_get
, mc_rotation_set
},
375 { 1, SWFDEC_AS_STR__target
, NULL
, NULL
}, //"_target"
376 { 1, SWFDEC_AS_STR__framesloaded
,mc_framesloaded
, NULL
},
377 { 0, SWFDEC_AS_STR__name
, mc_name_get
, mc_name_set
},
378 { 1, SWFDEC_AS_STR__droptarget
, NULL
, NULL
}, //"_droptarget"
379 { 0, SWFDEC_AS_STR__url
, NULL
, NULL
}, //"_url"
380 { 0, SWFDEC_AS_STR__highquality
, NULL
, NULL
}, //"_highquality"
381 { 0, SWFDEC_AS_STR__focusrect
, NULL
, NULL
}, //"_focusrect"
382 { 0, SWFDEC_AS_STR__soundbuftime
,NULL
, NULL
}, //"_soundbuftime"
383 { 0, SWFDEC_AS_STR__quality
, NULL
, NULL
}, //"_quality"
384 { 0, SWFDEC_AS_STR__xmouse
, mc_xmouse_get
, NULL
},
385 { 0, SWFDEC_AS_STR__ymouse
, mc_ymouse_get
, NULL
},
386 { 0, SWFDEC_AS_STR__parent
, mc_parent
, NULL
},
387 { 0, SWFDEC_AS_STR__root
, mc_root
, NULL
},
391 swfdec_movie_get_asprop_index (SwfdecMovie
*movie
, const char *name
)
395 if (name
< SWFDEC_AS_STR__x
|| name
> SWFDEC_AS_STR__root
)
398 for (i
= 0; i
< G_N_ELEMENTS (swfdec_movieclip_props
); i
++) {
399 if (swfdec_movieclip_props
[i
].name
== name
) {
400 if (swfdec_movieclip_props
[i
].needs_movie
&& !SWFDEC_IS_SPRITE_MOVIE (movie
))
402 if (swfdec_movieclip_props
[i
].get
== NULL
) {
403 SWFDEC_ERROR ("property %s not implemented", name
);
408 g_assert_not_reached ();
413 swfdec_movie_set_asprop (SwfdecMovie
*movie
, const char *name
, const SwfdecAsValue
*val
)
417 i
= swfdec_movie_get_asprop_index (movie
, name
);
420 if (swfdec_movieclip_props
[i
].set
!= NULL
) {
421 swfdec_movieclip_props
[i
].set (movie
, val
);
427 swfdec_movie_get_asprop (SwfdecMovie
*movie
, const char *name
, SwfdecAsValue
*val
)
431 i
= swfdec_movie_get_asprop_index (movie
, name
);
434 if (swfdec_movieclip_props
[i
].get
!= NULL
) {
435 swfdec_movieclip_props
[i
].get (movie
, val
);
437 SWFDEC_AS_VALUE_SET_UNDEFINED (val
);