2 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 * @brief EailVideo implementation
23 #include <Elementary.h>
27 #include "eail_video.h"
28 #include "eail_utils.h"
29 #include "eail_priv.h"
31 static void atk_action_interface_init(AtkActionIface *iface);
32 static void atk_stremable_content_iface_init(AtkStreamableContentIface *iface);
35 * @brief Define EailVideo type
37 G_DEFINE_TYPE_WITH_CODE(EailVideo, eail_video, EAIL_TYPE_WIDGET,
38 G_IMPLEMENT_INTERFACE(ATK_TYPE_ACTION,
39 atk_action_interface_init)
40 G_IMPLEMENT_INTERFACE(ATK_TYPE_STREAMABLE_CONTENT,
41 atk_stremable_content_iface_init)
45 * @brief Gets a reference to the state set of the accessible
47 * The caller must unreference it when it is no longer needed.
49 * Implementation of ref_state_set from AtkObject.
51 * @param object AtkObject instance
53 * @returns AtkStateSet representing the state set of the accessible
56 eail_video_ref_state_set(AtkObject *object)
58 AtkStateSet *state_set;
61 g_return_val_if_fail(EAIL_IS_VIDEO(object), NULL);
62 widget = eail_widget_get_widget(EAIL_WIDGET(object));
63 if (!widget) return NULL;
65 state_set = ATK_OBJECT_CLASS(eail_video_parent_class)->ref_state_set(object);
66 atk_state_set_add_state(state_set, ATK_STATE_ANIMATED);
72 * @brief Gets the accessible name of the accessible
74 * Implementation of get_name from AtkObject.
76 * @param object AtkObject instance
78 * @returns string representing the title of played video file
79 * or NULL if name is not set
82 eail_video_name_get(AtkObject *object)
85 const gchar *atk_name;
87 g_return_val_if_fail(EAIL_IS_VIDEO(object), NULL);
89 atk_name = ATK_OBJECT_CLASS(eail_video_parent_class)->get_name(object);
90 if (atk_name) return atk_name;
92 video = eail_widget_get_widget(EAIL_WIDGET(object));
93 if (!video) return NULL;
95 return elm_video_title_get(video);
99 * @brief Initializes EailVideo object
101 * @param object AtkObject instance
102 * @param data passed user data
105 eail_video_initialize(AtkObject *object, gpointer data)
107 ATK_OBJECT_CLASS(eail_video_parent_class)->initialize(object, data);
109 object->role = ATK_ROLE_ANIMATION;
113 * @brief Initiates EailVideo object
115 * @param video EailVideo instance
118 eail_video_init(EailVideo *video)
120 video->forward_desc = NULL;
121 video->next_desc = NULL;
122 video->pause_desc = NULL;
123 video->play_desc = NULL;
124 video->prev_desc = NULL;
125 video->rewind_desc = NULL;
126 video->stop_desc = NULL;
131 * @brief Finalizes EailVideo object
133 * @param object EailVideo instance
136 eail_video_finalize(GObject *object)
138 EailVideo *video = EAIL_VIDEO(object);
140 if (video->forward_desc) free(video->forward_desc);
141 if (video->next_desc) free(video->next_desc);
142 if (video->pause_desc) free(video->pause_desc);
143 if (video->play_desc) free(video->play_desc);
144 if (video->rewind_desc) free(video->rewind_desc);
145 if (video->stop_desc) free(video->stop_desc);
146 if (video->uri) free(video->uri);
148 G_OBJECT_CLASS(eail_video_parent_class)->finalize(object);
152 * @brief Initializes EailVideo class
154 * @param klass EailVideoClass instance
157 eail_video_class_init(EailVideoClass *klass)
159 AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
160 GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
162 atk_class->initialize = eail_video_initialize;
163 atk_class->get_name = eail_video_name_get;
164 atk_class->ref_state_set = eail_video_ref_state_set;
166 g_object_class->finalize = eail_video_finalize;
170 * @brief Gets the name of the specified action of the object
172 * Implementation of get_action_name from AtkAction interface.
174 * @param action AtkAction instance
175 * @param i action index
177 * @returns string representing the name of the specified action
180 eail_video_action_name_get(AtkAction *action, gint i)
182 const gchar *action_name;
183 g_return_val_if_fail(EAIL_IS_VIDEO(action), NULL);
188 /*"forward,clicked" - the user clicked the forward button.*/
189 action_name = "forward";
192 /*"next,clicked" - the user clicked the next button.*/
193 action_name = "next";
196 /*"pause,clicked" - the user clicked the pause button.*/
197 action_name = "pause";
200 /*"play,clicked" - the user clicked the play button.*/
201 action_name = "play";
204 /*"prev,clicked" - the user clicked the prev button*/
205 action_name = "prev";
208 /*"rewind,clicked" - the user clicked the rewind button.*/
209 action_name = "rewind";
212 /*"stop,clicked" - the user clicked the stop button.*/
213 action_name = "stop";
224 * @brief Gets the number of accessible actions available on the object
226 * If there are more than one, the first one is considered
227 * the "default" action of the object.
229 * Implementation of get_n_actions from AtkAction interface.
231 * @param action AtkAction instance
233 * @returns integer representing the number of actions
234 * supported by EailVideo object
237 eail_video_n_actions_get(AtkAction *action)
243 * @brief Performs the specified action on the object
245 * Implementation of do_action from AtkAction interface.
247 * @param action AtkAction instance
248 * @param i action index
250 * @returns TRUE on success, FALSE otherwise
253 eail_video_do_action(AtkAction *action, gint i)
256 gboolean result, playing, seekable;
257 double position, length;
259 g_return_val_if_fail(EAIL_IS_VIDEO(action), FALSE);
261 video = eail_widget_get_widget(EAIL_WIDGET(action));
262 if (!video) return FALSE;
263 if ((elm_object_disabled_get(video)) || (!evas_object_visible_get(video)))
266 playing = elm_video_is_playing_get(video);
267 seekable = elm_video_is_seekable_get(video);
268 length = elm_video_play_length_get(video);
269 position = elm_video_play_position_get(video);
279 position += length * 0.3;
280 elm_video_play_position_set(video, position);
282 (ATK_OBJECT(action), "visible-data-changed", ATK_TYPE_OBJECT);
291 position += length * 0.1;
292 elm_video_play_position_set(video, position);
294 (ATK_OBJECT(action), "visible-data-changed", ATK_TYPE_OBJECT);
303 elm_video_pause(video);
312 elm_video_play(video);
314 (ATK_OBJECT(action), "visible-data-changed", ATK_TYPE_OBJECT);
323 position -= length * 0.1;
324 elm_video_play_position_set(video, position);
326 (ATK_OBJECT(action), "visible-data-changed", ATK_TYPE_OBJECT);
335 elm_video_play_position_set(video, 0);
337 (ATK_OBJECT(action), "visible-data-changed", ATK_TYPE_OBJECT);
341 elm_video_stop(video);
342 elm_video_play_position_set(video, 0);
344 (ATK_OBJECT(action), "visible-data-changed", ATK_TYPE_OBJECT);
357 * @brief Gets the description of the specified action of the object
359 * Implementation of get_description from AtkAction interface.
361 * @param action AtkAction instance
362 * @param i action index
364 * @returns string representing the description of the specified action
367 eail_video_description_get(AtkAction *action, gint i)
369 const gchar *action_description;
372 g_return_val_if_fail(EAIL_IS_VIDEO(action), NULL);
373 video = EAIL_VIDEO(action);
378 action_description = video->forward_desc;
381 action_description = video->next_desc;
384 action_description = video->pause_desc;
387 action_description = video->play_desc;
390 action_description = video->prev_desc;
393 action_description = video->rewind_desc;
396 action_description = video->stop_desc;
399 action_description = NULL;
403 return action_description;
407 * @brief Sets a description of the specified action of the object
409 * Implementation of set_description from AtkAction interface.
411 * @param action AtkAction instance
412 * @param i action index
413 * @param description action descritpion
415 * @returns TRUE on success, FALSE otherwise
418 eail_video_description_set(AtkAction *action, gint i, const char *description)
423 g_return_val_if_fail(EAIL_IS_VIDEO(action), FALSE);
424 video = EAIL_VIDEO(action);
428 value = &video->forward_desc;
431 value = &video->next_desc;
434 value = &video->pause_desc;
437 value = &video->play_desc;
440 value = &video->prev_desc;
443 value = &video->rewind_desc;
446 value = &video->stop_desc;
455 *value = g_strdup(description);
462 * @brief AtkAction interface initializer
464 * Function called upon instance creation. It initializes AtkAction
465 * interface implementation i.e hooks method pointers in the interface structure
466 * to the implementing class's implementation.
468 * @param iface AtkActionIface instance
471 atk_action_interface_init(AtkActionIface *iface)
473 g_return_if_fail(iface != NULL);
475 iface->do_action = eail_video_do_action;
476 iface->get_n_actions = eail_video_n_actions_get;
477 iface->get_name = eail_video_action_name_get;
478 iface->get_description = eail_video_description_get;
479 iface->set_description = eail_video_description_set;
483 * @brief Helper function for matching file extension with a mime type
485 * @param ext file extension
487 * @returns string representing the mime type
490 _match_mime_type(const char *ext)
492 if (!strcmp(ext, ".264"))
494 if (!strcmp(ext, ".3g2"))
495 return "video/3gpp2";
496 if (!strcmp(ext, ".3gp"))
498 if (!strcmp(ext, ".asf"))
499 return "video/x-ms-asf";
500 if (!strcmp(ext, ".avi"))
501 return "video/x-msvideo";
502 if (!strcmp(ext, ".clp"))
503 return "application/x-msclip";
504 if (!strcmp(ext, "flv"))
505 return "video/x-flv";
506 if (!strcmp(ext, ".m4v"))
507 return "video/x-m4v";
508 if (!strcmp(ext, ".mkv"))
509 return "video/x-matroska";
510 if (!strcmp(ext, ".mov"))
511 return "video/quicktime";
512 if (!strcmp(ext, ".mp2"))
514 if (!strcmp(ext, ".mp4"))
516 if (!strcmp(ext, ".mpe"))
518 if (!strcmp(ext, ".mpeg"))
520 if (!strcmp(ext, ".mpg"))
522 if (!strcmp(ext, ".mts"))
523 return "model/vnd.mts";
524 if (!strcmp(ext, ".mxf"))
525 return "application/mxf";
526 if (!strcmp(ext, ".ogg"))
528 if (!strcmp(ext, ".ogv"))
530 if (!strcmp(ext, ".rm"))
531 return "audio/x-pn-realaudio";
532 if (!strcmp(ext, ".swf"))
533 return "application/x-shockwave-flash";
534 if (!strcmp(ext, ".ts"))
536 if (!strcmp(ext, ".weba"))
538 if (!strcmp(ext, ".webm"))
540 if (!strcmp(ext, ".wmv"))
541 return "video/x-ms-wmv";
547 * @brief Helper function for getting extension from a filename
549 * @param filename target filename
551 * @returns string representing the file extension
554 _get_file_ext(const char *filename) {
555 const char *ext = strrchr(filename, '.');
562 * @brief Helper function for getting the video's file path
564 * @param widget Evas_Object instance
566 * @returns string representing the path to video file
569 _get_video_path(const Evas_Object *widget)
571 Evas_Object *emotion;
573 emotion = elm_video_emotion_get(widget);
575 return emotion_object_file_get(emotion);
579 * @brief Gets the character string of the specified mime type
581 * The first mime type is at position 0, the second at position 1, and so on.
583 * Implementation of get_mime_type from AtkStreamableContent interface.
585 * @param streamable AtkStreamableContent instance
586 * @param i index of supported mime type
588 * @returns string representing the specified mime type
591 eail_video_mime_type_get(AtkStreamableContent *streamable, gint i)
594 const char *path, *ext;
596 g_return_val_if_fail(EAIL_IS_VIDEO(streamable), NULL);
597 if (i != 0) return NULL;
599 widget = eail_widget_get_widget(EAIL_WIDGET(streamable));
600 path = _get_video_path(widget);
601 ext = _get_file_ext(path);
603 return _match_mime_type(ext);
607 * @brief Gets the number of mime types supported by this object
609 * For video widget implementation by ATK-EAIL, there will always be maximum one
610 * supported content type at a time for the given file,
611 * so this function will always return 1 or 0.
613 * Implementation of get_n_mime_types from AtkStreamableContent interface.
615 * @param streamable AtkStreamableContent instance
617 * @returns integer representing the number of mime-types for the given
618 * streamable content ('0' in case when no mime-type was matched for content file)
621 eail_video_n_mime_types_get(AtkStreamableContent *streamable)
623 const gchar *mime_type = NULL;
625 mime_type = eail_video_mime_type_get(streamable, 0);
626 if (mime_type) return 1;
628 /* no mime type for content*/
633 * @brief Gets a string representing an URI
635 * Gets a string representing a URI in IETF standard format
636 * (see http://www.ietf.org/rfc/rfc2396.txt) from which the object's
637 * content may be streamed in the specified mime-type, if one is available.
638 * If mime_type is NULL, the URI for the default (and possibly only)
639 * mime-type is returned.
641 * Implementation of get_uri from AtkStreamableContent.
643 * @param streamable AtkStreamableContent instance
644 * @param mime_type requested mime type
646 * @returns string representing the video file's URI
649 eail_video_get_uri(AtkStreamableContent *streamable, const gchar *mime_type)
653 const char *mime, *path;
656 g_return_val_if_fail(EAIL_IS_VIDEO(streamable), NULL);
658 widget = eail_widget_get_widget(EAIL_WIDGET(streamable));
659 video = EAIL_VIDEO(streamable);
660 mime = eail_video_mime_type_get(streamable, 0);
661 if ((mime) && (mime_type) && (strcmp(mime, mime_type))) return NULL;
663 path = _get_video_path(widget);
664 file = g_file_new_for_path(path);
665 if (video->uri) free(video->uri);
666 video->uri = g_file_get_uri(file);
667 g_object_unref(file);
673 * @brief Gets the content in the specified mime type
675 * Implementation of get_stream from AtkStreamableContent.
677 * @param streamable AtkStreamableContent instance
678 * @param mime_type requested mime type
680 * @returns GIOChannel to video file
683 eail_video_get_stream(AtkStreamableContent *streamable,
684 const gchar *mime_type)
689 const char *path, *mime;
691 g_return_val_if_fail(EAIL_IS_VIDEO(streamable), NULL);
693 widget = eail_widget_get_widget(EAIL_WIDGET(streamable));
694 mime = eail_video_mime_type_get(streamable, 0);
695 if ((mime) && (strcmp(mime, mime_type))) return NULL;
696 path = _get_video_path(widget);
699 channel = g_io_channel_new_file(path, "r", &error);
702 WRN("cannot open GIOChannel %s", error->message);
709 * @brief Initializes AtkStreamableContent interface
711 * @param iface EailVideo instance
714 atk_stremable_content_iface_init(AtkStreamableContentIface *iface)
716 g_return_if_fail(iface != NULL);
718 iface->get_n_mime_types = eail_video_n_mime_types_get;
719 iface->get_mime_type = eail_video_mime_type_get;
720 iface->get_stream = eail_video_get_stream;
721 iface->get_uri = eail_video_get_uri;