📄 swfdec_player.c
字号:
{ SwfdecPlayerAction *action; SwfdecMovie *movie; movie = g_queue_peek_head (player->init_queue); if (movie) { swfdec_movie_run_init (movie); return TRUE; } movie = g_queue_peek_head (player->construct_queue); if (movie) { swfdec_movie_run_construct (movie); return TRUE; } do { action = swfdec_ring_buffer_pop (player->actions); if (action == NULL) return FALSE; } while (action->object == NULL); /* skip removed actions */ SWFDEC_LOG ("executing action %p %p %p", action->object, action->func, action->data); action->func (action->object, action->data); return TRUE;}static voidswfdec_player_perform_external_actions (SwfdecPlayer *player){ SwfdecPlayerAction *action; guint i; /* remove timeout if it exists - do this before executing stuff below */ if (player->external_timeout.callback) { swfdec_player_remove_timeout (player, &player->external_timeout); player->external_timeout.callback = NULL; } /* we need to query the number of current actions so newly added ones aren't * executed in here */ for (i = swfdec_ring_buffer_get_n_elements (player->external_actions); i > 0; i--) { action = swfdec_ring_buffer_pop (player->external_actions); g_assert (action != NULL); /* skip removed actions */ if (action->object == NULL) continue; action->func (action->object, action->data); } swfdec_player_perform_actions (player);}static voidswfdec_player_trigger_external_actions (SwfdecTimeout *advance){ SwfdecPlayer *player = SWFDEC_PLAYER ((guint8 *) advance - G_STRUCT_OFFSET (SwfdecPlayer, external_timeout)); player->external_timeout.callback = NULL; swfdec_player_perform_external_actions (player);}voidswfdec_player_add_external_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 external action %p %p %p", object, action_func, action_data); action = swfdec_ring_buffer_push (player->external_actions); if (action == NULL) { /* FIXME: limit number of actions to not get inf loops due to scripts? */ swfdec_ring_buffer_set_size (player->external_actions, swfdec_ring_buffer_get_size (player->external_actions) + 16); action = swfdec_ring_buffer_push (player->external_actions); g_assert (action); } action->object = object; action->func = action_func; action->data = action_data; if (!player->external_timeout.callback) { /* trigger execution immediately, but at least 100ms after the last external timeout */ player->external_timeout.timestamp = MAX (player->time + 1, player->external_timeout.timestamp + SWFDEC_MSECS_TO_TICKS (100)); player->external_timeout.callback = swfdec_player_trigger_external_actions; swfdec_player_add_timeout (player, &player->external_timeout); }}voidswfdec_player_remove_all_external_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->external_actions); i++) { action = swfdec_ring_buffer_peek_nth (player->external_actions, i); if (action->object == object) { SWFDEC_LOG ("removing external action %p %p %p", action->object, action->func, action->data); action->object = NULL; } }}/*** SwfdecPlayer ***/enum { INVALIDATE, ADVANCE, HANDLE_KEY, HANDLE_MOUSE, AUDIO_ADDED, AUDIO_REMOVED, LAUNCH, FSCOMMAND, LAST_SIGNAL};static guint signals[LAST_SIGNAL] = { 0, };enum { PROP_0, PROP_CACHE_SIZE, PROP_INITIALIZED, PROP_MOUSE_CURSOR, PROP_NEXT_EVENT, PROP_BACKGROUND_COLOR, PROP_WIDTH, PROP_HEIGHT, PROP_ALIGNMENT, PROP_SCALE};G_DEFINE_TYPE (SwfdecPlayer, swfdec_player, SWFDEC_TYPE_AS_CONTEXT)voidswfdec_player_remove_movie (SwfdecPlayer *player, SwfdecMovie *movie){ swfdec_movie_remove (movie); player->movies = g_list_remove (player->movies, movie);}static guintswfdec_player_alignment_to_flags (SwfdecAlignment alignment){ static const guint align_flags[9] = { SWFDEC_ALIGN_FLAG_TOP | SWFDEC_ALIGN_FLAG_LEFT, SWFDEC_ALIGN_FLAG_TOP, SWFDEC_ALIGN_FLAG_TOP | SWFDEC_ALIGN_FLAG_RIGHT, SWFDEC_ALIGN_FLAG_LEFT, 0, SWFDEC_ALIGN_FLAG_RIGHT, SWFDEC_ALIGN_FLAG_BOTTOM | SWFDEC_ALIGN_FLAG_LEFT, SWFDEC_ALIGN_FLAG_BOTTOM, SWFDEC_ALIGN_FLAG_BOTTOM | SWFDEC_ALIGN_FLAG_RIGHT }; return align_flags[alignment];}static SwfdecAlignmentswfdec_player_alignment_from_flags (guint flags){ if (flags & SWFDEC_ALIGN_FLAG_TOP) { if (flags & SWFDEC_ALIGN_FLAG_LEFT) { return SWFDEC_ALIGNMENT_TOP_LEFT; } else if (flags & SWFDEC_ALIGN_FLAG_RIGHT) { return SWFDEC_ALIGNMENT_TOP_RIGHT; } else { return SWFDEC_ALIGNMENT_TOP; } } else if (flags & SWFDEC_ALIGN_FLAG_BOTTOM) { if (flags & SWFDEC_ALIGN_FLAG_LEFT) { return SWFDEC_ALIGNMENT_BOTTOM_LEFT; } else if (flags & SWFDEC_ALIGN_FLAG_RIGHT) { return SWFDEC_ALIGNMENT_BOTTOM_RIGHT; } else { return SWFDEC_ALIGNMENT_BOTTOM; } } else { if (flags & SWFDEC_ALIGN_FLAG_LEFT) { return SWFDEC_ALIGNMENT_LEFT; } else if (flags & SWFDEC_ALIGN_FLAG_RIGHT) { return SWFDEC_ALIGNMENT_RIGHT; } else { return SWFDEC_ALIGNMENT_CENTER; } }}static voidswfdec_player_get_property (GObject *object, guint param_id, GValue *value, GParamSpec * pspec){ SwfdecPlayer *player = SWFDEC_PLAYER (object); switch (param_id) { case PROP_BACKGROUND_COLOR: g_value_set_uint (value, swfdec_player_get_background_color (player)); break; case PROP_CACHE_SIZE: g_value_set_uint (value, player->cache->max_size); break; case PROP_INITIALIZED: g_value_set_boolean (value, swfdec_player_is_initialized (player)); break; case PROP_MOUSE_CURSOR: g_value_set_enum (value, player->mouse_cursor); break; case PROP_NEXT_EVENT: g_value_set_uint (value, swfdec_player_get_next_event (player)); break; case PROP_WIDTH: g_value_set_int (value, player->stage_width); break; case PROP_HEIGHT: g_value_set_int (value, player->stage_height); break; case PROP_ALIGNMENT: g_value_set_enum (value, swfdec_player_alignment_from_flags (player->align_flags)); break; case PROP_SCALE: g_value_set_enum (value, player->scale_mode); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; }}static voidswfdec_player_update_scale (SwfdecPlayer *player){ int width, height; double scale_x, scale_y; width = player->stage_width >= 0 ? player->stage_width : (int) player->width; height = player->stage_height >= 0 ? player->stage_height : (int) player->height; if (height == 0 || width == 0) { player->scale_x = 1.0; player->scale_y = 1.0; player->offset_x = 0; player->offset_y = 0; return; } if (player->width == 0 || player->height == 0) { scale_x = 1.0; scale_y = 1.0; } else { scale_x = (double) width / player->width; scale_y = (double) height / player->height; } switch (player->scale_mode) { case SWFDEC_SCALE_SHOW_ALL: player->scale_x = MIN (scale_x, scale_y); player->scale_y = player->scale_x; break; case SWFDEC_SCALE_NO_BORDER: player->scale_x = MAX (scale_x, scale_y); player->scale_y = player->scale_x; break; case SWFDEC_SCALE_EXACT_FIT: player->scale_x = scale_x; player->scale_y = scale_y; break; case SWFDEC_SCALE_NONE: player->scale_x = 1.0; player->scale_y = 1.0; break; default: g_assert_not_reached (); } width = width - ceil (player->width * player->scale_x); height = height - ceil (player->height * player->scale_y); if (player->align_flags & SWFDEC_ALIGN_FLAG_LEFT) { player->offset_x = 0; } else if (player->align_flags & SWFDEC_ALIGN_FLAG_RIGHT) { player->offset_x = width; } else { player->offset_x = width / 2; } if (player->align_flags & SWFDEC_ALIGN_FLAG_TOP) { player->offset_y = 0; } else if (player->align_flags & SWFDEC_ALIGN_FLAG_BOTTOM) { player->offset_y = height; } else { player->offset_y = height / 2; } SWFDEC_LOG ("coordinate translation is %g * x + %d - %g * y + %d", player->scale_x, player->offset_x, player->scale_y, player->offset_y);#if 0 /* FIXME: make this emit the signal at the right time */ player->invalid.x0 = 0; player->invalid.y0 = 0; player->invalid.x1 = player->stage_width; player->invalid.y1 = player->stage_height;#endif}static voidswfdec_player_set_property (GObject *object, guint param_id, const GValue *value, GParamSpec *pspec){ SwfdecPlayer *player = SWFDEC_PLAYER (object); switch (param_id) { case PROP_BACKGROUND_COLOR: swfdec_player_set_background_color (player, g_value_get_uint (value)); break; case PROP_CACHE_SIZE: player->cache->max_size = g_value_get_uint (value); break; case PROP_WIDTH: swfdec_player_set_size (player, g_value_get_int (value), player->stage_height); break; case PROP_HEIGHT: swfdec_player_set_size (player, player->stage_width, g_value_get_int (value)); break; case PROP_ALIGNMENT: player->align_flags = swfdec_player_alignment_to_flags (g_value_get_enum (value)); swfdec_player_update_scale (player); break; case PROP_SCALE: swfdec_player_set_scale_mode (player, g_value_get_enum (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; }}static voidswfdec_player_dispose (GObject *object){ SwfdecPlayer *player = SWFDEC_PLAYER (object); swfdec_player_stop_all_sounds (player); g_hash_table_destroy (player->registered_classes); while (player->roots) swfdec_movie_destroy (player->roots->data); /* we do this here so references to GC'd objects get freed */ G_OBJECT_CLASS (swfdec_player_parent_class)->dispose (object); swfdec_player_remove_all_external_actions (player, player);#ifndef G_DISABLE_ASSERT { SwfdecPlayerAction *action; while ((action = swfdec_ring_buffer_pop (player->external_actions)) != NULL) { g_assert (action->object == NULL); /* skip removed actions */ } while ((action = swfdec_ring_buffer_pop (player->actions)) != NULL) { g_assert (action->object == NULL); /* skip removed actions */ } }#endif swfdec_ring_buffer_free (player->external_actions); swfdec_ring_buffer_free (player->actions); g_assert (player->movies == NULL); g_assert (player->audio == NULL); if (player->external_timeout.callback) swfdec_player_remove_timeout (player, &player->external_timeout); if (player->rate) { swfdec_player_remove_timeout (player, &player->iterate_timeout); } g_assert (player->timeouts == NULL); g_list_free (player->intervals); g_list_free (player->load_objects); player->intervals = NULL; g_assert (g_queue_is_empty (player->init_queue)); g_assert (g_queue_is_empty (player->construct_queue)); g_queue_free (player->init_queue); g_queue_free (player->construct_queue); swfdec_cache_unref (player->cache); if (player->loader) { g_object_unref (player->loader); player->loader = NULL; }}static voidswfdec_player_broadcast (SwfdecPlayer *player, const char *object_name, const char *signal){ SwfdecAsValue val; SwfdecAsObject *obj;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -