fix swfdec_as_context_startup() to work on non-SwfdecPlayer objects
[swfdec.git] / libswfdec / swfdec_player_as.c
blob5856ebce0895dc6f9956a2f5d0e59c6f91c587d7
1 /* Swfdec
2 * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 /* NB: include this first, it redefines SWFDEC_AS_NATIVE */
25 #include "swfdec_asnative.h"
27 #include "swfdec_player_internal.h"
28 #include "swfdec_as_function.h"
29 #include "swfdec_as_internal.h"
30 #include "swfdec_as_native_function.h"
31 #include "swfdec_as_object.h"
32 #include "swfdec_as_strings.h"
33 #include "swfdec_debug.h"
34 #include "swfdec_internal.h"
35 #include "swfdec_interval.h"
36 /* FIXME: to avoid duplicate definitions */
37 #undef SWFDEC_AS_NATIVE
38 #define SWFDEC_AS_NATIVE(x, y, func)
40 /*** INTERVALS ***/
42 static void
43 swfdec_player_do_set_interval (gboolean repeat, SwfdecAsContext *cx, guint argc,
44 SwfdecAsValue *argv, SwfdecAsValue *rval)
46 SwfdecPlayer *player = SWFDEC_PLAYER (cx);
47 SwfdecAsObject *object;
48 guint id, msecs;
49 #define MIN_INTERVAL_TIME 10
51 if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[0])) {
52 SWFDEC_WARNING ("first argument to setInterval is not an object");
53 return;
55 object = SWFDEC_AS_VALUE_GET_OBJECT (&argv[0]);
56 if (SWFDEC_IS_AS_FUNCTION (object)) {
57 msecs = swfdec_as_value_to_integer (cx, &argv[1]);
58 if (msecs < MIN_INTERVAL_TIME) {
59 SWFDEC_INFO ("interval duration is %u, making it %u msecs", msecs, MIN_INTERVAL_TIME);
60 msecs = MIN_INTERVAL_TIME;
62 id = swfdec_interval_new_function (player, msecs, repeat,
63 SWFDEC_AS_FUNCTION (object), argc - 2, &argv[2]);
64 } else {
65 const char *name;
66 if (argc < 3) {
67 SWFDEC_WARNING ("setInterval needs 3 arguments when not called with function");
68 return;
70 name = swfdec_as_value_to_string (cx, &argv[1]);
71 msecs = swfdec_as_value_to_integer (cx, &argv[2]);
72 if (msecs < MIN_INTERVAL_TIME) {
73 SWFDEC_INFO ("interval duration is %u, making it %u msecs", msecs, MIN_INTERVAL_TIME);
74 msecs = MIN_INTERVAL_TIME;
76 id = swfdec_interval_new_object (player, msecs, repeat, object, name, argc - 3, &argv[3]);
78 SWFDEC_AS_VALUE_SET_INT (rval, id);
81 SWFDEC_AS_NATIVE (250, 0, swfdec_player_setInterval)
82 void
83 swfdec_player_setInterval (SwfdecAsContext *cx, SwfdecAsObject *obj,
84 guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
86 swfdec_player_do_set_interval (TRUE, cx, argc, argv, rval);
89 SWFDEC_AS_NATIVE (250, 2, swfdec_player_setTimeout)
90 void
91 swfdec_player_setTimeout (SwfdecAsContext *cx, SwfdecAsObject *obj,
92 guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
94 swfdec_player_do_set_interval (FALSE, cx, argc, argv, rval);
97 SWFDEC_AS_NATIVE (250, 1, swfdec_player_clearInterval)
98 void
99 swfdec_player_clearInterval (SwfdecAsContext *cx, SwfdecAsObject *obj,
100 guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
102 SwfdecPlayer *player = SWFDEC_PLAYER (cx);
103 guint id;
105 id = swfdec_as_value_to_integer (cx, &argv[0]);
106 swfdec_interval_remove (player, id);
109 /*** VARIOUS ***/
111 static SwfdecAsFunction *
112 swfdec_get_asnative (SwfdecAsContext *cx, guint x, guint y)
114 guint i;
116 for (i = 0; native_funcs[i].func != NULL; i++) {
117 if (native_funcs[i].x == x && native_funcs[i].y == y) {
118 SwfdecAsFunction *fun = swfdec_as_native_function_new (cx, native_funcs[i].name,
119 native_funcs[i].func, 0, NULL);
120 if (native_funcs[i].get_type) {
121 swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (fun),
122 native_funcs[i].get_type ());
124 return fun;
127 return NULL;
130 // same as ASnative, but also sets prototype
131 static void
132 swfdec_player_ASconstructor (SwfdecAsContext *cx, SwfdecAsObject *object,
133 guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
135 SwfdecAsValue val;
136 SwfdecAsObject *proto;
137 SwfdecAsFunction *func;
138 guint x, y;
140 SWFDEC_AS_CHECK (0, NULL, "ii", &x, &y);
142 func = swfdec_get_asnative (cx, x, y);
143 if (func) {
144 proto = swfdec_as_object_new (cx);
146 SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
147 swfdec_as_object_set_variable_and_flags (SWFDEC_AS_OBJECT (func),
148 SWFDEC_AS_STR_prototype, &val,
149 SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
151 SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (func));
152 swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR_constructor,
153 &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
155 SWFDEC_AS_VALUE_SET_OBJECT (rval, SWFDEC_AS_OBJECT (func));
156 } else {
157 SWFDEC_FIXME ("ASconstructor for %u %u missing", x, y);
161 static void
162 swfdec_player_ASnative (SwfdecAsContext *cx, SwfdecAsObject *object,
163 guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
165 SwfdecAsFunction *func;
166 guint x, y;
168 SWFDEC_AS_CHECK (0, NULL, "ii", &x, &y);
170 func = swfdec_get_asnative (cx, x, y);
171 if (func) {
172 SWFDEC_AS_VALUE_SET_OBJECT (rval, SWFDEC_AS_OBJECT (func));
173 } else {
174 SWFDEC_FIXME ("ASnative for %u %u missing", x, y);
178 SWFDEC_AS_NATIVE (4, 0, ASSetNative)
179 void
180 ASSetNative (SwfdecAsContext *cx, SwfdecAsObject *object,
181 guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
183 SwfdecAsFunction *function;
184 SwfdecAsObject *target;
185 SwfdecAsValue val;
186 SwfdecAsVariableFlag flags;
187 const char *s;
188 char **names;
189 guint i, x, y;
191 SWFDEC_AS_CHECK (0, NULL, "ois", &target, &x, &s);
193 if (argc > 3)
194 y = swfdec_as_value_to_integer (cx, &argv[3]);
195 else
196 y = 0;
197 names = g_strsplit (s, ",", -1);
198 for (i = 0; names[i]; i++) {
199 s = names[i];
200 flags = 0;
201 if (s[0] == '6') {
202 flags |= SWFDEC_AS_VARIABLE_VERSION_6_UP;
203 s++;
204 } else if (s[0] == '7') {
205 flags |= SWFDEC_AS_VARIABLE_VERSION_7_UP;
206 s++;
207 } else if (s[0] == '8') {
208 flags |= SWFDEC_AS_VARIABLE_VERSION_8_UP;
209 s++;
211 function = swfdec_get_asnative (cx, x, y);
212 if (function == NULL) {
213 SWFDEC_FIXME ("no ASnative function for %u, %u, what now?", x, y);
214 break;
216 SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (function));
217 swfdec_as_object_set_variable_and_flags (target,
218 swfdec_as_context_get_string (cx, s), &val, flags);
219 y++;
221 g_strfreev (names);
224 SWFDEC_AS_NATIVE (4, 1, ASSetNativeAccessor)
225 void
226 ASSetNativeAccessor (SwfdecAsContext *cx, SwfdecAsObject *object,
227 guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
229 SwfdecAsFunction *get, *set;
230 SwfdecAsObject *target;
231 const char *s;
232 char **names;
233 guint i, x, y;
235 if (argc < 3)
236 return;
238 target = swfdec_as_value_to_object (cx, &argv[0]);
239 x = swfdec_as_value_to_integer (cx, &argv[1]);
240 s = swfdec_as_value_to_string (cx, &argv[2]);
241 if (argc > 3)
242 y = swfdec_as_value_to_integer (cx, &argv[3]);
243 else
244 y = 0;
245 names = g_strsplit (s, ",", -1);
246 for (i = 0; names[i]; i++) {
247 s = names[i];
248 if (s[0] >= '0' && s[0] <= '9') {
249 SWFDEC_FIXME ("implement the weird numbers");
250 s++;
252 get = swfdec_get_asnative (cx, x, y++);
253 set = swfdec_get_asnative (cx, x, y++);
254 if (get == NULL) {
255 SWFDEC_ERROR ("no getter for %s", s);
256 break;
258 swfdec_as_object_add_variable (target, swfdec_as_context_get_string (cx, s),
259 get, set);
261 g_strfreev (names);
264 SWFDEC_AS_NATIVE (101, 8, swfdec_player_object_registerClass)
265 void
266 swfdec_player_object_registerClass (SwfdecAsContext *cx, SwfdecAsObject *object,
267 guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
269 const char *name;
271 name = swfdec_as_value_to_string (cx, &argv[0]);
272 if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[1])) {
273 SWFDEC_AS_VALUE_SET_BOOLEAN (rval, FALSE);
274 return;
277 swfdec_player_set_export_class (SWFDEC_PLAYER (cx), name,
278 SWFDEC_AS_VALUE_GET_OBJECT (&argv[1]));
279 SWFDEC_AS_VALUE_SET_BOOLEAN (rval, TRUE);
282 /* This is ran at the beginning of swfdec_as_context_startup.
283 * Yes, this is a hack */
284 void
285 swfdec_player_preinit_global (SwfdecAsContext *context, guint version)
287 /* init these two before swfdec_as_context_startup, so they won't get
288 * __proto__ and constructor properties */
289 swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_ASnative,
290 0, swfdec_player_ASnative, 2);
291 swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_ASconstructor,
292 0, swfdec_player_ASconstructor, 2);