Macro qtTrIdx() replaced by tr() and QT_TRANSLATE_NOOP()
[mafwsubrenderer] / mafw-gst-subtitles-renderer / libmafw-gst-renderer / mafw-gst-renderer-state.c
1 /*
2  * This file is a part of MAFW
3  *
4  * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
5  *
6  * Contact: Visa Smolander <visa.smolander@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <libmafw/mafw-renderer.h>
30 #include <libmafw/mafw-errors.h>
31
32 #include "mafw-gst-renderer.h"
33 #include "mafw-gst-renderer-state.h"
34
35 #undef  G_LOG_DOMAIN
36 #define G_LOG_DOMAIN "mafw-gst-renderer-state"
37
38 /*----------------------------------------------------------------------------
39   Default playback implementations
40   ----------------------------------------------------------------------------*/
41
42 static void _default_play(MafwGstRendererState *self, GError **error)
43 {
44         g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
45                     "Play: operation not allowed in %s state",
46                     MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
47 }
48
49
50 static void _default_play_object(MafwGstRendererState *self,
51                                  const gchar *objectid,
52                                  GError **error)
53 {
54         g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
55                     "Play object: operation not allowed in %s state",
56                     MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
57 }
58
59 static void _default_stop(MafwGstRendererState *self, GError **error)
60 {
61         g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_STOP,
62                     "Stop: operation not allowed in %s state",
63                     MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
64 }
65
66 static void _default_pause(MafwGstRendererState *self, GError **error)
67 {
68         g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PAUSE,
69                     "Pause: operation not allowed in %s state",
70                     MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
71 }
72
73 static void _default_resume(MafwGstRendererState *self, GError **error)
74 {
75         g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
76                     "Resume: operation not allowed in %s state",
77                     MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
78 }
79
80 static void _default_set_position (MafwGstRendererState *self,
81                                    MafwRendererSeekMode mode, gint seconds,
82                                    GError **error)
83 {
84         g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_PLAY,
85                     "Set position: operation not allowed in %s state",
86                     MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
87 }
88
89 static void _default_get_position (MafwGstRendererState *self,
90                                    gint *seconds,
91                                    GError **error)
92 {
93         g_set_error(error, MAFW_RENDERER_ERROR, MAFW_RENDERER_ERROR_CANNOT_GET_POSITION,
94                     "Get position: operation not allowed in %s state",
95                     MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
96 }
97
98 /*----------------------------------------------------------------------------
99   Default playlist implementations
100   ----------------------------------------------------------------------------*/
101
102 static void _default_next(MafwGstRendererState *self, GError **error)
103 {
104         g_set_error(error, MAFW_EXTENSION_ERROR, MAFW_EXTENSION_ERROR_FAILED,
105                     "Next: operation not allowed in %s state",
106                     MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
107 }
108
109 static void _default_previous(MafwGstRendererState *self, GError **error)
110 {
111         g_set_error(error, MAFW_EXTENSION_ERROR, MAFW_EXTENSION_ERROR_FAILED,
112                     "Previous: Operation not allowed in %s state",
113                     MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
114 }
115
116 static void _default_goto_index(MafwGstRendererState *self, guint index,
117                                 GError **error)
118 {
119         g_set_error(error, MAFW_EXTENSION_ERROR, MAFW_EXTENSION_ERROR_FAILED,
120                     "Goto index: operation not allowed in %s state",
121                     MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
122 }
123
124 /*----------------------------------------------------------------------------
125   Default notify  metadata implementation
126   ----------------------------------------------------------------------------*/
127
128 static void _default_notify_metadata(MafwGstRendererState *self,
129                                      const gchar *object_id,
130                                      GHashTable *metadata,
131                                      GError **error)
132 {
133
134         g_critical("Notify metadata: got unexpected metadata in %s state",
135                     MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
136 }
137
138 /*----------------------------------------------------------------------------
139   Default notify worker implementations
140   ----------------------------------------------------------------------------*/
141
142 static void _default_notify_play(MafwGstRendererState *self, GError **error)
143 {
144         g_critical("Notify play: unexpected Play notification received in %s "
145                    "state", MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
146 }
147
148 static void _default_notify_pause(MafwGstRendererState *self, GError **error)
149 {
150
151         g_critical("Notify pause: unexpected Pause notification received %s "
152                    "state", MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
153 }
154
155 static void _default_notify_seek(MafwGstRendererState *self, GError **error)
156 {
157         g_critical("Notify seek: incorrect operation in %s state",
158                    MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
159 }
160
161 static void _default_notify_buffer_status(MafwGstRendererState *self,
162                                           gdouble percent,
163                                           GError **error)
164 {
165         g_critical("Notify buffer status: incorrect operation in %s state",
166                    MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
167 }
168
169
170 static void _default_notify_eos(MafwGstRendererState *self, GError **error)
171 {
172         g_critical("Notify eos: incorrect operation in %s state",
173                    MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
174 }
175
176 /*----------------------------------------------------------------------------
177   Default playlist editing signal handlers implementation
178   ----------------------------------------------------------------------------*/
179
180 static void _default_playlist_contents_changed(MafwGstRendererState *self,
181                                                gboolean clip_changed,
182                                                GError **error)
183 {
184         g_warning("playlist::contents-changed not implemented in %s state",
185                   MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
186 }
187
188 /*----------------------------------------------------------------------------
189   Default property methods implementation
190   ----------------------------------------------------------------------------*/
191
192 static GValue* _default_get_property_value(MafwGstRendererState *self,
193                                         const gchar *name)
194 {
195         g_warning("get_property_value function not implemented in %s state",
196                   MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
197         return NULL;
198 }
199
200 /*----------------------------------------------------------------------------
201   Default memory card event handlers implementation
202   ----------------------------------------------------------------------------*/
203
204 static void _default_handle_pre_unmount(MafwGstRendererState *self,
205                                         const gchar *mount_point)
206 {
207         g_debug("pre-unmount signal received: %s in state %s", mount_point,
208                 MAFW_GST_RENDERER_STATE_GET_CLASS(self)->name);
209 }
210
211 /*----------------------------------------------------------------------------
212   GObject initialization
213   ----------------------------------------------------------------------------*/
214
215 G_DEFINE_ABSTRACT_TYPE(MafwGstRendererState, mafw_gst_renderer_state,
216                        G_TYPE_OBJECT);
217
218 static void mafw_gst_renderer_state_init(MafwGstRendererState *self)
219 {
220 }
221
222 static void mafw_gst_renderer_state_class_init(MafwGstRendererStateClass *klass)
223 {
224         /* Playback */
225
226         klass->play         = _default_play;
227         klass->play_object  = _default_play_object;
228         klass->stop         = _default_stop;
229         klass->pause        = _default_pause;
230         klass->resume       = _default_resume;
231         klass->set_position = _default_set_position;
232         klass->get_position = _default_get_position;
233
234         /* Playlist */
235
236         klass->next              = _default_next;
237         klass->previous          = _default_previous;
238         klass->goto_index        = _default_goto_index;
239
240         /* Notification metadata */
241
242         klass->notify_metadata = _default_notify_metadata;
243
244         /* Notification worker */
245
246         klass->notify_play          = _default_notify_play;
247         klass->notify_pause         = _default_notify_pause;
248         klass->notify_seek          = _default_notify_seek;
249         klass->notify_buffer_status = _default_notify_buffer_status;
250         klass->notify_eos           = _default_notify_eos;
251
252         klass->notify_eos           = _default_notify_eos;
253
254         /* Playlist editing signals */
255
256         klass->playlist_contents_changed =
257                 _default_playlist_contents_changed;
258
259         /* Property methods */
260
261         klass->get_property_value = _default_get_property_value;
262
263         /* Memory card event handlers */
264
265         klass->handle_pre_unmount = _default_handle_pre_unmount;
266 }
267
268 /*----------------------------------------------------------------------------
269   Playback
270   ----------------------------------------------------------------------------*/
271
272 void mafw_gst_renderer_state_play(MafwGstRendererState *self, GError **error)
273
274 {
275         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->play(self, error);
276 }
277
278 void mafw_gst_renderer_state_play_object(MafwGstRendererState *self,
279                                        const gchar *object_id,
280                                        GError **error)
281 {
282         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->play_object(self, object_id,
283                                                            error);
284 }
285
286 void mafw_gst_renderer_state_stop(MafwGstRendererState *self, GError **error)
287 {
288         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->stop(self, error);
289 }
290
291 void mafw_gst_renderer_state_pause(MafwGstRendererState *self, GError **error)
292 {
293         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->pause(self, error);
294 }
295
296 void mafw_gst_renderer_state_resume(MafwGstRendererState *self, GError **error)
297 {
298         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->resume(self, error);
299 }
300
301 void mafw_gst_renderer_state_set_position(MafwGstRendererState *self,
302                                          MafwRendererSeekMode mode, gint seconds,
303                                          GError **error)
304 {
305         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->set_position(self, mode, seconds,
306                                                              error);
307 }
308
309 void mafw_gst_renderer_state_get_position(MafwGstRendererState *self,
310                                           gint *seconds,
311                                           GError **error)
312 {
313         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->get_position(self, seconds, 
314                                                               error);
315 }
316
317 /*----------------------------------------------------------------------------
318   Playlist
319   ----------------------------------------------------------------------------*/
320
321 void mafw_gst_renderer_state_next(MafwGstRendererState *self, GError **error)
322 {
323         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->next(self, error);
324 }
325
326 void mafw_gst_renderer_state_previous(MafwGstRendererState *self, GError **error)
327 {
328         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->previous(self, error);
329 }
330
331 void mafw_gst_renderer_state_goto_index(MafwGstRendererState *self, guint index,
332                                       GError **error)
333 {
334         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->goto_index(self, index, error);
335
336 }
337
338 /*----------------------------------------------------------------------------
339   Notification metatada
340   ----------------------------------------------------------------------------*/
341
342 void  mafw_gst_renderer_state_notify_metadata(MafwGstRendererState *self,
343                                             const gchar *object_id,
344                                             GHashTable *metadata,
345                                             GError **error)
346 {
347         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_metadata(self, object_id,
348                                                                metadata,
349                                                                error);
350 }
351
352 /*----------------------------------------------------------------------------
353   Notification worker
354   ----------------------------------------------------------------------------*/
355
356 void mafw_gst_renderer_state_notify_play(MafwGstRendererState *self,
357                                         GError **error)
358 {
359         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_play(self, error);
360 }
361
362 void mafw_gst_renderer_state_notify_pause(MafwGstRendererState *self,
363                                         GError **error)
364 {
365         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_pause(self, error);
366 }
367
368 void mafw_gst_renderer_state_notify_seek(MafwGstRendererState *self,
369                                         GError **error)
370 {
371         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_seek(self, error);
372 }
373
374 void mafw_gst_renderer_state_notify_buffer_status(MafwGstRendererState *self,
375                                                 gdouble percent,
376                                                 GError **error)
377 {
378         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_buffer_status(self,
379                                                                     percent,
380                                                                     error);
381 }
382
383 void mafw_gst_renderer_state_notify_eos(MafwGstRendererState *self,
384                                        GError **error)
385 {
386         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->notify_eos(self, error);
387 }
388
389 /*----------------------------------------------------------------------------
390   Playlist editing handlers
391   ----------------------------------------------------------------------------*/
392
393 void mafw_gst_renderer_state_playlist_contents_changed_handler(
394         MafwGstRendererState *self,
395         gboolean clip_changed,
396         GError **error)
397 {
398         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->playlist_contents_changed(
399                 self,
400                 clip_changed,
401                 error);
402 }
403
404 /*----------------------------------------------------------------------------
405   Property methods
406   ----------------------------------------------------------------------------*/
407
408 GValue* mafw_gst_renderer_state_get_property_value(MafwGstRendererState *self,
409                                                    const gchar *name)
410 {
411         return MAFW_GST_RENDERER_STATE_GET_CLASS(self)->get_property_value(
412                 self,
413                 name);
414 }
415
416 /*----------------------------------------------------------------------------
417   Memory card event handlers
418   ----------------------------------------------------------------------------*/
419
420 void mafw_gst_renderer_state_handle_pre_unmount(MafwGstRendererState *self,
421                                                 const gchar *mount_point)
422 {
423         MAFW_GST_RENDERER_STATE_GET_CLASS(self)->
424                 handle_pre_unmount(self, mount_point);
425 }
426
427 /*----------------------------------------------------------------------------
428   Helpers
429   ----------------------------------------------------------------------------*/
430
431 void mafw_gst_renderer_state_do_play(MafwGstRendererState *self, GError **error)
432 {
433         MafwGstRenderer *renderer;
434         GError *gm_error = NULL;
435         MafwGstRendererPlaybackMode mode;
436
437         renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
438
439         /* Stop any on going playback */
440         mafw_gst_renderer_worker_stop(renderer->worker);
441
442         /* Play command only affects playlists, so switch to playlist
443            mode first if necessary */
444         mode = mafw_gst_renderer_get_playback_mode(renderer);
445         if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
446                 mafw_gst_renderer_set_playback_mode(
447                         renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
448                 mafw_gst_renderer_set_media_playlist(renderer);
449         }
450
451         /* Do we have any objectid to play? Otherwise we cannot do it */
452         if (renderer->media->object_id) {
453                 /* If so, resolve URI for this objectid */
454                 mafw_gst_renderer_get_metadata(renderer,
455                                              renderer->media->object_id,
456                                              &gm_error);
457                 if (gm_error) {
458                         MafwGstRendererErrorClosure *error_closure;
459                         if (error) {
460                                 g_set_error(error,
461                                             MAFW_RENDERER_ERROR,
462                                             MAFW_RENDERER_ERROR_NO_MEDIA,
463                                             "Unable to find media");
464                         }
465
466                         /* This is a playback error: execute error policy */
467                         error_closure = g_new0(MafwGstRendererErrorClosure, 1);
468                         error_closure->renderer = renderer;
469                         error_closure->error = g_error_copy(gm_error);
470                         g_idle_add(mafw_gst_renderer_manage_error_idle,
471                                    error_closure);
472
473                         g_error_free(gm_error);
474                 } else {
475                         mafw_gst_renderer_set_state(renderer, Transitioning);
476                 }
477         } else if (error) {
478                 g_set_error(error,
479                             MAFW_RENDERER_ERROR,
480                             MAFW_RENDERER_ERROR_NO_MEDIA,
481                             "There is no media to play");
482                 mafw_gst_renderer_set_state(renderer, Stopped);
483         }
484 }
485
486 void  mafw_gst_renderer_state_do_play_object(MafwGstRendererState *self,
487                                            const gchar *object_id,
488                                            GError **error)
489 {
490         MafwGstRenderer *renderer;
491         GError *gm_error = NULL;
492
493         renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
494
495         /* Stop any ongoing playback */
496         mafw_gst_renderer_worker_stop(renderer->worker);
497
498         if (object_id) {
499                 /* Switch to standalone mode */
500                 mafw_gst_renderer_set_playback_mode(
501                         renderer, MAFW_GST_RENDERER_MODE_STANDALONE);
502
503                 mafw_gst_renderer_set_object(renderer, object_id);
504                 mafw_gst_renderer_get_metadata(renderer,
505                                              renderer->media->object_id,
506                                              &gm_error);
507                 if (gm_error) {
508                         MafwGstRendererErrorClosure *error_closure;
509                         if (error) {
510                                 g_set_error(error,
511                                             MAFW_RENDERER_ERROR,
512                                             MAFW_RENDERER_ERROR_NO_MEDIA,
513                                             "Unable to find media");
514                         }
515
516                         /* This is a playback error: execute error policy */
517                         error_closure = g_new0(MafwGstRendererErrorClosure, 1);
518                         error_closure->renderer = renderer;
519                         error_closure->error = g_error_copy(gm_error);
520                         g_idle_add(mafw_gst_renderer_manage_error_idle,
521                                    error_closure);
522                         g_error_free(gm_error);
523                 } else {
524                         /* Play object has been successful */
525                         mafw_gst_renderer_set_state(renderer, Transitioning);
526                 }
527         } else if (error) {
528                 g_set_error(error,
529                             MAFW_RENDERER_ERROR,
530                             MAFW_RENDERER_ERROR_NO_MEDIA,
531                             "There is no media to play");
532                 mafw_gst_renderer_set_state(renderer, Stopped);
533         }
534 }
535
536 void mafw_gst_renderer_state_do_stop(MafwGstRendererState *self, GError **error)
537 {
538         MafwGstRenderer *renderer;
539         MafwGstRendererPlaybackMode mode;
540
541         renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
542
543         /* Stop any ongoing playback */
544         mafw_gst_renderer_worker_stop(renderer->worker);
545
546         /* Cancel update */
547         if (renderer->update_playcount_id > 0) {
548                 g_source_remove(renderer->update_playcount_id);
549                 renderer->update_playcount_id = 0;
550         }
551
552         /* Set new state */
553         mafw_gst_renderer_set_state(renderer, Stopped);
554
555         /* If we were playing a standalone object, then go back
556            to playlist mode and stay stopped */
557         mode = mafw_gst_renderer_get_playback_mode(renderer);
558         if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
559                 mafw_gst_renderer_set_playback_mode(
560                         renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
561                 mafw_gst_renderer_set_media_playlist(renderer);
562         }
563 }
564
565 void mafw_gst_renderer_state_do_next (MafwGstRendererState *self, GError **error)
566 {
567         MafwGstRenderer *renderer;
568         MafwGstRendererMovementResult move_type;
569         MafwGstRendererPlaybackMode mode;
570
571         renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
572
573         /* If we are in standalone mode, we switch back to playlist
574          * mode. Then we resume playback only if renderer->resume_playlist
575          * was set.
576          * If we are in playlist mode we just move to the next and
577          * play.
578          */
579         mode = mafw_gst_renderer_get_playback_mode(renderer);
580         if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
581                 mafw_gst_renderer_set_playback_mode(
582                         renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
583                 mafw_gst_renderer_set_media_playlist(renderer);
584         }
585
586         move_type = mafw_gst_renderer_move(renderer,
587                                           MAFW_GST_RENDERER_MOVE_TYPE_NEXT,
588                                           0, error);
589         switch (move_type) {
590         case MAFW_GST_RENDERER_MOVE_RESULT_OK:
591                 if (mode == MAFW_GST_RENDERER_MODE_PLAYLIST ||
592                     renderer->resume_playlist) {
593                         /* We issued the comand in playlist mode, or
594                           in standalone mode but with resume_playlist
595                           set, so let's play the new item */
596                         mafw_gst_renderer_state_play(self, error);
597
598                 } else {
599                         /* We issued the command in standalone mode and we
600                           do not want to resume playlist, so let's
601                           move to Stopped */
602                         mafw_gst_renderer_state_stop(self, NULL);
603                 }
604                 break;
605         case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
606                 g_set_error(error,
607                             MAFW_RENDERER_ERROR,
608                             MAFW_RENDERER_ERROR_NO_MEDIA,
609                             "There is no playlist or media to play");
610                 mafw_gst_renderer_state_stop(self, NULL);
611                 break;
612         case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
613                 /* Normal mode */
614                 mafw_playlist_iterator_reset(renderer->iterator, NULL);
615                 mafw_gst_renderer_set_media_playlist(renderer);
616                 mafw_gst_renderer_state_play(self, error);
617                 break;
618         case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
619                 break;
620         default:
621                 g_critical("Movement not controlled");
622         }
623 }
624
625 void mafw_gst_renderer_state_do_prev(MafwGstRendererState *self, GError **error)
626 {
627         MafwGstRenderer *renderer;
628         MafwGstRendererMovementResult move_type;
629         MafwGstRendererPlaybackMode mode;
630
631         renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
632
633         mode = mafw_gst_renderer_get_playback_mode(renderer);
634         if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
635                 mafw_gst_renderer_set_playback_mode(
636                         renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
637                 mafw_gst_renderer_set_media_playlist(renderer);
638         }
639
640         move_type = mafw_gst_renderer_move(renderer,
641                                           MAFW_GST_RENDERER_MOVE_TYPE_PREV,
642                                           0, error);
643         switch (move_type) {
644         case MAFW_GST_RENDERER_MOVE_RESULT_OK:
645                 if (mode == MAFW_GST_RENDERER_MODE_PLAYLIST ||
646                     renderer->resume_playlist) {
647                         /* We issued the comand in playlist mode, or
648                           in standalone mode but with resume_playlist
649                           set, so let's play the new item */
650                         mafw_gst_renderer_state_play(self, error);
651
652                 } else {
653                         /* We issued the command in standalone mode and we
654                           do not want to resume playlist, so let's
655                           move to Stopped */
656                         mafw_gst_renderer_state_stop(self, NULL);
657                 }
658                 break;
659         case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
660                 g_set_error(error,
661                             MAFW_RENDERER_ERROR,
662                             MAFW_RENDERER_ERROR_NO_MEDIA,
663                             "There is no playlist or media to play");
664                 mafw_gst_renderer_state_stop(self, NULL);
665                 break;
666         case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
667                 /* Normal mode */
668                 mafw_playlist_iterator_move_to_last(renderer->iterator, NULL);
669                 mafw_gst_renderer_set_media_playlist(renderer);
670                 mafw_gst_renderer_state_play(self, error);
671                 break;
672         case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
673                 break;
674         default:
675                 g_critical("Movement not controlled");
676         }
677 }
678
679
680 void mafw_gst_renderer_state_do_goto_index(MafwGstRendererState *self,
681                                          guint index,
682                                          GError **error)
683 {
684         MafwGstRenderer *renderer;
685         MafwGstRendererMovementResult move_type;
686         MafwGstRendererPlaybackMode mode;
687
688         renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
689
690         /* If we are in standalone mode, we switch back to playlist
691          * mode. Then we resume playback only if renderer->resume_playlist
692          * was set.
693          * If we are in playlist mode we just move to the next and
694          * play.
695          */
696         mode = mafw_gst_renderer_get_playback_mode(renderer);
697         if (mode == MAFW_GST_RENDERER_MODE_STANDALONE) {
698                 mafw_gst_renderer_set_playback_mode(
699                         renderer, MAFW_GST_RENDERER_MODE_PLAYLIST);
700                 mafw_gst_renderer_set_media_playlist(renderer);
701         }
702
703         move_type = mafw_gst_renderer_move(renderer, MAFW_GST_RENDERER_MOVE_TYPE_INDEX, index, error);
704
705         switch (move_type) {
706         case MAFW_GST_RENDERER_MOVE_RESULT_OK:
707                 if (mode == MAFW_GST_RENDERER_MODE_PLAYLIST ||
708                     renderer->resume_playlist) {
709                         /* We issued the comand in playlist mode, or
710                           in standalone mode but with resume_playlist
711                           set, so let's play the new item */
712                         mafw_gst_renderer_state_play(self, error);
713
714                 } else {
715                         /* We issued the command in standalone mode and we
716                           do not want to resume playlist, so let's
717                           move to Stopped */
718                         mafw_gst_renderer_state_stop(self, NULL);
719                 }
720                 break;
721         case MAFW_GST_RENDERER_MOVE_RESULT_NO_PLAYLIST:
722                 g_set_error(error,
723                             MAFW_RENDERER_ERROR,
724                             MAFW_RENDERER_ERROR_NO_MEDIA,
725                             "There is no playlist or media to play");
726                 mafw_gst_renderer_state_stop(self, NULL);
727                 break;
728         case MAFW_GST_RENDERER_MOVE_RESULT_PLAYLIST_LIMIT:
729                 g_set_error(error,
730                             MAFW_RENDERER_ERROR,
731                             MAFW_RENDERER_ERROR_INDEX_OUT_OF_BOUNDS,
732                             "Index is out of bounds");
733                 mafw_gst_renderer_state_stop(self, NULL);
734                 break;
735         case MAFW_GST_RENDERER_MOVE_RESULT_ERROR:
736                 break;
737         default:
738                 g_critical("Movement not controlled");
739         }
740 }
741
742 void mafw_gst_renderer_state_do_get_position(MafwGstRendererState *self,
743                                             gint *seconds,
744                                             GError **error)
745 {
746         *seconds = mafw_gst_renderer_worker_get_position(self->renderer->worker);
747         if (*seconds < 0) {
748                 *seconds = 0;
749                 g_set_error(error, MAFW_EXTENSION_ERROR, 
750                             MAFW_RENDERER_ERROR_CANNOT_GET_POSITION,
751                             "Position query failed");
752         }
753 }
754
755 void mafw_gst_renderer_state_do_set_position(MafwGstRendererState *self,
756                                             MafwRendererSeekMode mode,
757                                             gint seconds,
758                                             GError **error)
759 {
760         MafwGstRenderer *renderer;
761         GstSeekType seektype;
762
763         renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
764
765         /* TODO Gst stuff should be moved to worker, not handled here... */
766         if (mode == SeekAbsolute) {
767                 if (seconds < 0) {
768                         seektype = GST_SEEK_TYPE_END;
769                         seconds *= -1;
770                 } else {
771                         seektype = GST_SEEK_TYPE_SET;
772                 }
773         } else if (mode == SeekRelative) {
774                 seektype = GST_SEEK_TYPE_CUR;
775         } else {
776                 g_critical("Unknown seek mode: %d", mode);
777                 g_set_error(error, MAFW_EXTENSION_ERROR,
778                             MAFW_EXTENSION_ERROR_INVALID_PARAMS,
779                             "Unknown seek mode: %d", mode);
780                 return;
781         }
782         if (renderer->seek_pending) {
783                 g_debug("seek pending, storing position %d", seconds);
784                 renderer->seek_type_pending = seektype;
785                 renderer->seeking_to = seconds;
786         } else {
787                 renderer->seek_pending = TRUE;
788                 mafw_gst_renderer_worker_set_position(renderer->worker,
789                                                      seektype,
790                                                      seconds,
791                                                      error);
792         }
793 }
794
795 void mafw_gst_renderer_state_do_notify_seek(MafwGstRendererState *self,
796                                            GError **error)
797 {
798         MafwGstRenderer *renderer;
799
800         renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
801
802         if (renderer->seeking_to != -1) {
803                 renderer->seek_pending = TRUE;
804                 mafw_gst_renderer_worker_set_position(renderer->worker,
805                                                     renderer->seek_type_pending,
806                                                     renderer->seeking_to,
807                                                     NULL);
808         } else {
809                 renderer->seek_pending = FALSE;
810         }
811         renderer->seeking_to = -1;
812 }
813
814 void mafw_gst_renderer_state_do_notify_buffer_status(MafwGstRendererState *self,
815                                                     gdouble percent,
816                                                     GError **error)
817 {
818         MafwGstRenderer *renderer = NULL;
819
820         g_return_if_fail(MAFW_IS_GST_RENDERER_STATE(self));
821
822         renderer = MAFW_GST_RENDERER_STATE(self)->renderer;
823
824         mafw_renderer_emit_buffering_info(MAFW_RENDERER(renderer), percent / 100.0);
825 }