2 * Copyright (C) 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.
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
24 #include <libswfdec-gtk/swfdec-gtk.h>
25 #include "vivi_application.h"
26 #include "vivi_debugger.h"
27 #include "vivi_function.h"
28 #include "vivi_ming.h"
43 G_DEFINE_TYPE (ViviApplication
, vivi_application
, SWFDEC_TYPE_AS_CONTEXT
)
44 static guint signals
[LAST_SIGNAL
] = { 0, };
47 vivi_application_get_property (GObject
*object
, guint param_id
, GValue
*value
,
50 ViviApplication
*app
= VIVI_APPLICATION (object
);
54 g_value_set_string (value
, app
->filename
);
57 g_value_set_object (value
, app
->player
);
59 case PROP_INTERRUPTED
:
60 g_value_set_boolean (value
, app
->loop
!= NULL
);
63 g_value_set_boolean (value
, app
->playback_state
== VIVI_APPLICATION_EXITING
);
66 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
72 vivi_application_set_property (GObject
*object
, guint param_id
, const GValue
*value
,
75 ViviApplication
*app
= VIVI_APPLICATION (object
);
79 vivi_application_set_filename (app
, g_value_get_string (value
));
82 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
88 vivi_application_dispose (GObject
*object
)
90 ViviApplication
*app
= VIVI_APPLICATION (object
);
92 if (app
->playback_state
!= VIVI_APPLICATION_EXITING
)
93 vivi_application_quit (app
);
95 g_object_unref (app
->player
);
96 g_hash_table_destroy (app
->wraps
);
98 G_OBJECT_CLASS (vivi_application_parent_class
)->dispose (object
);
102 vivi_application_class_init (ViviApplicationClass
*klass
)
104 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
106 object_class
->dispose
= vivi_application_dispose
;
107 object_class
->get_property
= vivi_application_get_property
;
108 object_class
->set_property
= vivi_application_set_property
;
110 g_object_class_install_property (object_class
, PROP_FILENAME
,
111 g_param_spec_string ("filename", "filename", "name of file to play",
112 NULL
, G_PARAM_READWRITE
));
113 g_object_class_install_property (object_class
, PROP_PLAYER
,
114 g_param_spec_object ("player", "player", "Flash player in use",
115 SWFDEC_TYPE_PLAYER
, G_PARAM_READABLE
));
116 g_object_class_install_property (object_class
, PROP_INTERRUPTED
,
117 g_param_spec_boolean ("interrupted", "interrupted", "TRUE if handling a breakpoint",
118 FALSE
, G_PARAM_READABLE
));
119 g_object_class_install_property (object_class
, PROP_QUIT
,
120 g_param_spec_boolean ("quit", "quit", "TRUE if application has been quit (no breakpoints will happen)",
121 FALSE
, G_PARAM_READABLE
));
123 signals
[MESSAGE
] = g_signal_new ("message", G_TYPE_FROM_CLASS (klass
),
124 G_SIGNAL_RUN_LAST
, 0, NULL
, NULL
, g_cclosure_marshal_VOID__UINT_POINTER
, /* FIXME */
125 G_TYPE_NONE
, 2, G_TYPE_UINT
, G_TYPE_POINTER
);
129 vivi_application_init (ViviApplication
*app
)
131 app
->debugger
= g_object_new (VIVI_TYPE_DEBUGGER
, NULL
);
132 app
->debugger
->app
= app
;
133 app
->player
= swfdec_gtk_player_new (SWFDEC_AS_DEBUGGER (app
->debugger
));
135 app
->wraps
= g_hash_table_new (g_direct_hash
, g_direct_equal
);
139 vivi_application_new (void)
141 ViviApplication
*app
;
143 app
= g_object_new (VIVI_TYPE_APPLICATION
, NULL
);
144 swfdec_as_context_startup (SWFDEC_AS_CONTEXT (app
), 8);
145 vivi_function_init_context (app
);
150 vivi_application_init_player (ViviApplication
*app
)
152 SwfdecLoader
*loader
;
154 g_return_if_fail (VIVI_IS_APPLICATION (app
));
156 if (app
->player_inited
)
159 if (app
->filename
== NULL
) {
160 vivi_application_error (app
, "no file set to play.");
164 loader
= swfdec_file_loader_new (app
->filename
);
165 swfdec_player_set_loader (app
->player
, loader
);
166 app
->player_inited
= TRUE
;
170 vivi_application_reset (ViviApplication
*app
)
172 g_return_if_fail (VIVI_IS_APPLICATION (app
));
174 g_assert (app
->loop
== NULL
); /* FIXME: what do we do if we're inside a breakpoint? */
175 g_object_unref (app
->player
);
176 app
->player
= swfdec_gtk_player_new (SWFDEC_AS_DEBUGGER (app
->debugger
));
177 app
->player_inited
= FALSE
;
178 g_object_notify (G_OBJECT (app
), "player");
182 vivi_application_set_filename (ViviApplication
*app
, const char *filename
)
184 g_return_if_fail (VIVI_IS_APPLICATION (app
));
185 g_return_if_fail (filename
!= NULL
);
187 g_free (app
->filename
);
188 app
->filename
= g_strdup (filename
);
189 vivi_application_reset (app
);
190 g_object_notify (G_OBJECT (app
), "filename");
194 vivi_application_get_filename (ViviApplication
*app
)
196 g_return_val_if_fail (VIVI_IS_APPLICATION (app
), NULL
);
198 return app
->filename
;
202 vivi_application_get_player (ViviApplication
*app
)
204 g_return_val_if_fail (VIVI_IS_APPLICATION (app
), NULL
);
210 vivi_application_get_interrupted (ViviApplication
*app
)
212 g_return_val_if_fail (VIVI_IS_APPLICATION (app
), FALSE
);
214 return app
->loop
!= NULL
;
218 vivi_application_is_quit (ViviApplication
*app
)
220 g_return_val_if_fail (VIVI_IS_APPLICATION (app
), FALSE
);
222 return app
->playback_state
== VIVI_APPLICATION_EXITING
;
226 vivi_application_step_forward (gpointer appp
)
228 ViviApplication
*app
= appp
;
231 next_event
= swfdec_player_get_next_event (app
->player
);
232 swfdec_player_advance (app
->player
, next_event
);
238 vivi_application_check (ViviApplication
*app
)
240 gboolean is_playing
, is_breakpoint
;
242 /* if we're inside some script code, don't do anything */
243 if (swfdec_as_context_get_frame (SWFDEC_AS_CONTEXT (app
)))
246 is_playing
= swfdec_gtk_player_get_playing (SWFDEC_GTK_PLAYER (app
->player
));
247 is_breakpoint
= app
->loop
!= NULL
;
248 swfdec_as_context_maybe_gc (SWFDEC_AS_CONTEXT (app
));
250 switch (app
->playback_state
) {
251 case VIVI_APPLICATION_EXITING
:
253 swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app
->player
), FALSE
);
255 g_main_loop_quit (app
->loop
);
257 case VIVI_APPLICATION_STOPPED
:
259 swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app
->player
), FALSE
);
261 case VIVI_APPLICATION_PLAYING
:
263 swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app
->player
), TRUE
);
265 g_main_loop_quit (app
->loop
);
267 case VIVI_APPLICATION_STEPPING
:
269 swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app
->player
), FALSE
);
271 g_main_loop_quit (app
->loop
);
273 /* FIXME: sanely handle this */
274 g_idle_add_full (-100, vivi_application_step_forward
, app
, NULL
);
278 g_assert_not_reached ();
284 vivi_application_execute (ViviApplication
*app
, const char *command
)
287 SwfdecAsObject
*object
;
288 SwfdecScript
*script
;
291 g_return_if_fail (VIVI_IS_APPLICATION (app
));
292 g_return_if_fail (command
!= NULL
);
294 vivi_application_input (app
, command
);
295 script
= vivi_ming_compile (command
, &error
);
296 if (script
== NULL
) {
297 vivi_application_error (app
, error
);
301 object
= SWFDEC_AS_CONTEXT (app
)->global
;
302 swfdec_as_object_get_variable (object
,
303 swfdec_as_context_get_string (SWFDEC_AS_CONTEXT (app
), "Commands"),
305 if (SWFDEC_AS_VALUE_IS_OBJECT (&val
))
306 object
= SWFDEC_AS_VALUE_GET_OBJECT (&val
);
307 swfdec_as_object_run (object
, script
);
308 swfdec_script_unref (script
);
309 vivi_application_check (app
);
313 vivi_application_send_message (ViviApplication
*app
,
314 ViviMessageType type
, const char *format
, ...)
319 g_return_if_fail (VIVI_IS_APPLICATION (app
));
320 g_return_if_fail (format
!= NULL
);
322 va_start (args
, format
);
323 msg
= g_strdup_vprintf (format
, args
);
325 g_signal_emit (app
, signals
[MESSAGE
], 0, (guint
) type
, msg
);
330 vivi_application_play (ViviApplication
*app
)
332 g_return_if_fail (VIVI_IS_APPLICATION (app
));
334 if (app
->playback_state
== VIVI_APPLICATION_EXITING
)
336 app
->playback_state
= VIVI_APPLICATION_PLAYING
;
337 app
->playback_count
= 1;
338 vivi_application_check (app
);
342 vivi_application_stop (ViviApplication
*app
)
344 g_return_if_fail (VIVI_IS_APPLICATION (app
));
346 if (app
->playback_state
== VIVI_APPLICATION_EXITING
)
348 app
->playback_state
= VIVI_APPLICATION_STOPPED
;
349 app
->playback_count
= 0;
350 vivi_application_check (app
);
354 vivi_application_step (ViviApplication
*app
, guint n_times
)
356 g_return_if_fail (VIVI_IS_APPLICATION (app
));
358 if (app
->playback_state
== VIVI_APPLICATION_EXITING
)
360 app
->playback_state
= VIVI_APPLICATION_STEPPING
;
361 app
->playback_count
= n_times
;
362 vivi_application_check (app
);
366 vivi_application_quit (ViviApplication
*app
)
368 g_return_if_fail (VIVI_IS_APPLICATION (app
));
370 if (app
->playback_state
== VIVI_APPLICATION_EXITING
)
372 app
->playback_state
= VIVI_APPLICATION_EXITING
;
373 app
->playback_count
= 1;
374 g_object_notify (G_OBJECT (app
), "quit");
375 vivi_application_check (app
);