add test for frames and bytes properties of empty movies
[swfdec.git] / test / trace / swfdec_interaction.c
blobcb940b9718fe6f54f1ce493d4e5e5b878a0c8dff
1 /* Swfdec
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.
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 #include "swfdec_interaction.h"
26 static const GScannerConfig scanner_config = {
27 (char *) ",; \t\n",
28 (char *) G_CSET_a_2_z G_CSET_A_2_Z,
29 (char *) G_CSET_a_2_z G_CSET_A_2_Z,
30 (char *) "#\n",
31 FALSE,
32 FALSE, TRUE, FALSE, TRUE, TRUE, FALSE,
33 TRUE, FALSE, FALSE, FALSE, FALSE, FALSE,
34 TRUE, TRUE, TRUE, FALSE, FALSE,
35 FALSE, TRUE, FALSE, FALSE,
39 void
40 swfdec_interaction_free (SwfdecInteraction *inter)
42 g_return_if_fail (inter != NULL);
44 g_array_free (inter->commands, TRUE);
45 g_free (inter);
48 void
49 swfdec_interaction_reset (SwfdecInteraction *inter)
51 g_return_if_fail (inter != NULL);
53 inter->mouse_x = 0;
54 inter->mouse_y = 0;
55 inter->mouse_button = 0;
56 inter->cur_idx = 0;
57 inter->time_elapsed = 0;
60 static void
61 swfdec_interaction_scanner_message (GScanner *scanner, gchar *message, gboolean error)
63 if (!error)
64 g_printerr ("warning: %s\n", message);
65 g_set_error (scanner->user_data, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s", message);
68 static void
69 swfdec_command_append_mouse (SwfdecInteraction *inter, SwfdecCommandType type, int x, int y, int button)
71 SwfdecCommand command;
73 command.command = type;
74 command.args.mouse.x = x;
75 command.args.mouse.y = y;
76 command.args.mouse.button = button;
77 inter->mouse_x = x;
78 inter->mouse_y = y;
79 inter->mouse_button = button;
80 g_array_append_val (inter->commands, command);
83 static void
84 swfdec_command_append_key (SwfdecInteraction *inter, SwfdecKey code, guint ascii, SwfdecCommandType type)
86 SwfdecCommand command;
88 command.command = type;
89 command.args.key.code = code;
90 command.args.key.ascii = ascii;
91 g_array_append_val (inter->commands, command);
94 static void
95 swfdec_command_append_wait (SwfdecInteraction *inter, int msecs)
97 SwfdecCommand command;
99 command.command = SWFDEC_COMMAND_WAIT;
100 command.args.time = msecs;
101 g_array_append_val (inter->commands, command);
104 SwfdecInteraction *
105 swfdec_interaction_new (const char *data, guint length, GError **error)
107 GScanner *scanner;
108 GTokenType token;
109 SwfdecInteraction *inter;
110 int i, j;
112 g_return_val_if_fail (data != NULL || length == 0, NULL);
114 /* setup scanner */
115 scanner = g_scanner_new (&scanner_config);
116 scanner->user_data = error;
117 scanner->msg_handler = swfdec_interaction_scanner_message;
118 g_scanner_scope_add_symbol (scanner, 0, "wait", GINT_TO_POINTER (SWFDEC_COMMAND_WAIT));
119 g_scanner_scope_add_symbol (scanner, 0, "move", GINT_TO_POINTER (SWFDEC_COMMAND_MOVE));
120 g_scanner_scope_add_symbol (scanner, 0, "down", GINT_TO_POINTER (SWFDEC_COMMAND_DOWN));
121 g_scanner_scope_add_symbol (scanner, 0, "up", GINT_TO_POINTER (SWFDEC_COMMAND_UP));
122 g_scanner_scope_add_symbol (scanner, 0, "press", GINT_TO_POINTER (SWFDEC_COMMAND_PRESS));
123 g_scanner_scope_add_symbol (scanner, 0, "release", GINT_TO_POINTER (SWFDEC_COMMAND_RELEASE));
124 g_scanner_input_text (scanner, data, length);
126 /* setup inter */
127 inter = g_new0 (SwfdecInteraction, 1);
128 inter->commands = g_array_new (FALSE, FALSE, sizeof (SwfdecCommand));
130 while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF) {
131 switch ((SwfdecCommandType)token) {
132 case SWFDEC_COMMAND_WAIT:
133 token = g_scanner_get_next_token (scanner);
134 if (token != G_TOKEN_INT) {
135 g_scanner_unexp_token (scanner, G_TOKEN_INT, NULL, NULL, NULL, NULL, TRUE);
136 goto error;
138 i = scanner->value.v_int;
139 swfdec_command_append_wait (inter, i);
140 break;
141 case SWFDEC_COMMAND_MOVE:
142 token = g_scanner_get_next_token (scanner);
143 if (token != G_TOKEN_INT) {
144 g_scanner_unexp_token (scanner, G_TOKEN_INT, NULL, NULL, NULL, NULL, TRUE);
145 goto error;
147 i = scanner->value.v_int;
148 token = g_scanner_get_next_token (scanner);
149 if (token != G_TOKEN_INT) {
150 g_scanner_unexp_token (scanner, G_TOKEN_INT, NULL, NULL, NULL, NULL, TRUE);
151 goto error;
153 j = scanner->value.v_int;
154 swfdec_command_append_mouse (inter, SWFDEC_COMMAND_MOVE, i, j, inter->mouse_button);
155 break;
156 case SWFDEC_COMMAND_DOWN:
157 swfdec_command_append_mouse (inter, SWFDEC_COMMAND_DOWN, inter->mouse_x, inter->mouse_y, 1);
158 break;
159 case SWFDEC_COMMAND_UP:
160 swfdec_command_append_mouse (inter, SWFDEC_COMMAND_UP, inter->mouse_x, inter->mouse_y, 1);
161 break;
162 case SWFDEC_COMMAND_PRESS:
163 case SWFDEC_COMMAND_RELEASE:
164 j = token;
165 token = g_scanner_get_next_token (scanner);
166 if (token != G_TOKEN_INT) {
167 g_scanner_unexp_token (scanner, G_TOKEN_INT, NULL, NULL, NULL, NULL, TRUE);
168 goto error;
170 i = scanner->value.v_int;
171 if (i >= 256) {
172 g_scanner_unexp_token (scanner, G_TOKEN_INT, NULL, NULL, NULL, NULL, TRUE);
173 goto error;
175 /* FIXME: allow string here and convert first char */
176 token = g_scanner_get_next_token (scanner);
177 if (token != G_TOKEN_INT) {
178 g_scanner_unexp_token (scanner, G_TOKEN_INT, NULL, NULL, NULL, NULL, TRUE);
179 goto error;
181 swfdec_command_append_key (inter, i, scanner->value.v_int, j);
182 break;
183 default:
184 g_scanner_unexp_token (scanner, SWFDEC_COMMAND_WAIT, NULL, NULL, NULL, NULL, TRUE);
185 goto error;
188 swfdec_interaction_reset (inter);
189 g_scanner_destroy (scanner);
190 return inter;
192 error:
193 swfdec_interaction_free (inter);
194 g_scanner_destroy (scanner);
195 return NULL;
198 SwfdecInteraction *
199 swfdec_interaction_new_from_file (const char *filename, GError **error)
201 char *contents;
202 gsize length;
203 SwfdecInteraction *ret;
205 g_return_val_if_fail (filename != NULL, NULL);
207 if (!g_file_get_contents (filename, &contents, &length, error))
208 return NULL;
210 ret = swfdec_interaction_new (contents, length, error);
211 g_free (contents);
212 return ret;
215 /* returns time until next event in msecs or -1 if none */
217 swfdec_interaction_get_next_event (SwfdecInteraction *inter)
219 SwfdecCommand *command;
221 g_return_val_if_fail (inter != NULL, -1);
223 if (inter->cur_idx >= inter->commands->len)
224 return -1;
225 command = &g_array_index (inter->commands, SwfdecCommand, inter->cur_idx);
226 if (command->command != SWFDEC_COMMAND_WAIT)
227 return 0;
228 g_assert (command->args.time > inter->time_elapsed);
229 return command->args.time - inter->time_elapsed;
232 void
233 swfdec_interaction_advance (SwfdecInteraction *inter, SwfdecPlayer *player, guint msecs)
235 SwfdecCommand *command;
237 g_return_if_fail (inter != NULL);
239 inter->time_elapsed += msecs;
240 while (inter->cur_idx < inter->commands->len) {
241 command = &g_array_index (inter->commands, SwfdecCommand, inter->cur_idx);
242 switch (command->command) {
243 case SWFDEC_COMMAND_WAIT:
244 if (inter->time_elapsed < command->args.time)
245 return;
246 inter->time_elapsed -= command->args.time;
247 break;
248 case SWFDEC_COMMAND_MOVE:
249 swfdec_player_mouse_move (player, command->args.mouse.x,
250 command->args.mouse.y);
251 break;
252 case SWFDEC_COMMAND_PRESS:
253 swfdec_player_key_press (player, command->args.key.code, command->args.key.ascii);
254 break;
255 case SWFDEC_COMMAND_RELEASE:
256 swfdec_player_key_release (player, command->args.key.code, command->args.key.ascii);
257 break;
258 case SWFDEC_COMMAND_DOWN:
259 swfdec_player_mouse_press (player, command->args.mouse.x,
260 command->args.mouse.y, command->args.mouse.button);
261 break;
262 case SWFDEC_COMMAND_UP:
263 swfdec_player_mouse_release (player, command->args.mouse.x,
264 command->args.mouse.y, command->args.mouse.button);
265 break;
266 default:
267 g_assert_not_reached ();
268 return;
270 inter->cur_idx++;
274 guint
275 swfdec_interaction_get_duration (SwfdecInteraction *inter)
277 guint i, duration;
279 g_return_val_if_fail (inter != NULL, 0);
281 duration = 0;
282 for (i = 0; i < inter->commands->len; i++) {
283 SwfdecCommand *command = &g_array_index (inter->commands, SwfdecCommand, i);
284 if (command->command == SWFDEC_COMMAND_WAIT)
285 duration += command->args.time;
287 return duration;