⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swfdec_player.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* FIXME: need to do anything with old drag? */  player->mouse_drag = drag;  player->mouse_drag_center = center;  if (rect) {    player->mouse_drag_rect = *rect;  } else {    player->mouse_drag_rect.x0 = -G_MAXDOUBLE;    player->mouse_drag_rect.y0 = -G_MAXDOUBLE;    player->mouse_drag_rect.x1 = G_MAXDOUBLE;    player->mouse_drag_rect.y1 = G_MAXDOUBLE;  }  SWFDEC_DEBUG ("starting drag in %g %g  %g %g",       player->mouse_drag_rect.x0, player->mouse_drag_rect.y0,      player->mouse_drag_rect.x1, player->mouse_drag_rect.y1);  /* FIXME: need a way to make sure we get updated */  if (drag) {    swfdec_movie_update (drag);    swfdec_player_update_drag_movie (player);  }}static voidswfdec_player_update_mouse_position (SwfdecPlayer *player){  GList *walk;  SwfdecMovie *mouse_grab = NULL;  if (player->mouse_button) {    mouse_grab = player->mouse_grab;  } else {    /* if the mouse button is pressed the grab widget stays the same (I think) */    for (walk = g_list_last (player->roots); walk; walk = walk->prev) {      mouse_grab = swfdec_movie_get_movie_at (walk->data, player->mouse_x, player->mouse_y);      if (mouse_grab)	break;    }  }  SWFDEC_DEBUG ("%s %p has mouse at %g %g",       mouse_grab ? G_OBJECT_TYPE_NAME (mouse_grab) : "---",       mouse_grab, player->mouse_x, player->mouse_y);  if (player->mouse_grab && mouse_grab != player->mouse_grab)    swfdec_movie_send_mouse_change (player->mouse_grab, TRUE);  player->mouse_grab = mouse_grab;  if (mouse_grab)    swfdec_movie_send_mouse_change (mouse_grab, FALSE);}static voidswfdec_player_do_mouse_move (SwfdecPlayer *player){  GList *walk;  swfdec_player_update_drag_movie (player);  for (walk = player->movies; walk; walk = walk->next) {    swfdec_movie_queue_script (walk->data, SWFDEC_EVENT_MOUSE_MOVE);  }  swfdec_listener_execute (player->mouse_listener, "onMouseMove");  swfdec_player_update_mouse_position (player);}static voidswfdec_player_do_mouse_button (SwfdecPlayer *player){  GList *walk;  guint event;  const char *event_name;  if (player->mouse_button) {    event = SWFDEC_EVENT_MOUSE_DOWN;    event_name = "onMouseDown";  } else {    event = SWFDEC_EVENT_MOUSE_UP;    event_name = "onMouseUp";  }  for (walk = player->movies; walk; walk = walk->next) {    swfdec_movie_queue_script (walk->data, event);  }  swfdec_listener_execute (player->mouse_listener, event_name);  if (player->mouse_grab)    swfdec_movie_send_mouse_change (player->mouse_grab, FALSE);}static voidswfdec_player_emit_signals (SwfdecPlayer *player){  GList *walk;  /* emit invalidate signal */  if (!swfdec_rect_is_empty (&player->invalid)) {    double x, y, width, height;    /* FIXME: currently we clamp the rectangle to the visible area, it might     * be useful to allow out-of-bounds drawing. In that case this needs to be     * changed */    x = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x0);    x = MAX (x, 0.0);    y = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y0);    y = MAX (y, 0.0);    width = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x1 - player->invalid.x0);    width = MIN (width, player->width - x);    height = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y1 - player->invalid.y0);    height = MIN (height, player->height - y);    g_signal_emit (player, signals[INVALIDATE], 0, x, y, width, height);    swfdec_rect_init_empty (&player->invalid);  }  /* emit audio-added for all added audio streams */  for (walk = player->audio; walk; walk = walk->next) {    SwfdecAudio *audio = walk->data;    if (audio->added)      continue;    g_signal_emit (player, signals[AUDIO_ADDED], 0, audio);    audio->added = TRUE;  }}static gbooleanswfdec_player_do_handle_mouse (SwfdecPlayer *player,     double x, double y, int button){  swfdec_player_lock (player);  x *= SWFDEC_TWIPS_SCALE_FACTOR;  y *= SWFDEC_TWIPS_SCALE_FACTOR;  SWFDEC_LOG ("handling mouse at %g %g %d", x, y, button);  if (player->mouse_x != x || player->mouse_y != y) {    player->mouse_x = x;    player->mouse_y = y;    swfdec_player_do_mouse_move (player);  }  if (player->mouse_button != button) {    player->mouse_button = button;    swfdec_player_do_mouse_button (player);  }  swfdec_player_perform_actions (player);  swfdec_player_unlock (player);  /* FIXME: allow events to pass through */  return TRUE;}static voidswfdec_player_iterate (SwfdecTimeout *timeout){  SwfdecPlayer *player = SWFDEC_PLAYER ((void *) timeout - G_STRUCT_OFFSET (SwfdecPlayer, iterate_timeout));  GList *walk;  SWFDEC_INFO ("=== START ITERATION ===");  /* First, we prepare the iteration. We flag all movies for removal that will    * be removed */  for (walk = player->movies; walk; walk = walk->next) {    if (SWFDEC_IS_SPRITE_MOVIE (walk->data))      swfdec_sprite_movie_prepare (walk->data);  }  /* Step 2: start the iteration. This performs a goto next frame on all    * movies that are not stopped. It also queues onEnterFrame.   */  for (walk = player->movies; walk; walk = walk->next) {    SwfdecMovieClass *klass = SWFDEC_MOVIE_GET_CLASS (walk->data);    if (klass->iterate_start)      klass->iterate_start (walk->data);  }  swfdec_player_perform_actions (player);  SWFDEC_INFO ("=== STOP ITERATION ===");  /* this loop allows removal of walk->data */  walk = player->movies;  while (walk) {    SwfdecMovie *cur = walk->data;    SwfdecMovieClass *klass = SWFDEC_MOVIE_GET_CLASS (cur);    walk = walk->next;    g_assert (klass->iterate_end);    if (!klass->iterate_end (cur))      swfdec_movie_destroy (cur);  }  /* add timeout again */  /* FIXME: rounding issues? */  player->iterate_timeout.timestamp += SWFDEC_TICKS_PER_SECOND * 256 / player->rate;  swfdec_player_add_timeout (player, &player->iterate_timeout);}static voidswfdec_player_do_advance (SwfdecPlayer *player, guint msecs, guint audio_samples){  GList *walk;  SwfdecAudio *audio;  SwfdecTimeout *timeout;  SwfdecTick target_time;  guint frames_now;    swfdec_player_lock (player);  target_time = player->time + SWFDEC_MSECS_TO_TICKS (msecs);  SWFDEC_DEBUG ("advancing %u msecs (%u audio frames)", msecs, audio_samples);  player->audio_skip = audio_samples;  /* iterate all playing sounds */  walk = player->audio;  while (walk) {    audio = walk->data;    walk = walk->next;    if (swfdec_audio_iterate (audio, audio_samples) == 0)      swfdec_audio_remove (audio);  }  for (timeout = player->timeouts ? player->timeouts->data : NULL;       timeout && timeout->timestamp <= target_time;        timeout = player->timeouts ? player->timeouts->data : NULL) {    player->timeouts = g_list_remove (player->timeouts, timeout);    frames_now = SWFDEC_TICKS_TO_SAMPLES (timeout->timestamp) -      SWFDEC_TICKS_TO_SAMPLES (player->time);    player->time = timeout->timestamp;    player->audio_skip -= frames_now;    SWFDEC_LOG ("activating timeout %p now (timeout is %"G_GUINT64_FORMAT", target time is %"G_GUINT64_FORMAT,	timeout, timeout->timestamp, target_time);    timeout->callback (timeout);    swfdec_player_perform_actions (player);  }  if (target_time > player->time) {    frames_now = SWFDEC_TICKS_TO_SAMPLES (target_time) -      SWFDEC_TICKS_TO_SAMPLES (player->time);    player->time = target_time;    player->audio_skip -= frames_now;  }  g_assert (player->audio_skip == 0);    swfdec_player_unlock (player);}voidswfdec_player_perform_actions (SwfdecPlayer *player){  GList *walk;  SwfdecRect old_inval;  g_return_if_fail (SWFDEC_IS_PLAYER (player));  swfdec_rect_init_empty (&old_inval);  do {    while (swfdec_player_do_action (player));    for (walk = player->roots; walk; walk = walk->next) {      swfdec_movie_update (walk->data);    }    /* update the state of the mouse when stuff below it moved */    if (swfdec_rect_contains (&player->invalid, player->mouse_x, player->mouse_y)) {      SWFDEC_INFO ("=== NEED TO UPDATE mouse post-iteration ===");      swfdec_player_update_mouse_position (player);      for (walk = player->roots; walk; walk = walk->next) {	swfdec_movie_update (walk->data);      }    }    swfdec_rect_union (&old_inval, &old_inval, &player->invalid);    swfdec_rect_init_empty (&player->invalid);  } while (swfdec_ring_buffer_get_n_elements (player->actions) > 0);  player->invalid = old_inval;}voidswfdec_player_lock (SwfdecPlayer *player){  g_return_if_fail (SWFDEC_IS_PLAYER (player));  g_assert (swfdec_ring_buffer_get_n_elements (player->actions) == 0);  g_assert (swfdec_rect_is_empty (&player->invalid));  g_object_freeze_notify (G_OBJECT (player));  SWFDEC_DEBUG ("LOCKED");}voidswfdec_player_unlock (SwfdecPlayer *player){  g_return_if_fail (SWFDEC_IS_PLAYER (player));  g_assert (swfdec_ring_buffer_get_n_elements (player->actions) == 0);  SWFDEC_DEBUG ("UNLOCK");  swfdec_player_update_mouse_cursor (player);  g_object_thaw_notify (G_OBJECT (player));  swfdec_player_emit_signals (player);}static gbooleanswfdec_accumulate_or (GSignalInvocationHint *ihint, GValue *return_accu,     const GValue *handler_return, gpointer data){  if (g_value_get_boolean (handler_return))    g_value_set_boolean (return_accu, TRUE);  return TRUE;}static voidswfdec_player_class_init (SwfdecPlayerClass *klass){  GObjectClass *object_class = G_OBJECT_CLASS (klass);  object_class->get_property = swfdec_player_get_property;  object_class->set_property = swfdec_player_set_property;  object_class->dispose = swfdec_player_dispose;  g_object_class_install_property (object_class, PROP_INITIALIZED,      g_param_spec_boolean ("initialized", "initialized", "TRUE when the player has initialized its basic values",	  FALSE, G_PARAM_READABLE));  g_object_class_install_property (object_class, PROP_MOUSE_CURSOR,      g_param_spec_enum ("mouse-cursor", "mouse cursor", "how the mouse pointer should be presented",	  SWFDEC_TYPE_MOUSE_CURSOR, SWFDEC_MOUSE_CURSOR_NONE, G_PARAM_READABLE));  g_object_class_install_property (object_class, PROP_NEXT_EVENT,      g_param_spec_uint ("next-event", "next event", "how many milliseconds until the next event or 0 when no event pending",	  0, G_MAXUINT, 0, G_PARAM_READABLE));  g_object_class_install_property (object_class, PROP_CACHE_SIZE,      g_param_spec_uint ("cache-size", "cache size", "maximum cache size in bytes",	  0, G_MAXUINT, 50 * 1024 * 1024, G_PARAM_READABLE));  g_object_class_install_property (object_class, PROP_BACKGROUND_COLOR,      g_param_spec_uint ("background-color", "background color", "ARGB color used to draw the background",	  0, G_MAXUINT, SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF), G_PARAM_READWRITE));  /**   * SwfdecPlayer::trace:   * @player: the #SwfdecPlayer affected   * @text: the debugging string   *   * Emits a debugging string while running. The effect of calling any swfdec    * functions on the emitting @player is undefined.   */  signals[TRACE] = g_signal_new ("trace", G_TYPE_FROM_CLASS (klass),      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__STRING,      G_TYPE_NONE, 1, G_TYPE_STRING);  /**   * SwfdecPlayer::invalidate:   * @player: the #SwfdecPlayer affected   * @x: x coordinate of invalid region   * @y: y coordinate of invalid region   * @width: width of invalid region   * @height: height of invalid region   *   * This signal is emitted whenever graphical elements inside the player have    * changed. The coordinates describe the smallest rectangle that includes all   * changes.   */  signals[INVALIDATE] = g_signal_new ("invalidate", G_TYPE_FROM_CLASS (klass),      G_SIGNAL_RUN_LAST, 0, NULL, NULL, swfdec_marshal_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE,      G_TYPE_NONE, 4, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE);  /**   * SwfdecPlayer::advance:   * @player: the #SwfdecPlayer affected   * @msecs: the amount of milliseconds the player will advance   * @audio_samples: number of frames the audio is advanced (in 44100Hz steps)   *   * Emitted whenever the player advances.   */  signals[ADVANCE] = g_signal_new ("advance", G_TYPE_FROM_CLASS (klass),      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SwfdecPlayerClass, advance),       NULL, NULL, swfdec_marshal_VOID__UINT_UINT,      G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);  /**   * SwfdecPlayer::handle-mouse:   * @player: the #SwfdecPlayer affected   * @x: new x coordinate of the mouse   * @y: new y coordinate of the mouse   * @button: 1 if the button is pressed, 0 if not   *   * this signal is emitted whenever @player should respond to a mouse event. If   * any of the handlers returns TRUE, swfdec_player_handle_mouse() will return    * TRUE. Note that unlike many event handlers in gtk, returning TRUE will not    * stop further event handlers from being invoked. Use g_signal_stop_emission()   * in that case.   *   * Returns: TRUE if this handler handles the event.    **/  signals[HANDLE_MOUSE] = g_signal_new ("handle-mouse", G_TYPE_FROM_CLASS (klass),      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (SwfdecPlayerClass, handle_mouse),       swfdec_accumulate_or, NULL, swfdec_marshal_BOOLEAN__DOUBLE_DOUBLE_INT,      G_TYPE_BOOLEAN, 3, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_INT);  /**   * SwfdecPlayer::audio-added:   * @player: the #SwfdecPlayer affected   * @audio: the audio stream that was added   *   * Emitted whenever a new audio stream was added to @player.   */  signals[AUDIO_ADDED] = g_signal_new ("audio-added", G_TYPE_FROM_CLASS (klass),      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT,      G_TYPE_NONE, 1, SWFDEC_TYPE_AUDIO);  /**   * SwfdecPlayer::audio-removed:   * @player: the #SwfdecPlayer affected   * @audio: the audio stream that was removed   *   * Emitted whenever an audio stream was removed from @player. The stream will    * have been added with the SwfdecPlayer::audio-added signal previously.    */  signals[AUDIO_REMOVED] = g_signal_new ("audio-removed", G_TYPE_FROM_CLASS (klass),      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT,      G_TYPE_NONE, 1, SWFDEC_TYPE_AUDIO);  /**   * SwfdecPlayer::launch:   * @player: the #SwfdecPlayer affected   * @url: URL to open   * @target: target to load the URL into   *   * Emitted whenever the @player encounters an URL that should be loaded into    * a target the Flash player does not recognize. In most cases this happens    * when the user clicks a link in an embedded Flash movie that should open a   * new web page.   * The effect of calling any swfdec functions on the emitting @player is undefined.   */  signals[LAUNCH] = g_signal_new ("launch", G_TYPE_FROM_CLASS (klass),      G_SIGNAL_RUN_LAST, 0, NULL, NULL, swfdec_marshal_VOID__STRING_STRING,      G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);  klass->advance = swfdec_player_do_advance;  klass->handle_mouse = swfdec_player_do_handle_mouse;}static voidswfdec_player_init (SwfdecPlayer *player){  swfdec_js_init_player (player);  player->registered_classes = g_hash_table_new_full (g_str_hash, g_str_equal,       g_free, NULL);  player->actions = swfdec_ring_buffer_new_for_type (SwfdecPlayerAction, 16);  player->cache = swfdec_cache_new (50 * 1024 * 1024); /* 100 MB */  player->bgcolor = SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF);  player->mouse_visible = TRUE;  player->mouse_cursor = SWFDEC_MOUSE_CURSOR_NORMAL;  player->iterate_timeout.callback = swfdec_player_iterate;  player->init_queue = g_queue_new ();  player->construct_queue = g_queue_new ();}voidswfdec_player_stop_all_sounds (SwfdecPlayer *player){  g_return_if_fail (SWFDEC_IS_PLAYER (player));  while (player->audio) {    swfdec_audio_remove (player->audio->data);  }}voidswfdec_player_trace (SwfdecPlayer *player, const char *text){  g_return_if_fail (SWFDEC_IS_PLAYER (player));  g_return_if_fail (text != NULL);    /* FIXME: accumulate and emit after JS handling? */  g_signal_emit (player, signals[TRACE], 0, text);}voidswfdec_player_invalidate (SwfdecPlayer *player, const SwfdecRect *rect){  if (swfdec_rect_is_empty (rect)) {    g_assert_not_reached ();    return;  }  swfdec_rect_union (&player->invalid, &player->invalid, rect);  SWFDEC_DEBUG ("toplevel invalidation of %g %g  %g %g - invalid region now %g %g  %g %g",      rect->x0, rect->y0, rect->x1, rect->y1,      player->invalid.x0, player->invalid.y0, player->invalid.x1, player->invalid.y1);}SwfdecRootMovie *swfdec_player_add_level_from_loader (SwfdecPlayer *player, guint depth,    SwfdecLoader *loader, const char *variables){  SwfdecMovie *movie;  SwfdecRootMovie *root;  swfdec_player_remove_level (player, depth);  movie = swfdec_movie_new_for_player (player, depth);  root = SWFDEC_ROOT_MOVIE (movie);  root->player = player;  root->loader = loader;  if (variables)    swfdec_scriptable_set_variables (SWFDEC_SCRIPTABLE (movie), variables);  swfdec_loader_set_target (root->loader, SWFDEC_LOADER_TARGET (root));  return root;}voidswfdec_player_remove_level (SwfdecPlayer *player, guint depth){  GList *walk;  int real_depth;  real_depth = (int) depth - 16384;  for (walk = player->roots; walk; walk = walk->next) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -