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

📄 swfdec_player.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 5 页
字号:
  SWFDEC_DEBUG ("broadcasting message %s.%s", object_name, signal);  obj = SWFDEC_AS_CONTEXT (player)->global;  swfdec_as_object_get_variable (obj, object_name, &val);  if (!SWFDEC_AS_VALUE_IS_OBJECT (&val))    return;  obj = SWFDEC_AS_VALUE_GET_OBJECT (&val);  SWFDEC_AS_VALUE_SET_STRING (&val, signal);  swfdec_as_object_call (obj, SWFDEC_AS_STR_broadcastMessage, 1, &val, NULL);}static voidswfdec_player_update_mouse_cursor (SwfdecPlayer *player){  SwfdecMouseCursor new = SWFDEC_MOUSE_CURSOR_NORMAL;  if (!player->mouse_visible) {    new = SWFDEC_MOUSE_CURSOR_NONE;  } else if (player->mouse_grab != NULL) {    /* FIXME: this needs to be more sophisticated, since SwfdecEditText may     * want to have different mouse cursors depending on location (it supports     * links in theory)     */    if (SWFDEC_IS_BUTTON_MOVIE (player->mouse_grab))      new = SWFDEC_MOUSE_CURSOR_CLICK;  }  if (new != player->mouse_cursor) {    player->mouse_cursor = new;    g_object_notify (G_OBJECT (player), "mouse-cursor");  }}static voidswfdec_player_update_drag_movie (SwfdecPlayer *player){  double x, y;  SwfdecMovie *movie;  if (player->mouse_drag == NULL)    return;  movie = player->mouse_drag;  g_assert (movie->cache_state == SWFDEC_MOVIE_UP_TO_DATE);  x = player->mouse_x;  y = player->mouse_y;  swfdec_player_stage_to_global (player, &x, &y);  if (movie->parent)    swfdec_movie_global_to_local (movie->parent, &x, &y);  if (player->mouse_drag_center) {    x -= (movie->extents.x1 - movie->extents.x0) / 2;    y -= (movie->extents.y1 - movie->extents.y0) / 2;  } else {    x -= player->mouse_drag_x;    y -= player->mouse_drag_y;  }  x = CLAMP (x, player->mouse_drag_rect.x0, player->mouse_drag_rect.x1);  y = CLAMP (y, player->mouse_drag_rect.y0, player->mouse_drag_rect.y1);  SWFDEC_LOG ("mouse is at %g %g, originally (%g %g)", x, y, player->mouse_x, player->mouse_y);  if (x != movie->matrix.x0 || y != movie->matrix.y0) {    movie->matrix.x0 = x;    movie->matrix.y0 = y;    swfdec_movie_queue_update (movie, SWFDEC_MOVIE_INVALID_MATRIX);  }}/** * swfdec_player_set_drag_movie: * @player: a #SwfdecPlayer * @drag: the movie to be dragged by the mouse or NULL to unset * @center: TRUE if the center of @drag should be at the mouse pointer, FALSE if (0,0) *          of @drag should be at the mouse pointer. * @rect: NULL or the rectangle that clips the mouse position. The coordinates  *        are in the coordinate system of the parent of @drag. * * Sets or unsets the movie that is dragged by the mouse. **/voidswfdec_player_set_drag_movie (SwfdecPlayer *player, SwfdecMovie *drag, gboolean center,    SwfdecRect *rect){  g_return_if_fail (SWFDEC_IS_PLAYER (player));  g_return_if_fail (drag == NULL || SWFDEC_IS_MOVIE (drag));  /* FIXME: need to do anything with old drag? */  player->mouse_drag = drag;  player->mouse_drag_center = center;  if (drag && !center) {    player->mouse_drag_x = player->mouse_x;    player->mouse_drag_y = player->mouse_y;    swfdec_player_stage_to_global (player, &player->mouse_drag_x, &player->mouse_drag_y);    if (drag->parent)      swfdec_movie_global_to_local (drag->parent, &player->mouse_drag_x, &player->mouse_drag_y);    player->mouse_drag_x -= drag->matrix.x0;    player->mouse_drag_y -= drag->matrix.y0;  }  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);    drag->modified = TRUE;    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 {    double x, y;    /* if the mouse button is pressed the grab widget stays the same (I think) */    x = player->mouse_x;    y = player->mouse_y;    swfdec_player_stage_to_global (player, &x, &y);    for (walk = g_list_last (player->roots); walk; walk = walk->prev) {      mouse_grab = swfdec_movie_get_movie_at (walk->data, x, 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_player_broadcast (player, SWFDEC_AS_STR_Mouse, SWFDEC_AS_STR_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 = SWFDEC_AS_STR_onMouseDown;  } else {    event = SWFDEC_EVENT_MOUSE_UP;    event_name = SWFDEC_AS_STR_onMouseUp;  }  for (walk = player->movies; walk; walk = walk->next) {    swfdec_movie_queue_script (walk->data, event);  }  swfdec_player_broadcast (player, SWFDEC_AS_STR_Mouse, 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 */    swfdec_player_global_to_stage (player, &player->invalid.x0, &player->invalid.y0);    swfdec_player_global_to_stage (player, &player->invalid.x1, &player->invalid.y1);    x = MAX (player->invalid.x0, 0.0);    y = MAX (player->invalid.y0, 0.0);    width = MIN (player->invalid.x1, player->stage_width) - x;    height = MIN (player->invalid.y1, player->stage_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_key (SwfdecPlayer *player, guint keycode, guint character, gboolean down){  g_assert (keycode < 256);  /* set the correct variables */  player->last_keycode = keycode;  player->last_character = character;  if (down) {    player->key_pressed[keycode / 8] |= 1 << keycode % 8;  } else {    player->key_pressed[keycode / 8] &= ~(1 << keycode % 8);  }  swfdec_player_broadcast (player, SWFDEC_AS_STR_Stage, down ? SWFDEC_AS_STR_onKeyDown : SWFDEC_AS_STR_onKeyUp);  return TRUE;}static gbooleanswfdec_player_do_handle_mouse (SwfdecPlayer *player,     double x, double y, int button){  swfdec_player_lock (player);  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;}voidswfdec_player_global_to_stage (SwfdecPlayer *player, double *x, double *y){  g_return_if_fail (SWFDEC_IS_PLAYER (player));  g_return_if_fail (x != NULL);  g_return_if_fail (y != NULL);  *x = *x / SWFDEC_TWIPS_SCALE_FACTOR * player->scale_x + player->offset_x;  *y = *y / SWFDEC_TWIPS_SCALE_FACTOR * player->scale_y + player->offset_y;}voidswfdec_player_stage_to_global (SwfdecPlayer *player, double *x, double *y){  g_return_if_fail (SWFDEC_IS_PLAYER (player));  g_return_if_fail (x != NULL);  g_return_if_fail (y != NULL);  *x = (*x - player->offset_x) / player->scale_x * SWFDEC_TWIPS_SCALE_FACTOR;  *y = (*y - player->offset_y) / player->scale_y * SWFDEC_TWIPS_SCALE_FACTOR;}static voidswfdec_player_iterate (SwfdecTimeout *timeout){  SwfdecPlayer *player = SWFDEC_PLAYER ((guint8 *) timeout - G_STRUCT_OFFSET (SwfdecPlayer, iterate_timeout));  GList *walk;  swfdec_player_perform_external_actions (player);  SWFDEC_INFO ("=== START ITERATION ===");  /* 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;  double x, y;  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 */    x = player->mouse_x;    y = player->mouse_y;    swfdec_player_stage_to_global (player, &x, &y);    if (swfdec_rect_contains (&player->invalid, x, 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;}/* used for breakpoints */voidswfdec_player_lock_soft (SwfdecPlayer *player){  g_return_if_fail (SWFDEC_IS_PLAYER (player));  g_assert (swfdec_rect_is_empty (&player->invalid));  g_object_freeze_notify (G_OBJECT (player));  SWFDEC_DEBUG ("LOCKED");

⌨️ 快捷键说明

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