viewer: support FF/REW 09/55309/2 accepted/tizen/tv/20151223.110704 submit/tizen/20151223.093646
authorMinkyu Kang <mk7.kang@samsung.com>
Wed, 23 Dec 2015 05:08:05 +0000 (14:08 +0900)
committerMinkyu Kang <mk7.kang@samsung.com>
Wed, 23 Dec 2015 06:25:30 +0000 (15:25 +0900)
Change-Id: I776b656dab20d54b5123856f15b98ccc5f039ce5
Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
include/util/playermgr.h
include/view/viewer.h
res/edc/images/ic_player_ff.png [new file with mode: 0644]
res/edc/images/ic_player_rew.png [new file with mode: 0644]
res/edc/view/viewer.edc
src/util/playermgr.c
src/view/viewer.c

index 46c6005..369b638 100644 (file)
@@ -33,7 +33,14 @@ bool playermgr_set_position(struct playermgr *m, int ms,
                player_seek_completed_cb cb, void *data);
 void playermgr_get_state(struct playermgr *m, player_state_e *state);
 bool playermgr_set_completed_cb(struct playermgr *m,
-               player_completed_cb cb, void *data);
+               void (*func)(void *data), void *data);
+bool playermgr_set_seek_cb(struct playermgr *m,
+               void (*func)(void *data), void *data);
 const char *playermgr_get_path(struct playermgr *m);
 
+bool playermgr_set_ff(struct playermgr *m);
+bool playermgr_set_rew(struct playermgr *m);
+void playermgr_stop_wind(struct playermgr *m);
+int playermgr_get_wind(struct playermgr *m);
+
 #endif
index 11744a2..beb81a8 100644 (file)
@@ -36,6 +36,7 @@
 #define PART_VIEWER_TOTAL "part.viewer_total"
 #define PART_VIEWER_FAVORITE "part.viewer_favorite"
 #define PART_VIEWER_SLIDER "part.viewer_slider"
+#define PART_VIEWER_WIND "part.viewer_wind"
 
 /* signal */
 #define SIG_SET_PLAY "set,play,icon"
@@ -46,6 +47,9 @@
 #define SIG_SHOWED_BAR "showed,bar"
 #define SIG_VIEWER_SHOW_FAV "show,favorite"
 #define SIG_VIEWER_HIDE_FAV "hide,favorite"
+#define SIG_VIEWER_SHOW_FF "show,ff"
+#define SIG_VIEWER_SHOW_REW "show,rew"
+#define SIG_VIEWER_HIDE_WIND "hide,wind"
 #define SIG_SET_FOCUS "set,focus"
 #define SIG_SET_UNFOCUS "set,unfocus"
 
@@ -85,5 +89,7 @@
 #define IMAGE_VIEWER_ZOOM_NORMAL "btn_view_contr_zoom_nor.png"
 #define IMAGE_VIEWER_SLIDE_FOCUS "btn_view_contr_slideshow_foc.png"
 #define IMAGE_VIEWER_SLIDE_NORMAL "btn_view_contr_slideshow_nor.png"
+#define IMAGE_VIEWER_FF_ICON "ic_player_ff.png"
+#define IMAGE_VIEWER_REW_ICON "ic_player_rew.png"
 
 #endif /* __AIR_MEDIAHUB_VIEW_VIEWER_H__ */
diff --git a/res/edc/images/ic_player_ff.png b/res/edc/images/ic_player_ff.png
new file mode 100644 (file)
index 0000000..b13c9c4
Binary files /dev/null and b/res/edc/images/ic_player_ff.png differ
diff --git a/res/edc/images/ic_player_rew.png b/res/edc/images/ic_player_rew.png
new file mode 100644 (file)
index 0000000..e1e16c4
Binary files /dev/null and b/res/edc/images/ic_player_rew.png differ
index b0f1ab4..0810c18 100644 (file)
@@ -18,6 +18,8 @@ group {
        name: GRP_VIEWER_VIEW;
        images {
                image: IMAGE_VIEWER_FAVORITE COMP;
+               image: IMAGE_VIEWER_FF_ICON COMP;
+               image: IMAGE_VIEWER_REW_ICON COMP;
        }
        parts {
                part {
@@ -228,6 +230,93 @@ group {
                                visible: 1;
                        }
                }
+               part {
+                       name: "padding_bottom";
+                       type: SPACER;
+                       scale: 1;
+                       description {
+                               state: "default" 0.0;
+                               min: 35 35;
+                               rel1 {
+                                       to: "toparea";
+                                       relative: 0.0 1.0;
+                               }
+                               rel2 {
+                                       to: "toparea";
+                                       relative: 0.0 1.0;
+                               }
+                               fixed: 1 1;
+                               align: 0.0 0.0;
+                       }
+               }
+               part {
+                       name: "wind_icon";
+                       type: IMAGE;
+                       scale: 1;
+                       description {
+                               state: "default" 0.0;
+                               min: 46 36;
+                               rel1 {
+                                       to: "padding_bottom";
+                                       relative: 1.0 1.0;
+                               }
+                               rel2 {
+                                       to: "padding_bottom";
+                                       relative: 1.0 1.0;
+                               }
+                               image.normal: IMAGE_VIEWER_FF_ICON;
+                               fixed: 1 1;
+                               align: 0.0 0.0;
+                               visible: 0;
+                       }
+                       description {
+                               state: "ff" 0.0;
+                               inherit: "default" 0.0;
+                               image.normal: IMAGE_VIEWER_FF_ICON;
+                               visible: 1;
+                       }
+                       description {
+                               state: "rew" 0.0;
+                               inherit: "default" 0.0;
+                               image.normal: IMAGE_VIEWER_REW_ICON;
+                               visible: 1;
+                       }
+               }
+               part {
+                       name: PART_VIEWER_WIND;
+                       type: TEXT;
+                       scale: 1;
+                       description {
+                               state: "default" 0.0;
+                               min: 56 0;
+                               rel1 {
+                                       to: "wind_icon";
+                                       relative: 1.0 0.0;
+                               }
+                               rel2 {
+                                       to: "wind_icon";
+                               }
+                               text {
+                                       font: FONT_LIGHT;
+                                       size: 36;
+                                       align: 1.0 0.5;
+                               }
+                               color: COLOR_TEXT_FOCUS;
+                               fixed: 1 0;
+                               align: 0.0 0.5;
+                               visible: 0;
+                       }
+                       description {
+                               state: "ff" 0.0;
+                               inherit: "default" 0.0;
+                               visible: 1;
+                       }
+                       description {
+                               state: "rew" 0.0;
+                               inherit: "default" 0.0;
+                               visible: 1;
+                       }
+               }
 
                /* BOTTOM */
                part {
@@ -639,5 +728,29 @@ group {
                        action: STATE_SET "default" 0.0;
                        target: PART_VIEWER_FAVORITE;
                }
+               program {
+                       name: SIG_VIEWER_SHOW_FF;
+                       signal: SIG_VIEWER_SHOW_FF;
+                       source: "";
+                       action: STATE_SET "ff" 0.0;
+                       target: "wind_icon";
+                       target: PART_VIEWER_WIND;
+               }
+               program {
+                       name: SIG_VIEWER_SHOW_REW;
+                       signal: SIG_VIEWER_SHOW_REW;
+                       source: "";
+                       action: STATE_SET "rew" 0.0;
+                       target: "wind_icon";
+                       target: PART_VIEWER_WIND;
+               }
+               program {
+                       name: SIG_VIEWER_HIDE_WIND;
+                       signal: SIG_VIEWER_HIDE_WIND;
+                       source: "";
+                       action: STATE_SET "default" 0.0;
+                       target: "wind_icon";
+                       target: PART_VIEWER_WIND;
+               }
        }
 }
index d4d8967..8e406d2 100644 (file)
 #include "define.h"
 
 #define EVENT_INTERVAL 0.1
+#define SEEK_INTERVAL 0.5
+
+#define SPEED_MAX 3
+
+static int _speed[] = {
+       0,
+       2,
+       4,
+       8
+};
 
 struct _player_cb {
        void (*func)(void *data);
        void *data;
 };
 
+struct _wind {
+       int ff;
+       int rew;
+};
+
 struct playermgr {
        Evas_Object *win;
        Ecore_Timer *event_loop;
@@ -35,6 +50,9 @@ struct playermgr {
        player_h player;
        char *path;
        struct _player_cb complete_cb;
+       struct _player_cb seek_set_cb;
+       struct _player_cb seek_cb;
+       struct _wind wind;
 };
 
 static Eina_Bool _event_cb(void *data)
@@ -63,8 +81,10 @@ static Eina_Bool _event_cb(void *data)
 
 static void _event_loop_stop(struct playermgr *m)
 {
-       ecore_timer_del(m->event_loop);
-       m->event_loop = NULL;
+       if (m->event_loop) {
+               ecore_timer_del(m->event_loop);
+               m->event_loop = NULL;
+       }
 }
 
 static void _event_loop_start(struct playermgr *m)
@@ -201,8 +221,6 @@ bool playermgr_pause(struct playermgr *m)
                return false;
        }
 
-       _event_loop_stop(m);
-
        return true;
 }
 
@@ -226,8 +244,6 @@ bool playermgr_resume(struct playermgr *m)
                return false;
        }
 
-       _event_loop_start(m);
-
        return true;
 }
 
@@ -308,22 +324,201 @@ bool playermgr_play(struct playermgr *m, const char *path, int ms)
 }
 
 bool playermgr_set_completed_cb(struct playermgr *m,
-               player_completed_cb cb, void *data)
+               void (*func)(void *data), void *data)
 {
        int r;
 
+       if (!m) {
+               _ERR("invalid parameter");
+               return false;
+       }
+
        r = player_set_completed_cb(m->player, _player_complete_cb, m);
        if (r != PLAYER_ERROR_NONE) {
                _ERR("player: set callback error (%d)", r);
                return false;
        }
 
-       m->complete_cb.func = cb;
+       m->complete_cb.func = func;
        m->complete_cb.data = data;
 
        return true;
 }
 
+bool playermgr_set_seek_cb(struct playermgr *m,
+               void (*func)(void *data), void *data)
+{
+       if (!m) {
+               _ERR("invalid parameter");
+               return false;
+       }
+
+       m->seek_cb.func = func;
+       m->seek_cb.data = data;
+
+       return true;
+}
+
+void playermgr_stop_wind(struct playermgr *m)
+{
+       if (!m) {
+               _ERR("invalid parameter");
+               return;
+       }
+
+       m->wind.ff = 0;
+       m->wind.rew = 0;
+}
+
+static void _player_seek_cb(void *data)
+{
+       struct playermgr *m;
+
+       if (!data)
+               return;
+
+       m = data;
+
+       m->cb_list = eina_list_append(m->cb_list, &m->seek_set_cb);
+}
+
+static void _seek(void *data)
+{
+       struct playermgr *m;
+       int position;
+       int duration;
+       bool fin;
+
+       if (!data)
+               return;
+
+       m = data;
+
+       position = playermgr_get_position(m);
+       duration = playermgr_get_duration(m);
+
+       fin = false;
+
+       if (m->wind.ff) {
+               position += _speed[m->wind.ff] * 500;
+               if (position > duration) {
+                       position = duration;
+                       fin = true;
+               }
+       } else if (m->wind.rew) {
+               position -= _speed[m->wind.rew] * 500;
+               if (position < 0) {
+                       position = 0;
+                       fin = true;
+               }
+       } else {
+               return;
+       }
+
+       playermgr_set_position(m, position, _player_seek_cb, m);
+
+       if (fin) {
+               m->wind.ff = 0;
+               m->wind.rew = 0;
+
+               if (m->seek_cb.func)
+                       m->seek_cb.func(m->seek_cb.data);
+       }
+}
+
+static Eina_Bool _seek_set_cb(void *data)
+{
+       struct playermgr *m;
+
+       if (!data)
+               return EINA_FALSE;
+
+       m = data;
+
+       _seek(m);
+
+       return EINA_FALSE;
+}
+
+static void _seek_set(void *data)
+{
+       struct playermgr *m;
+
+       if (!data)
+               return;
+
+       m = data;
+
+       ecore_timer_add(SEEK_INTERVAL, _seek_set_cb, m);
+}
+
+static void _start_wind(struct playermgr *m)
+{
+       bool r;
+
+       m->seek_set_cb.func = _seek_set;
+       m->seek_set_cb.data = m;
+
+       r = playermgr_pause(m);
+       if (!r)
+               return;
+
+       _seek_set(m);
+}
+
+bool playermgr_set_rew(struct playermgr *m)
+{
+       if (!m) {
+               _ERR("invalid parameter");
+               return false;
+       }
+
+       m->wind.ff = 0;
+
+       if (m->wind.rew == SPEED_MAX)
+               m->wind.rew = 1;
+       else
+               m->wind.rew++;
+
+       _start_wind(m);
+
+       return true;
+}
+
+bool playermgr_set_ff(struct playermgr *m)
+{
+       if (!m) {
+               _ERR("invalid parameter");
+               return false;
+       }
+
+       m->wind.rew = 0;
+
+       if (m->wind.ff == SPEED_MAX)
+               m->wind.ff = 1;
+       else
+               m->wind.ff++;
+
+       _start_wind(m);
+
+       return true;
+}
+
+int playermgr_get_wind(struct playermgr *m)
+{
+       if (!m) {
+               _ERR("invalid parameter");
+               return false;
+       }
+
+       if (m->wind.ff)
+               return _speed[m->wind.ff];
+       else if (m->wind.rew)
+               return _speed[m->wind.rew];
+
+       return 0;
+}
+
 struct playermgr *playermgr_create(Evas_Object *win)
 {
        struct playermgr *m;
@@ -346,6 +541,9 @@ struct playermgr *playermgr_create(Evas_Object *win)
        m->path = NULL;
        m->event_loop = NULL;
 
+       m->wind.ff = 0;
+       m->wind.rew = 0;
+
        return m;
 }
 
index 925db14..13ac8ed 100644 (file)
 #define PART_VIEWER_BTN "control_btn"
 
 #define POSITION_MARGIN 500
-#define VIEWER_TIMEOUT 3.0
+#define VIEWER_TIMEOUT 5.0
 #define VIEWER_SEPARATOR "/ "
 #define SLIDE_SHOW_INTERVAL 3.0
 #define ERROR_MESSAGE "Something went wrong."
 
 #define BTN_LOC_NONE -1
 #define BTN_LOC_PREV 0
+#define BTN_LOC_REW 1
 #define BTN_LOC_PLAY 2
+#define BTN_LOC_FF 3
 #define BTN_LOC_NEXT 4
 #define BTN_LOC_ROTATE 5
 #define BTN_LOC_ZOOM 5
 #define BTN_LOC_SLIDE 8
 
 enum {
+       WIND_NONE,
+       WIND_FF,
+       WIND_REW,
+};
+
+enum {
        VIEWER_MOVIE,
        VIEWER_PHOTO,
        VIEWER_VIDEO,
@@ -104,10 +112,18 @@ static struct _btn_info btn_movie[] = {
                .loc = BTN_LOC_PREV,
        },
        {
+               .name = SRC_BTN_REW,
+               .loc = BTN_LOC_REW,
+       },
+       {
                .name = SRC_BTN_PLAY,
                .loc = BTN_LOC_PLAY,
        },
        {
+               .name = SRC_BTN_FF,
+               .loc = BTN_LOC_FF,
+       },
+       {
                .name = SRC_BTN_NEXT,
                .loc = BTN_LOC_NEXT,
        },
@@ -144,6 +160,10 @@ static struct _btn_info btn_video[] = {
                .loc = BTN_LOC_PREV,
        },
        {
+               .name = SRC_BTN_REW,
+               .loc = BTN_LOC_REW,
+       },
+       {
                .name = SRC_BTN_PLAY,
                .loc = BTN_LOC_PLAY,
        },
@@ -152,6 +172,10 @@ static struct _btn_info btn_video[] = {
                .loc = BTN_LOC_NEXT,
        },
        {
+               .name = SRC_BTN_FF,
+               .loc = BTN_LOC_FF,
+       },
+       {
                .name = SRC_BTN_SLIDE,
                .loc = BTN_LOC_SLIDE,
        },
@@ -166,6 +190,7 @@ struct _viewer_info {
 
 static void _player_play(struct _priv *priv);
 static void _player_stop(struct _priv *priv);
+static void _player_pause(struct _priv *priv);
 
 static void _callback_movie(void *data, const char *ev);
 static void _callback_photo(void *data, const char *ev);
@@ -178,7 +203,7 @@ static void _slideshow_disable(struct _priv *priv);
 static struct _viewer_info viewer_info[] = {
        {
                .btns = btn_movie,
-               .btn_count = 3,
+               .btn_count = 5,
                .focus_loc = BTN_LOC_PLAY,
                .callback = _callback_movie,
        },
@@ -190,7 +215,7 @@ static struct _viewer_info viewer_info[] = {
        },
        {
                .btns = btn_video,
-               .btn_count = 4,
+               .btn_count = 6,
                .focus_loc = BTN_LOC_NEXT,
                .callback = _callback_video,
        },
@@ -211,49 +236,6 @@ static void _set_bg_color(struct _priv *priv, int r, int g, int b, int a)
        elm_object_part_content_set(priv->base, PART_VIEWER_BG, bg);
 }
 
-static void _draw_thumbnail(struct _priv *priv, app_media_info *mi)
-{
-       Evas_Object *obj;
-
-       if (priv->photo_pre) {
-               evas_object_del(priv->photo_pre);
-               priv->photo_pre = NULL;
-       }
-
-       if (priv->photo) {
-               evas_object_del(priv->photo);
-               priv->photo = NULL;
-       }
-
-       obj = elm_image_add(priv->base);
-       if (!obj) {
-               _ERR("failed to adding image");
-               return;
-       }
-
-       elm_image_file_set(obj, mi->thumbnail_path, NULL);
-       elm_object_part_content_set(priv->base, PART_VIEWER_CONTENT, obj);
-
-       priv->photo = obj;
-}
-
-static void _remove_thumbnail(struct _priv *priv)
-{
-       if (priv->photo_pre) {
-               evas_object_del(priv->photo_pre);
-               priv->photo_pre = NULL;
-       }
-
-       if (priv->photo) {
-               evas_object_del(priv->photo);
-               priv->photo = NULL;
-       }
-
-       _set_bg_color(priv, 0, 0, 0, 0);
-
-       elm_object_part_content_unset(priv->base, PART_VIEWER_CONTENT);
-}
-
 static void _image_loaded(void *data, Evas_Object *obj, void *ev)
 {
        struct _priv *priv;
@@ -295,10 +277,11 @@ static void _draw_contents(struct _priv *priv, int id, app_media_info *mi)
                _player_play(priv);
                return;
        } else if (id == VIEWER_VIDEO) {
-               if (priv->slideshow.enable)
-                       _player_play(priv);
-               else
-                       _draw_thumbnail(priv, mi);
+               _player_play(priv);
+
+               if (!priv->slideshow.enable)
+                       _player_pause(priv);
+
                return;
        } else if (id == VIEWER_PHOTO) {
                if (priv->slideshow.enable)
@@ -395,6 +378,18 @@ static void _draw_favorite_icon(struct _priv *priv, int id, app_media_info *mi)
                elm_object_signal_emit(priv->base, SIG_VIEWER_HIDE_FAV, "");
 }
 
+static void _draw_wind(struct _priv *priv, int speed)
+{
+       char buf[32] = {0,};
+
+       if (speed) {
+               snprintf(buf, sizeof(buf), "x%d", speed);
+               elm_object_part_text_set(priv->base, PART_VIEWER_WIND, buf);
+       } else {
+               elm_object_part_text_set(priv->base, PART_VIEWER_WIND, "");
+       }
+}
+
 static app_media_info *_get_current_media_info(struct _priv *priv)
 {
        app_media *am;
@@ -612,15 +607,15 @@ static bool _viewer_show(struct _priv *priv)
                }
        }
 
-       ctl->ops->signal(ctl->handle, loc, SIG_SET_FOCUS);
-       ctl->ops->focus(ctl->handle, loc, true);
-
        _draw_title_bar(priv, id, mi);
        _draw_progressbar(priv, id, mi);
        _draw_favorite_icon(priv, id, mi);
 
        _draw_contents(priv, id, mi);
 
+       ctl->ops->signal(ctl->handle, loc, SIG_SET_FOCUS);
+       ctl->ops->focus(ctl->handle, loc, true);
+
        return true;
 }
 
@@ -631,7 +626,6 @@ static void _viewer_hide(struct _priv *priv)
        ctl = priv->viewer.ctl[priv->viewer.cur];
        ctl->ops->hide(ctl->handle);
 
-       _remove_thumbnail(priv);
        elm_object_signal_emit(priv->base, SIG_VIEWER_HIDE_FAV, "");
 }
 
@@ -871,6 +865,7 @@ static void _player_play_pause(struct _priv *priv)
                break;
        case PLAYER_STATE_PLAYING:
                progressbar_pause(priv->progress);
+               playermgr_stop_wind(priv->player);
                r = playermgr_pause(priv->player);
                if (!r) {
                        _error_exit(priv);
@@ -885,9 +880,9 @@ static void _player_play_pause(struct _priv *priv)
                        return;
                }
 
-               _remove_thumbnail(priv);
                _update_to_player(priv);
 
+               playermgr_stop_wind(priv->player);
                r = playermgr_play(priv->player, mi->file_path,
                                mi->video->position);
                if (!r) {
@@ -934,9 +929,9 @@ static void _player_play(struct _priv *priv)
                        return;
                }
 
-               _remove_thumbnail(priv);
                _update_to_player(priv);
 
+               playermgr_stop_wind(priv->player);
                r = playermgr_play(priv->player, mi->file_path,
                                mi->video->position);
                if (!r) {
@@ -1025,6 +1020,52 @@ static void _player_complete_cb(void *data)
        }
 }
 
+static void _player_set_wind(struct _priv *priv, int wind)
+{
+       struct controller *ctl;
+
+       switch (wind) {
+       case WIND_FF:
+               elm_object_signal_emit(priv->base, SIG_VIEWER_SHOW_FF, "");
+               playermgr_set_ff(priv->player);
+               timeout_handler_enable(priv->timeout, false);
+               progressbar_resume(priv->progress);
+
+               ctl = priv->viewer.ctl[priv->viewer.cur];
+               ctl->ops->signal(ctl->handle, BTN_LOC_PLAY, SIG_SET_PLAY);
+               break;
+       case WIND_REW:
+               elm_object_signal_emit(priv->base, SIG_VIEWER_SHOW_REW, "");
+               playermgr_set_rew(priv->player);
+               timeout_handler_enable(priv->timeout, false);
+               progressbar_resume(priv->progress);
+
+               ctl = priv->viewer.ctl[priv->viewer.cur];
+               ctl->ops->signal(ctl->handle, BTN_LOC_PLAY, SIG_SET_PLAY);
+               break;
+       case WIND_NONE:
+       default:
+               elm_object_signal_emit(priv->base, SIG_VIEWER_HIDE_WIND, "");
+               playermgr_stop_wind(priv->player);
+               timeout_handler_enable(priv->timeout, true);
+               break;
+       }
+
+       _draw_wind(priv, playermgr_get_wind(priv->player));
+}
+
+static void _player_seek_cb(void *data)
+{
+       struct _priv *priv;
+
+       if (!data)
+               return;
+
+       priv = data;
+
+       _player_set_wind(priv, WIND_NONE);
+}
+
 static struct progressbar_ops _progressbar_ops = {
        .get_value = _player_get_position,
 };
@@ -1038,12 +1079,20 @@ static void _callback_movie(void *data, const char *ev)
 
        priv = data;
 
-       if (!strcmp(ev, SRC_BTN_PREV))
+       if (!strcmp(ev, SRC_BTN_PREV)) {
+               _player_set_wind(priv, WIND_NONE);
                _player_set_position(priv, 0);
-       else if (!strcmp(ev, SRC_BTN_NEXT))
+       } else if (!strcmp(ev, SRC_BTN_NEXT)) {
+               _player_set_wind(priv, WIND_NONE);
                _player_set_position(priv, -1);
-       else if (!strcmp(ev, SRC_BTN_PLAY))
+       } else if (!strcmp(ev, SRC_BTN_PLAY)) {
+               _player_set_wind(priv, WIND_NONE);
                _player_play_pause(priv);
+       } else if (!strcmp(ev, SRC_BTN_REW)) {
+               _player_set_wind(priv, WIND_REW);
+       } else if (!strcmp(ev, SRC_BTN_FF)) {
+               _player_set_wind(priv, WIND_FF);
+       }
 }
 
 static void _callback_photo(void *data, const char *ev)
@@ -1083,17 +1132,25 @@ static void _callback_video(void *data, const char *ev)
        priv = data;
 
        if (!strcmp(ev, SRC_BTN_GALLERY_PREV)) {
+               _player_set_wind(priv, WIND_NONE);
                _player_stop(priv);
                _viewer_prev(priv);
        } else if (!strcmp(ev, SRC_BTN_GALLERY_NEXT)) {
+               _player_set_wind(priv, WIND_NONE);
                _player_stop(priv);
                _viewer_next(priv);
        } else if (!strcmp(ev, SRC_BTN_PLAY)) {
+               _player_set_wind(priv, WIND_NONE);
                _player_play_pause(priv);
        } else if (!strcmp(ev, SRC_BTN_SLIDE)) {
+               _player_set_wind(priv, WIND_NONE);
                _slideshow_enable(priv);
                _hide_bar(priv);
                _viewer_show(priv);
+       } else if (!strcmp(ev, SRC_BTN_REW)) {
+               _player_set_wind(priv, WIND_REW);
+       } else if (!strcmp(ev, SRC_BTN_FF)) {
+               _player_set_wind(priv, WIND_FF);
        }
 }
 
@@ -1276,6 +1333,14 @@ static Evas_Object *_create(Evas_Object *win, void *data)
                goto err;
        }
 
+       r = playermgr_set_seek_cb(player, _player_seek_cb, priv);
+       if (!r) {
+               _ERR("failed to set callback");
+               evas_object_del(base);
+               playermgr_destroy(player);
+               goto err;
+       }
+
        priv->player = player;
 
        r = _ui_init(priv);