fix build for --disable-gtk-doc
[swfdec.git] / swfdec / swfdec_movie_asprops.c
blob7d018abc074e9e4669dcf6ee0b243666c7e5456c
1 /* Swfdec
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
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include <string.h>
26 #include <math.h>
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"
40 static SwfdecAsValue
41 mc_x_get (SwfdecMovie *movie)
43 double d;
44 SwfdecAsValue rval;
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);
49 return rval;
52 static void
53 mc_x_set (SwfdecMovie *movie, SwfdecAsValue val)
55 SwfdecTwips x;
57 if (!swfdec_as_value_to_twips (swfdec_gc_object_get_context (movie), &val, FALSE, &x))
58 return;
59 movie->modified = TRUE;
60 if (x != movie->matrix.x0) {
61 swfdec_movie_begin_update_matrix (movie);
62 movie->matrix.x0 = x;
63 swfdec_movie_end_update_matrix (movie);
67 static SwfdecAsValue
68 mc_y_get (SwfdecMovie *movie)
70 double d;
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);
77 static void
78 mc_y_set (SwfdecMovie *movie, SwfdecAsValue val)
80 SwfdecTwips y;
82 if (!swfdec_as_value_to_twips (swfdec_gc_object_get_context (movie), &val, FALSE, &y))
83 return;
84 movie->modified = TRUE;
85 if (y != movie->matrix.y0) {
86 swfdec_movie_begin_update_matrix (movie);
87 movie->matrix.y0 = y;
88 swfdec_movie_end_update_matrix (movie);
92 static SwfdecAsValue
93 mc_xscale_get (SwfdecMovie *movie)
95 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie), movie->xscale);
98 static void
99 mc_xscale_set (SwfdecMovie *movie, SwfdecAsValue val)
101 double d;
103 d = swfdec_as_value_to_number (swfdec_gc_object_get_context (movie), val);
104 if (!isfinite (d)) {
105 SWFDEC_WARNING ("trying to set xscale to a non-finite value, ignoring");
106 return;
108 movie->modified = TRUE;
109 if (movie->xscale != d) {
110 swfdec_movie_begin_update_matrix (movie);
111 movie->xscale = d;
112 swfdec_movie_end_update_matrix (movie);
116 static SwfdecAsValue
117 mc_yscale_get (SwfdecMovie *movie)
119 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie), movie->yscale);
122 static void
123 mc_yscale_set (SwfdecMovie *movie, SwfdecAsValue val)
125 double d;
127 d = swfdec_as_value_to_number (swfdec_gc_object_get_context (movie), val);
128 if (!isfinite (d)) {
129 SWFDEC_WARNING ("trying to set yscale to a non-finite value, ignoring");
130 return;
132 movie->modified = TRUE;
133 if (movie->yscale != d) {
134 swfdec_movie_begin_update_matrix (movie);
135 movie->yscale = d;
136 swfdec_movie_end_update_matrix (movie);
140 static SwfdecAsValue
141 mc_name_get (SwfdecMovie *movie)
143 return SWFDEC_AS_VALUE_FROM_STRING (movie->name);
146 static void
147 mc_name_set (SwfdecMovie *movie, SwfdecAsValue val)
149 movie->name = swfdec_as_value_to_string (swfdec_gc_object_get_context (movie), val);
152 static SwfdecAsValue
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);
159 static void
160 mc_alpha_set (SwfdecMovie *movie, SwfdecAsValue val)
162 double d;
163 int alpha;
165 d = swfdec_as_value_to_number (swfdec_gc_object_get_context (movie), val);
166 if (!isfinite (d)) {
167 SWFDEC_WARNING ("trying to set alpha to a non-finite value, ignoring");
168 return;
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);
177 static SwfdecAsValue
178 mc_visible_get (SwfdecMovie *movie)
180 return SWFDEC_AS_VALUE_FROM_BOOLEAN (movie->visible);
183 static void
184 mc_visible_set (SwfdecMovie *movie, SwfdecAsValue val)
186 gboolean b;
188 b = swfdec_as_value_to_boolean (swfdec_gc_object_get_context (movie), val);
189 if (b != movie->visible) {
190 movie->visible = b;
191 swfdec_movie_invalidate_last (movie);
195 static SwfdecAsValue
196 mc_width_get (SwfdecMovie *movie)
198 double d;
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);
206 static void
207 mc_width_set (SwfdecMovie *movie, SwfdecAsValue val)
209 double d, cur;
211 /* property was readonly in Flash 4 and before */
212 if (swfdec_gc_object_get_context (movie)->version < 5)
213 return;
214 d = swfdec_as_value_to_number (swfdec_gc_object_get_context (movie), val);
215 if (!isfinite (d)) {
216 SWFDEC_WARNING ("trying to set width to a non-finite value, ignoring");
217 return;
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);
223 if (cur != 0) {
224 d = 100 * d / cur;
225 if (d == movie->xscale)
226 return;
227 swfdec_movie_begin_update_matrix (movie);
228 movie->xscale = d;
229 } else {
230 swfdec_movie_begin_update_matrix (movie);
231 movie->xscale = 0;
232 movie->yscale = 0;
234 swfdec_movie_end_update_matrix (movie);
237 static SwfdecAsValue
238 mc_height_get (SwfdecMovie *movie)
240 double d;
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);
248 static void
249 mc_height_set (SwfdecMovie *movie, SwfdecAsValue val)
251 double d, cur;
253 /* property was readonly in Flash 4 and before */
254 if (swfdec_gc_object_get_context (movie)->version < 5)
255 return;
256 d = swfdec_as_value_to_number (swfdec_gc_object_get_context (movie), val);
257 if (!isfinite (d)) {
258 SWFDEC_WARNING ("trying to set height to a non-finite value, ignoring");
259 return;
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);
265 if (cur != 0) {
266 d = 100 * d / cur;
267 if (d == movie->yscale)
268 return;
269 swfdec_movie_begin_update_matrix (movie);
270 movie->yscale = d;
271 } else {
272 swfdec_movie_begin_update_matrix (movie);
273 movie->xscale = 0;
274 movie->yscale = 0;
276 swfdec_movie_end_update_matrix (movie);
279 static SwfdecAsValue
280 mc_rotation_get (SwfdecMovie *movie)
282 return swfdec_as_value_from_number (swfdec_gc_object_get_context (movie), movie->rotation);
285 static void
286 mc_rotation_set (SwfdecMovie *movie, SwfdecAsValue val)
288 double d;
290 /* FIXME: Flash 4 handles this differently */
291 d = swfdec_as_value_to_number (swfdec_gc_object_get_context (movie), val);
292 if (isnan (d)) {
293 SWFDEC_WARNING ("setting rotation to NaN - not allowed");
294 return;
296 d = fmod (d, 360.0);
297 if (d > 180.0)
298 d -= 360.0;
299 if (d < -180.0)
300 d += 360.0;
301 if (swfdec_gc_object_get_context (movie)->version < 5) {
302 if (!isfinite (d))
303 return;
304 SWFDEC_FIXME ("implement correct rounding errors here");
306 movie->modified = TRUE;
307 if (movie->rotation != d) {
308 swfdec_movie_begin_update_matrix (movie);
309 movie->rotation = d;
310 swfdec_movie_end_update_matrix (movie);
314 static SwfdecAsValue
315 mc_xmouse_get (SwfdecMovie *movie)
317 double x, y;
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);
324 static SwfdecAsValue
325 mc_ymouse_get (SwfdecMovie *movie)
327 double x, y;
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);
334 static SwfdecAsValue
335 mc_parent (SwfdecMovie *movie)
337 if (movie->parent) {
338 return SWFDEC_AS_VALUE_FROM_MOVIE (movie->parent);
339 } else {
340 return SWFDEC_AS_VALUE_UNDEFINED;
344 static SwfdecAsValue
345 mc_root (SwfdecMovie *movie)
347 movie = swfdec_movie_get_root (movie);
348 return SWFDEC_AS_VALUE_FROM_MOVIE (movie);
351 static SwfdecAsValue
352 mc_target_get (SwfdecMovie *movie)
354 GString *s;
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;
362 if (s->len == 0) {
363 g_string_free (s, TRUE);
364 return SWFDEC_AS_VALUE_FROM_STRING (SWFDEC_AS_STR_SLASH);
365 } else {
366 return SWFDEC_AS_VALUE_FROM_STRING (swfdec_as_context_give_string (
367 swfdec_gc_object_get_context (movie), g_string_free (s, FALSE)));
371 static SwfdecAsValue
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))));
379 static SwfdecAsValue
380 mc_focusrect_get (SwfdecMovie *movie)
382 SwfdecAsContext *cx;
383 SwfdecActor *actor;
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:
394 if (cx->version > 5)
395 return SWFDEC_AS_VALUE_TRUE;
396 else
397 return swfdec_as_value_from_integer (cx, 1);
398 break;
399 case SWFDEC_FLASH_NO:
400 if (cx->version > 5)
401 return SWFDEC_AS_VALUE_FALSE;
402 else
403 return swfdec_as_value_from_integer (cx, 0);
404 break;
405 case SWFDEC_FLASH_MAYBE:
406 return SWFDEC_AS_VALUE_NULL;
407 break;
408 default:
409 g_assert_not_reached();
410 return SWFDEC_AS_VALUE_UNDEFINED;
414 static void
415 mc_focusrect_set (SwfdecMovie *movie, SwfdecAsValue val)
417 SwfdecAsContext *cx;
418 SwfdecActor *actor;
419 SwfdecFlashBool b;
421 if (!SWFDEC_IS_ACTOR (movie)) {
422 SWFDEC_FIXME ("should not be possible to get _focusrect on non-actors");
423 return;
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)
431 return;
432 b = SWFDEC_FLASH_MAYBE;
433 } else {
434 if (movie->parent == NULL) {
435 double d = swfdec_as_value_to_number (cx, val);
436 if (isnan (d))
437 return;
438 b = d ? SWFDEC_FLASH_YES : SWFDEC_FLASH_NO;
439 } else {
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));
453 struct {
454 const char * name;
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 },
484 guint
485 swfdec_movie_property_lookup (const char *name)
487 guint i;
489 for (i = 0; i < G_N_ELEMENTS (swfdec_movieclip_props); i++) {
490 if (swfdec_movieclip_props[i].name == name)
491 return i;
493 return G_MAXUINT;
496 SwfdecAsValue
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;
502 } else {
503 return swfdec_movieclip_props[id].get (movie);
507 void
508 swfdec_movie_property_do_set (SwfdecMovie *movie, guint id,
509 SwfdecAsValue val)
511 if (id < G_N_ELEMENTS (swfdec_movieclip_props) &&
512 swfdec_movieclip_props[id].set != NULL) {
513 swfdec_movieclip_props[id].set (movie, val);