📄 swfdec_player.c
字号:
/* Swfdec * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <math.h>#include <string.h>#include <stdlib.h>#include <liboil/liboil.h>#include "swfdec_player_internal.h"#include "swfdec_as_internal.h"#include "swfdec_as_strings.h"#include "swfdec_audio_internal.h"#include "swfdec_button_movie.h" /* for mouse cursor */#include "swfdec_cache.h"#include "swfdec_debug.h"#include "swfdec_enums.h"#include "swfdec_event.h"#include "swfdec_initialize.h"#include "swfdec_internal.h"#include "swfdec_loader_internal.h"#include "swfdec_marshal.h"#include "swfdec_movie.h"#include "swfdec_script_internal.h"#include "swfdec_sprite_movie.h"#include "swfdec_swf_instance.h"/*** gtk-doc ***//** * SECTION:SwfdecPlayer * @title: SwfdecPlayer * @short_description: main playback object * * A #SwfdecPlayer is the main object used for playing back Flash files through * Swfdec. * * A player interacts with the outside world in a multitude of ways. The most * important ones are described below. * * Input is handled via the * <link linkend="swfdec-SwfdecLoader">SwfdecLoader</link> class. A * #SwfdecLoader is set on a new player using swfdec_player_set_loader(). * * When the loader has provided enough data, you can start playing the file. * This is done in steps by calling swfdec_player_advance() - preferrably as * often as swfdec_player_get_next_event() indicates. Or you can provide user input * to the player by calling for example swfdec_player_handle_mouse(). * * You can use swfdec_player_render() to draw the current state of the player. * After that, connect to the SwfdecPlayer::invalidate signal to be notified of * changes. * * Audio output is handled via the * <link linkend="swfdec-SwfdecAudio">SwfdecAudio</link> class. One * #SwfdecAudio object is created for every output using the * SwfdecPlayer::audio-added signal. *//** * SwfdecPlayer: * * This is the base object used for playing Flash files. *//** * SECTION:Enumerations * @title: Enumerations * @short_description: enumerations used in Swfdec * * This file lists all of the enumerations used in various parts of Swfdec. *//** * SwfdecMouseCursor: * @SWFDEC_MOUSE_CURSOR_NORMAL: a normal mouse cursor * @SWFDEC_MOUSE_CURSOR_NONE: no mouse image * @SWFDEC_MOUSE_CURSOR_TEXT: a mouse cursor suitable for text editing * @SWFDEC_MOUSE_CURSOR_CLICK: a mouse cursor for clicking a hyperlink or a * button * * This enumeration describes the possible types for the SwfdecPlayer::mouse-cursor * property. *//** * SwfdecAlignment: * @SWFDEC_ALIGNMENT_TOP_LEFT: top left * @SWFDEC_ALIGNMENT_TOP: top * @SWFDEC_ALIGNMENT_TOP_RIGHT: top right * @SWFDEC_ALIGNMENT_LEFT: left * @SWFDEC_ALIGNMENT_CENTER: center * @SWFDEC_ALIGNMENT_RIGHT: right * @SWFDEC_ALIGNMENT_BOTTOM_LEFT: left * @SWFDEC_ALIGNMENT_BOTTOM: bottom * @SWFDEC_ALIGNMENT_BOTTOM_RIGHT: bottom right * * These are the possible values for the alignment of an unscaled movie. *//** * SwfdecScaleMode: * @SWFDEC_SCALE_SHOW_ALL: Show the whole content as large as possible * @SWFDEC_SCALE_NO_BORDER: Fill the whole area, possibly cropping parts * @SWFDEC_SCALE_EXACT_FIT: Fill the whole area, don't keep aspect ratio * @SWFDEC_SCALE_NONE: Do not scale the movie at all * * Describes how the movie should be scaled if the given size doesn't equal the * movie's size. *//** * SwfdecKey: * @SWFDEC_KEY_BACKSPACE: the backspace key * @SWFDEC_KEY_TAB: the tab key * @SWFDEC_KEY_CLEAR: the clear key * @SWFDEC_KEY_ENTER: the enter key * @SWFDEC_KEY_SHIFT: the shift key * @SWFDEC_KEY_CONTROL: the control key * @SWFDEC_KEY_ALT: the alt key * @SWFDEC_KEY_CAPS_LOCK: the caps lock key * @SWFDEC_KEY_ESCAPE: the escape key * @SWFDEC_KEY_SPACE: the space key * @SWFDEC_KEY_PAGE_UP: the page up key * @SWFDEC_KEY_PAGE_DOWN: the page down key * @SWFDEC_KEY_END: the end key * @SWFDEC_KEY_HOME: the home key * @SWFDEC_KEY_LEFT: the left key * @SWFDEC_KEY_UP: the up key * @SWFDEC_KEY_RIGHT: the right key * @SWFDEC_KEY_DOWN: the down key * @SWFDEC_KEY_INSERT: the insert key * @SWFDEC_KEY_DELETE: the delete key * @SWFDEC_KEY_HELP: the help key * @SWFDEC_KEY_0: the 0 key * @SWFDEC_KEY_1: the 1 key * @SWFDEC_KEY_2: the 2 key * @SWFDEC_KEY_3: the 3 key * @SWFDEC_KEY_4: the 4 key * @SWFDEC_KEY_5: the 5 key * @SWFDEC_KEY_6: the 6 key * @SWFDEC_KEY_7: the 7 key * @SWFDEC_KEY_8: the 8 key * @SWFDEC_KEY_9: the 9 key * @SWFDEC_KEY_A: the ! key * @SWFDEC_KEY_B: the B key * @SWFDEC_KEY_C: the C key * @SWFDEC_KEY_D: the D key * @SWFDEC_KEY_E: the E key * @SWFDEC_KEY_F: the F key * @SWFDEC_KEY_G: the G key * @SWFDEC_KEY_H: the H key * @SWFDEC_KEY_I: the I key * @SWFDEC_KEY_J: the J key * @SWFDEC_KEY_K: the K key * @SWFDEC_KEY_L: the L key * @SWFDEC_KEY_M: the M key * @SWFDEC_KEY_N: the N key * @SWFDEC_KEY_O: the O key * @SWFDEC_KEY_P: the P key * @SWFDEC_KEY_Q: the Q key * @SWFDEC_KEY_R: the R key * @SWFDEC_KEY_S: the S key * @SWFDEC_KEY_T: the T key * @SWFDEC_KEY_U: the U key * @SWFDEC_KEY_V: the V key * @SWFDEC_KEY_W: the W key * @SWFDEC_KEY_X: the X key * @SWFDEC_KEY_Y: the Y key * @SWFDEC_KEY_Z: the Z key * @SWFDEC_KEY_NUMPAD_0: the 0 key on the numeric keypad * @SWFDEC_KEY_NUMPAD_1: the 1 key on the numeric keypad * @SWFDEC_KEY_NUMPAD_2: the 2 key on the numeric keypad * @SWFDEC_KEY_NUMPAD_3: the 3 key on the numeric keypad * @SWFDEC_KEY_NUMPAD_4: the 4 key on the numeric keypad * @SWFDEC_KEY_NUMPAD_5: the 5 key on the numeric keypad * @SWFDEC_KEY_NUMPAD_6: the 6 key on the numeric keypad * @SWFDEC_KEY_NUMPAD_7: the 7 key on the numeric keypad * @SWFDEC_KEY_NUMPAD_8: the 8 key on the numeric keypad * @SWFDEC_KEY_NUMPAD_9: the 9 key on the numeric keypad * @SWFDEC_KEY_NUMPAD_MULTIPLY: the multiply key on the numeric keypad * @SWFDEC_KEY_NUMPAD_ADD: the add key on the numeric keypad * @SWFDEC_KEY_NUMPAD_SUBTRACT: the subtract key on the numeric keypad * @SWFDEC_KEY_NUMPAD_DECIMAL: the decimal key on the numeric keypad * @SWFDEC_KEY_NUMPAD_DIVIDE: the divide key on the numeric keypad * @SWFDEC_KEY_F1: the F1 key * @SWFDEC_KEY_F2: the F2 key * @SWFDEC_KEY_F3: the F3 key * @SWFDEC_KEY_F4: the F4 key * @SWFDEC_KEY_F5: the F5 key * @SWFDEC_KEY_F6: the F6 key * @SWFDEC_KEY_F7: the F7 key * @SWFDEC_KEY_F8: the F8 key * @SWFDEC_KEY_F9: the F9 key * @SWFDEC_KEY_F10: the F10 key * @SWFDEC_KEY_F11: the F11 key * @SWFDEC_KEY_F12: the F12 key * @SWFDEC_KEY_F13: the F13 key * @SWFDEC_KEY_F14: the F14 key * @SWFDEC_KEY_F15: the F15 key * @SWFDEC_KEY_NUM_LOCK: the num lock key * @SWFDEC_KEY_SEMICOLON: the semicolon key (on English keyboards) * @SWFDEC_KEY_EQUAL: the equal key (on English keyboards) * @SWFDEC_KEY_MINUS: the minus key (on English keyboards) * @SWFDEC_KEY_SLASH: the slash key (on English keyboards) * @SWFDEC_KEY_GRAVE: the grave key (on English keyboards) * @SWFDEC_KEY_LEFT_BRACKET: the left bracket key (on English keyboards) * @SWFDEC_KEY_BACKSLASH: the backslash key (on English keyboards) * @SWFDEC_KEY_RIGHT_BRACKET: the right bracket key (on English keyboards) * @SWFDEC_KEY_APOSTROPHE: the apostrophe key (on English keyboards) * * Lists all known key codes in Swfdec and their meanings on an English * keyboard. *//*** Timeouts ***/static SwfdecTickswfdec_player_get_next_event_time (SwfdecPlayer *player){ if (player->timeouts) { return ((SwfdecTimeout *) player->timeouts->data)->timestamp - player->time; } else { return 0; }}/** * swfdec_player_add_timeout: * @player: a #SwfdecPlayer * @timeout: timeout to add * * Adds a timeout to @player. The timeout will be removed automatically when * triggered, so you need to use swfdec_player_add_timeout() to add it again. * The #SwfdecTimeout struct and callback does not use a data callback pointer. * It's suggested that you use the struct as part of your own bigger struct * and get it back like this: * <programlisting> * typedef struct { * // ... * SwfdecTimeout timeout; * } MyStruct; * * static void * my_struct_timeout_callback (SwfdecTimeout *timeout) * { * MyStruct *mystruct = (MyStruct *) ((void *) timeout - G_STRUCT_OFFSET (MyStruct, timeout)); * * // do stuff * } * </programlisting> **/voidswfdec_player_add_timeout (SwfdecPlayer *player, SwfdecTimeout *timeout){ GList *walk; SwfdecTick next_tick; g_return_if_fail (SWFDEC_IS_PLAYER (player)); g_return_if_fail (timeout != NULL); g_return_if_fail (timeout->timestamp > player->time); g_return_if_fail (timeout->callback != NULL); SWFDEC_LOG ("adding timeout %p in %"G_GUINT64_FORMAT" msecs", timeout, SWFDEC_TICKS_TO_MSECS (timeout->timestamp - player->time)); next_tick = swfdec_player_get_next_event_time (player); /* the order is important, on events with the same time, we make sure the new one is last */ for (walk = player->timeouts; walk; walk = walk->next) { SwfdecTimeout *cur = walk->data; if (cur->timestamp > timeout->timestamp) break; } player->timeouts = g_list_insert_before (player->timeouts, walk, timeout); if (next_tick != swfdec_player_get_next_event_time (player)) g_object_notify (G_OBJECT (player), "next-event");}/** * swfdec_player_remove_timeout: * @player: a #SwfdecPlayer * @timeout: a timeout that should be removed * * Removes the @timeout from the list of scheduled timeouts. The timeout must * have been added with swfdec_player_add_timeout() before. **/voidswfdec_player_remove_timeout (SwfdecPlayer *player, SwfdecTimeout *timeout){ SwfdecTick next_tick; g_return_if_fail (SWFDEC_IS_PLAYER (player)); g_return_if_fail (timeout != NULL); g_return_if_fail (timeout->timestamp >= player->time); g_return_if_fail (timeout->callback != NULL); SWFDEC_LOG ("removing timeout %p", timeout); next_tick = swfdec_player_get_next_event_time (player); player->timeouts = g_list_remove (player->timeouts, timeout); if (next_tick != swfdec_player_get_next_event_time (player)) g_object_notify (G_OBJECT (player), "next-event");}/*** Actions ***/typedef struct { gpointer object; SwfdecActionFunc func; gpointer data;} SwfdecPlayerAction;/** * swfdec_player_add_action: * @player: a #SwfdecPlayer * @object: object identifying the action * @action_func: function to execute * @action_data: additional data to pass to @func * * Adds an action to the @player. Actions are used by Flash player to solve * reentrancy issues. Instead of calling back into the Actionscript engine, * an action is queued for later execution. So if you're writing code that * is calling Actionscript code, you want to do this by using actions. **/voidswfdec_player_add_action (SwfdecPlayer *player, gpointer object, SwfdecActionFunc action_func, gpointer action_data){ SwfdecPlayerAction *action; g_return_if_fail (SWFDEC_IS_PLAYER (player)); g_return_if_fail (object != NULL); g_return_if_fail (action_func != NULL); SWFDEC_LOG ("adding action %p %p %p", object, action_func, action_data); action = swfdec_ring_buffer_push (player->actions); if (action == NULL) { /* FIXME: limit number of actions to not get inf loops due to scripts? */ swfdec_ring_buffer_set_size (player->actions, swfdec_ring_buffer_get_size (player->actions) + 16); action = swfdec_ring_buffer_push (player->actions); g_assert (action); } action->object = object; action->func = action_func; action->data = action_data;}/** * swfdec_player_remove_all_actions: * @player: a #SwfdecPlayer * @object: object pointer identifying the actions to be removed * * Removes all actions associated with @object. See swfdec_player_add_action() * for details about actions. **/voidswfdec_player_remove_all_actions (SwfdecPlayer *player, gpointer object){ SwfdecPlayerAction *action; guint i; g_return_if_fail (SWFDEC_IS_PLAYER (player)); g_return_if_fail (object != NULL); for (i = 0; i < swfdec_ring_buffer_get_n_elements (player->actions); i++) { action = swfdec_ring_buffer_peek_nth (player->actions, i); if (action->object == object) { SWFDEC_LOG ("removing action %p %p %p", action->object, action->func, action->data); action->object = NULL; } }}static gbooleanswfdec_player_do_action (SwfdecPlayer *player)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -