int player_enable_media_packet_video_frame_decoded_cb(player_h player, bool enable);
/**
- * @brief Enables 360 video mode
+ * @brief Enables/disables 360 video mode.
* @since_tizen 4.0
* @details If it is @c true, the content will be displayed with 360 video mode.
* If it is @c false, the content will be displayed with full panorama mode. The default value is @c true.
* @param[in] player The handle to the media player
- * @param[in] enable The 360 video display status : (@c true = display with 360 video mode, @c false = display with full panorama mode)
+ * @param[in] enable The 360 video display status: @c true = display with 360 video mode,
+ @c false = display with full panorama mode
* @return @c 0 on success,
* otherwise a negative error value
* @retval #PLAYER_ERROR_NONE Successful
* @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
- * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED.
+ * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media
+ * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared
+ * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED.
* @see player_360_is_enabled()
- * @see player_360_set_direction_of_view()
*/
int player_360_set_enable(player_h player, bool enable);
* @brief Gets the 360 video display status.
* @since_tizen 4.0
* @param[in] player The handle to the media player
- * @param[out] enabled The 360 video display status : (@c true = display with 360 video mode, @c false = display with full panorama mode)
+ * @param[out] enabled Pointer to store current 360 video display status:
+ * (@c true = display with 360 video mode,
+ @c false = display with full panorama mode)
* @return @c 0 on success,
* otherwise a negative error value
* @retval #PLAYER_ERROR_NONE Successful
* @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
- * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state
- * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED.
+ * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media
+ * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared
+ * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED.
* @see player_360_set_enable()
*/
int player_360_is_enabled(player_h player, bool *enabled);
/**
* @brief Sets the 360 video direction of view.
* @since_tizen 4.0
- * @details This function is to set the vertical and lateral axis value.
+ * @details This function is to set horizontal (yaw) and vertical (pitch) angles
+ * of current direction of view in radians. Default direction of view
+ * is taken from meta-data stored in the media. If meta-data omits
+ * these values zeros are assumed that is equal to the centre of the
+ * panorama image.
* @param[in] player The handle to the media player
- * @param[in] yaw The vertical axis value
- * @param[in] pitch The lateral axis value
+ * @param[in] yaw The angle value around vertical axis. Valid values are in
+ * range +/- PI.
+ * @param[in] pitch The angle value around lateral axis. Valid values are in
+ * range +/- PI/2.
* @return @c 0 on success,
* otherwise a negative error value
- * @retval #PLAYER_ERROR_NONE Successful
- * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
- * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state
- * @pre The player state must be one of: #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED.
- * @see player_is_audio_only()
+ * @retval #PLAYER_ERROR_NONE Successful
+ * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media
+ * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared
+ * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED.
+ * @see player_360_get_direction_of_view()
*/
int player_360_set_direction_of_view(player_h player, float yaw, float pitch);
/**
* @brief Gets the 360 video direction of view.
* @since_tizen 4.0
- * @details This function is to get the vertical and lateral axis value.
+ * @details This function is to get horizontal (yaw) and vertical (pitch) angles
+ * of current direction of view in radians.
* @param[in] player The handle to the media player
- * @param[out] yaw The vertical axis value
- * @param[out] pitch The lateral axis value
+ * @param[out] yaw Pointer to store current value of direction of view
+ * angle around vertical axis
+ * @param[out] pitch Pointer to store current value of direction of view
+ * angle around lateral axis
* @return @c 0 on success,
* otherwise a negative error value
- * @retval #PLAYER_ERROR_NONE Successful
- * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
- * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state
- * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED.
- * @see player_is_audio_only()
+ * @retval #PLAYER_ERROR_NONE Successful
+ * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media
+ * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared
+ * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED.
+ * @see player_360_set_direction_of_view()
*/
int player_360_get_direction_of_view(player_h player, float *yaw, float *pitch);
* @brief Sets the zoom level of 360 video.
* @since_tizen 4.0
* @details The zoom means scaling of the flat image cutted from the panorama.
- * The valid range is from [TBD]. Default value is 1.0.
+ * The valid range is from 1.0 to 10.0. Where 1.0 is actual image and
+ * values above are zoom-in factor. Default value is 1.0 - no zoom.
* @param[in] player The handle to the media player
* @param[in] level The zoom level
* @return @c 0 on success,
* otherwise a negative error value
- * @retval #PLAYER_ERROR_NONE Successful
- * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
- * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state
- * @pre The player state must be one of #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED.
+ * @retval #PLAYER_ERROR_NONE Successful
+ * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media
+ * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared
+ * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED.
* @see player_360_get_zoom()
*/
int player_360_set_zoom(player_h player, float level);
* @brief Gets the current zoom level of 360 video.
* @since_tizen 4.0
* @details The zoom means scaling of the flat image cutted from the panorama.
- * The valid range is from [TBD]. Default value is 1.0.
+ * The valid range is from 1.0 to 10.0. Where 1.0 is actual image and
+ * values above are zoom-in factor. Default value is 1.0 - no zoom.
* @param[in] player The handle to the media player
- * @param[out] level The zoom level
+ * @param[out] level Pointer to store current value of zoom level
* @return @c 0 on success,
* otherwise a negative error value
- * @retval #PLAYER_ERROR_NONE Successful
- * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
- * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state
- * @pre The player state must be one of #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED.
+ * @retval #PLAYER_ERROR_NONE Successful
+ * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media
+ * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared
+ * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED.
* @see player_360_set_zoom()
*/
int player_360_get_zoom(player_h player, float *level);
* @brief Sets the field of view information of 360 video.
* @since_tizen 4.0
* @details This function is to set the field of view to decide the output frame size.
+ * Note: values above the default ones extends field of view to significantly
+ * distorted areas and thus don't make real sense.
* @param[in] player The handle to the media player
- * @param[in] horizontal_degrees The horizontal degrees to display (The default value is [TBD])
- * @param[in] vertical_degrees The vertical degrees to display (The default value is [TBD])
+ * @param[in] horizontal_degrees The horizontal field of view to display in degrees.
+ * Valid range is 1-360 degrees. Default value is 120 degrees.
+ * @param[in] vertical_degrees The vertical field of view to display in degrees.
+ * Valid range is 1-180 degrees. Default value is 67 degrees.
* @return @c 0 on success,
* otherwise a negative error value
- * @retval #PLAYER_ERROR_NONE Successful
- * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
- * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state
- * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED.
+ * @retval #PLAYER_ERROR_NONE Successful
+ * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media
+ * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared
+ * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED.
* @see player_360_get_field_of_view()
*/
int player_360_set_field_of_view(player_h player, int horizontal_degrees, int vertical_degrees);
* @since_tizen 4.0
* @details This function is to get the field of view information.
* @param[in] player The handle to the media player
- * @param[out] horizontal_degrees The horizontal degrees to display (The default value is [TBD])
- * @param[out] vertical_degrees The vertical degrees to display (The default value is [TBD])
+ * @param[out] horizontal_degrees Pointer to store current value of horizontal
+ * field of view to display in degrees.
+ * @param[out] vertical_degrees Pointer to store current value of vertical
+ * field of view to display in degrees.
* @return @c 0 on success,
* otherwise a negative error value
- * @retval #PLAYER_ERROR_NONE Successful
- * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #PLAYER_ERROR_INVALID_OPERATION Invalid operation
- * @retval #PLAYER_ERROR_INVALID_STATE Invalid player state
- * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING, or #PLAYER_STATE_PAUSED.
+ * @retval #PLAYER_ERROR_NONE Successful
+ * @retval #PLAYER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #PLAYER_ERROR_INVALID_OPERATION Not a spherical media
+ * @retval #PLAYER_ERROR_INVALID_STATE Player isn't prepared
+ * @pre The player state must be one of #PLAYER_STATE_IDLE, #PLAYER_STATE_READY, #PLAYER_STATE_PLAYING or #PLAYER_STATE_PAUSED.
* @see player_360_set_field_of_view()
*/
int player_360_get_field_of_view(player_h player, int *horizontal_degrees, int *vertical_degrees);
BuildRequires: pkgconfig(eom)
BuildRequires: pkgconfig(storage)
BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(libinput)
%if "%{TIZEN_PRODUCT_TV}" != "1"
BuildRequires: pkgconfig(mm-evas-renderer)
%endif
%{_bindir}/player_media_packet_test
%{_bindir}/player_es_push_test
%{_bindir}/player_audio_test
+%{_libdir}/libmm-navevent-handler.so*
INCLUDE_DIRECTORIES(../include/common)
ENDIF (TIZEN_WEARABLE)
+INCLUDE_DIRECTORIES(event-handler/include)
link_directories(${CMAKE_SOURCE_DIR}/../)
SET(WIN_PKG "${WIN_PKG} ecore-wayland")
INCLUDE(FindPkgConfig)
-pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary ecore evas capi-media-sound-manager ${WIN_PKG})
+pkg_check_modules(${fw_test} REQUIRED libudev libinput capi-system-info appcore-efl elementary ecore evas capi-media-sound-manager ${WIN_PKG})
FOREACH(flag ${${fw_test}_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
ENDFOREACH(flag)
GET_FILENAME_COMPONENT(src_name ${src} NAME_WE)
MESSAGE("${src_name}")
ADD_EXECUTABLE(${src_name} ${src})
- TARGET_LINK_LIBRARIES(${src_name} capi-media-player ${${fw_test}_LDFLAGS})
+ TARGET_LINK_LIBRARIES(${src_name} capi-media-player mm-navevent-handler ${${fw_test}_LDFLAGS})
INSTALL(TARGETS ${src_name} DESTINATION bin)
ENDFOREACH()
+ADD_SUBDIRECTORY(event-handler)
--- /dev/null
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(fw_handler "mm-navevent-handler")
+
+PROJECT(${fw_handler})
+
+SET(dependents "dlog libudev libinput capi-system-info")
+SET(pc_dependents "libudev libinput capi-system-info")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_handler} REQUIRED ${dependents})
+FOREACH(flag ${${fw_handler}_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+AUX_SOURCE_DIRECTORY (./src HANDLER_SRC)
+ADD_LIBRARY(${fw_handler} SHARED ${HANDLER_SRC})
+
+SET_TARGET_PROPERTIES(${fw_handler}
+ PROPERTIES
+ VERSION ${FULLVER}
+ SOVERSION ${MAJORVER}
+ CLEAN_DIRECT_OUTPUT 1
+)
+
+INSTALL(TARGETS ${fw_handler} DESTINATION ${LIB_INSTALL_DIR})
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * @author: Volodymyr Brynza <v dot brynza at samsung dot com>
+ * Andriy Martynets <a dot martynets at partner dot samsung dot com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MM_NAVEVENT_HANDLER__
+#define __MM_NAVEVENT_HANDLER__
+
+#include <tizen.h>
+#include <libinput.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file mm_navevent_handler.h
+ * @brief Navigation event handler handle type.
+ *
+ * @since_tizen 3.0
+ */
+typedef void *mm_navevent_handler_h;
+
+/**
+ * @brief Convenience type for screen/window sizes representation.
+ *
+ * @since_tizen 3.0
+ */
+typedef struct {
+ int width;
+ int height;
+} mm_navevent_handler_size_s;
+
+/**
+ * @brief Enumeration of window orientation relatively to screen
+ * counter-clockwise for event handling. Valid values of this enum
+ * complies with corresponding enumeration of walandsink's rotate
+ * property.
+ *
+ * @since_tizen 3.0
+ */
+typedef enum {
+ MM_NAVEVENT_HANDLER_ORIENTATION_INVALID = -1,
+ MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_0 = 0,
+ MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_90 = 1,
+ MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_180 = 2,
+ MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_270 = 3,
+ MM_NAVEVENT_HANDLER_ORIENTATION_MAX,
+} mm_navevent_handler_orientation_e;
+
+/**
+ * @brief Constants for default values of Field-Of-View angles in degrees.
+ * @details Human eye horizontal stereoscopic FOV is 120 degrees.
+ * With image aspect ratio of 16:9 vertical FOV is roughly 68 degrees.
+ * @since_tizen 3.0
+ */
+#define MM_NAVEVENT_HANDLER_DEFAULT_HORIZONTAL_FOV_DEGREE 120
+#define MM_NAVEVENT_HANDLER_DEFAULT_VERTICAL_FOV_DEGREE 68
+
+/**
+ * @brief Enumeration of device for event handling.
+ * @remarks Note that available device types can differ depending
+ * on platform. #MM_NAVEVENT_HANDLER_DEVICE_TYPE_INVALID and
+ * #MM_NAVEVENT_HANDLER_DEVICE_TYPE_MAX are invalid device types.
+ * @since_tizen 3.0
+ */
+typedef enum {
+ MM_NAVEVENT_HANDLER_DEVICE_TYPE_INVALID = -1,
+ MM_NAVEVENT_HANDLER_DEVICE_TYPE_TOUCH,
+ MM_NAVEVENT_HANDLER_DEVICE_TYPE_MAX,
+} mm_navevent_handler_device_type_e;
+
+/**
+ * @brief Enumeration for navigation event handler error.
+ *
+ * @since_tizen 3.0
+ */
+typedef enum {
+ MM_NAVEVENT_HANDLER_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+ MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+ MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */
+ MM_NAVEVENT_HANDLER_ERROR_FILE_NO_SPACE_ON_DEVICE = TIZEN_ERROR_FILE_NO_SPACE_ON_DEVICE, /**< No space left on the device */
+ MM_NAVEVENT_HANDLER_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< The feature is not supported */
+ MM_NAVEVENT_HANDLER_ERROR_INVALID_STATE, /**< Invalid state */
+} mm_navenvent_handler_error_e;
+
+/**
+ * @brief Called after processing each input event.
+ * @since_tizen 3.0
+ * @param [in] ev_t Type of the libinput event
+ * @param [in] x Value of pointer horizontal position in screen
+ * coordinates
+ * @param [in] y Value of pointer vertical position in screen coordinates
+ * @param [in] data The user data passed from the code where
+ * mm_navevent_handler_set_cb() was invoked
+ * This data will be accessible from mm_navevent_handler_cb
+ * @param [in] e Euler angles (XYZ configuration)
+ * @remarks @a Pointer coordinates are passed as screen coordinates regardless
+ * given application window size and orientation
+ * @pre @a handle must be created by calling mm_navevent_handler_create()
+ * @see mm_navevent_handler_set_cb()
+ * @see mm_navevent_handler_unset_cb()
+ */
+typedef void (*mm_navevent_handler_cb) (enum libinput_event_type ev_t, int x, int y, void* data, float e[3]);
+
+/**
+ * @brief Creates an instance of navigation event handler and
+ * passes the handle to the caller.
+ * @since_tizen 3.0
+ * @remarks @a handle must be released by calling mm_navevent_handler_destroy()
+ * @param [out] handle Event handler handle
+ * @param [in] device Device type
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_STATE Invalid state
+ * @see mm_navevent_handler_destroy()
+ * @see mm_navevent_handler_device_type_e
+ */
+int mm_navevent_handler_create(mm_navevent_handler_h *handle, mm_navevent_handler_device_type_e device);
+
+/**
+ * @brief Destroys event handler.
+ * @since_tizen 3.0
+ * @param [in] handle Event handler handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION Invalid operation
+ * @pre @a handle must be created by calling mm_navevent_handler_create()
+ * @see mm_navevent_handler_create()
+ */
+int mm_navevent_handler_destroy(mm_navevent_handler_h handle);
+
+/**
+ * @brief Sets navigation event callback.
+ * @since_tizen 3.0
+ * @param [in] handle Event handler handle
+ * @param [in] cb Navigation event callback
+ * @param [in] data Data that will be passed to callback
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a handle must be created by calling mm_navevent_handler_create()
+ * @see mm_navevent_handler_create()
+ */
+int mm_navevent_handler_set_cb(mm_navevent_handler_h handle, mm_navevent_handler_cb cb, void *data);
+
+/**
+ * @brief Unsets navigation event callback.
+ * @since_tizen 3.0
+ * @param [in] handle Event handler handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a handle must be created by calling mm_navevent_handler_create()
+ * @see mm_navevent_handler_create()
+ */
+int mm_navevent_handler_unset_cb(mm_navevent_handler_h handle);
+
+/**
+ * @brief Sets application window orientation and size.
+ * @details Window size defines the step of FOV degrees. Window orientation
+ * defines x and y coordinates exchange and coordinates
+ * increment/decrement direction.
+ * @since_tizen 3.0
+ * @param [in] handle Event handler handle
+ * @param [in] wo Window orientation
+ * @param [in] ws Window size
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a handle must be created by calling mm_navevent_handler_create()
+ * @see mm_navevent_handler_create()
+ */
+int mm_navevent_handler_set_window_parameters(mm_navevent_handler_h handle, mm_navevent_handler_orientation_e wo, mm_navevent_handler_size_s ws);
+
+/**
+ * @brief Sets Field-Of-View size in degrees.
+ * @details Field-Of-View size defines scale factor from pixels to angles.
+ * @since_tizen 3.0
+ * @param [in] handle Event handler handle
+ * @param [in] fovs Field-Of-View size in degrees
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a handle must be created by calling mm_navevent_handler_create()
+ * @see mm_navevent_handler_create()
+ */
+int mm_navevent_handler_set_fov_size(mm_navevent_handler_h handle, mm_navevent_handler_size_s fovs);
+
+/**
+ * @brief Returns screen size in pixels.
+ * @details Provides application with screen size information.
+ * @since_tizen 3.0
+ * @param [in] handle Event handler handle
+ * @param [in] size Pointer to where the size to store
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a handle must be created by calling mm_navevent_handler_create()
+ * @see mm_navevent_handler_create()
+ */
+int mm_navevent_handler_get_screen_size(mm_navevent_handler_h handle, mm_navevent_handler_size_s *size);
+
+/**
+ * @brief Sets direction of view angles (yaw, pitch and roll) in radians.
+ * @details Subsequent navigation events modify these values.
+ * @since_tizen 3.0
+ * @param [in] handle Event handler handle
+ * @param [in] angles array of 3 angles in radians (yaw, pitch and roll)
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_NONE Successful
+ * @retval #MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre @a handle must be created by calling mm_navevent_handler_create()
+ * @see mm_navevent_handler_create()
+ */
+int mm_navevent_handler_set_angles(mm_navevent_handler_h handle, float angles[3]);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MM_NAVEVENT_HANDLER__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * @author: Volodymyr Brynza <v dot brynza at samsung dot com>
+ * Andriy Martynets <a dot martynets at partner dot samsung dot com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MM_NAVEVENT_HANDLER_PRIV__
+#define __MM_NAVEVENT_HANDLER_PRIV__
+
+#include <libinput.h>
+#include <libudev.h>
+#include <pthread.h>
+
+#include "mm_navevent_handler.h"
+
+typedef struct _mm_navevent_handler_s mm_navevent_handler_s;
+
+struct _mm_navevent_handler_s {
+ struct libinput *lih;
+ mm_navevent_handler_device_type_e dev;
+ mm_navevent_handler_orientation_e window_orientation;
+ mm_navevent_handler_size_s window_size; /*<< Application window size in pixels */
+ mm_navevent_handler_size_s fov; /*<< Field-Of-View size in degrees */
+ mm_navevent_handler_size_s screen_size; /*<< Screen size in pixels */
+
+ unsigned int current[2];
+ unsigned int last[2];
+
+ float angles[3]; /*<< yaw, pitch and roll angles */
+
+ mm_navevent_handler_cb cb;
+ void *user_data;
+
+ pthread_t event_thread;
+ pthread_mutex_t event_lock;
+ int event_loop_run;
+};
+
+mm_navevent_handler_s *_mm_navevent_handler_create(mm_navevent_handler_device_type_e device);
+int _mm_navevent_handler_destroy(mm_navevent_handler_s *handler);
+int _mm_navevent_handler_set_cb(mm_navevent_handler_s *handler, mm_navevent_handler_cb cb, void *data);
+int _mm_navevent_handler_unset_cb(mm_navevent_handler_s *handler);
+int _mm_navevent_handler_set_window_parameters(mm_navevent_handler_s *handler, mm_navevent_handler_orientation_e wo, mm_navevent_handler_size_s ws);
+int _mm_navevent_handler_set_fov_size(mm_navevent_handler_s *handler, mm_navevent_handler_size_s fovs);
+int _mm_navevent_handler_get_screen_size(mm_navevent_handler_s *handler, mm_navevent_handler_size_s *size);
+int _mm_navevent_handler_set_angles(mm_navevent_handler_s *handler, float angles[3]);
+
+#endif /* __MM_NAVEVENT_HANDLER_PRIV__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * @author: Volodymyr Brynza <v dot brynza at samsung dot com>
+ * Andriy Martynets <a dot martynets at partner dot samsung dot com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MM_NAVEVENT_HANDLER_UTIL__
+#define __MM_NAVEVENT_HANDLER_UTIL__
+
+#include <dlog.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "MM_NAVEVENT_HANDLER"
+
+#define FONT_COLOR_RESET "\033[0m"
+#define FONT_COLOR_RED "\033[31m"
+#define FONT_COLOR_GREEN "\033[32m"
+
+#define MM_EH_DEBUG(fmt, arg...) \
+ do { \
+ LOGD(FONT_COLOR_RESET""fmt""FONT_COLOR_RESET, ##arg); \
+ } while (0)
+
+#define MM_EH_INFO(fmt, arg...) \
+ do { \
+ LOGI(FONT_COLOR_GREEN""fmt""FONT_COLOR_RESET, ##arg); \
+ } while (0)
+
+#define MM_EH_ERROR(fmt, arg...) \
+ do { \
+ LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg); \
+ } while (0)
+
+#define MM_EH_RETM_IF(expr, fmt, arg...) \
+ do { \
+ if (expr) { \
+ LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg); \
+ return; \
+ } \
+ } while (0)
+
+#define MM_EH_RETVM_IF(expr, val, fmt, arg...) \
+ do { \
+ if (expr) { \
+ LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg); \
+ return(val); \
+ } \
+ } while (0)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MM_NAVEVENT_HANDLER_UTIL__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * @author: Volodymyr Brynza <v dot brynza at samsung dot com>
+ * Andriy Martynets <a dot martynets at partner dot samsung dot com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mm_navevent_handler_util.h"
+#include "mm_navevent_handler_priv.h"
+
+int mm_navevent_handler_create(mm_navevent_handler_h *handle, mm_navevent_handler_device_type_e device)
+{
+ MM_EH_RETVM_IF(device <= MM_NAVEVENT_HANDLER_DEVICE_TYPE_INVALID ||
+ device >= MM_NAVEVENT_HANDLER_DEVICE_TYPE_MAX, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER,
+ "Wrong device type");
+
+ *handle = _mm_navevent_handler_create(device);
+ if (NULL == *handle)
+ return MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION;
+
+ return MM_NAVEVENT_HANDLER_ERROR_NONE;
+}
+
+int mm_navevent_handler_destroy(mm_navevent_handler_h handle)
+{
+ MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER,
+ "Handle is NULL");
+
+ mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle;
+
+ return _mm_navevent_handler_destroy(handler);
+}
+
+int mm_navevent_handler_set_cb(mm_navevent_handler_h handle, mm_navevent_handler_cb cb, void *data)
+{
+ MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER,
+ "Handle is NULL");
+ MM_EH_RETVM_IF(NULL == cb, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER,
+ "cb is NULL");
+
+ mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle;
+
+ return _mm_navevent_handler_set_cb(handler, cb, data);
+}
+
+int mm_navevent_handler_unset_cb(mm_navevent_handler_h handle)
+{
+ MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER,
+ "Handle is NULL");
+
+ mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle;
+
+ return _mm_navevent_handler_unset_cb(handler);
+}
+
+int mm_navevent_handler_set_window_parameters(mm_navevent_handler_h handle, mm_navevent_handler_orientation_e wo, mm_navevent_handler_size_s ws)
+{
+ MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER,
+ "Handle is NULL");
+
+ mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle;
+
+ return _mm_navevent_handler_set_window_parameters(handler, wo, ws);
+}
+
+int mm_navevent_handler_set_fov_size(mm_navevent_handler_h handle, mm_navevent_handler_size_s fovs)
+{
+ MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER,
+ "Handle is NULL");
+
+ mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle;
+
+ return _mm_navevent_handler_set_fov_size(handler, fovs);
+}
+
+int mm_navevent_handler_get_screen_size(mm_navevent_handler_h handle, mm_navevent_handler_size_s *size)
+{
+ MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER,
+ "Handle is NULL");
+
+ MM_EH_RETVM_IF(NULL == size, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER,
+ "Structure address is NULL");
+
+ mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle;
+
+ return _mm_navevent_handler_get_screen_size(handler, size);
+}
+
+int mm_navevent_handler_set_angles(mm_navevent_handler_h handle, float angles[3])
+{
+ MM_EH_RETVM_IF(NULL == handle, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER,
+ "Handle is NULL");
+
+ MM_EH_RETVM_IF(NULL == angles, MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER,
+ "Array address is NULL");
+
+ mm_navevent_handler_s *handler = (mm_navevent_handler_s *)handle;
+
+ return _mm_navevent_handler_set_angles(handler, angles);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * @author: Volodymyr Brynza <v dot brynza at samsung dot com>
+ * Andriy Martynets <a dot martynets at partner dot samsung dot com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <system_info.h>
+#include <poll.h>
+#include <math.h>
+
+#include "mm_navevent_handler_priv.h"
+#include "mm_navevent_handler_util.h"
+
+const char *UDEV_SEAT = "seat0";
+
+static int __mm_navevent_handler_input_open(const char *path, int flags, void *user_data)
+{
+ int fd = open(path, flags);
+ return fd < 0 ? -errno : fd;
+}
+
+static void __mm_navevent_handler_input_close(int fd, void *user_data)
+{
+ close(fd);
+}
+
+static const struct libinput_interface iface = {
+ .open_restricted = __mm_navevent_handler_input_open,
+ .close_restricted = __mm_navevent_handler_input_close,
+};
+
+static int __mm_navevent_handler_init_input(mm_navevent_handler_s *handler)
+{
+ struct udev *udev = udev_new();
+ if (NULL == udev) {
+ MM_EH_ERROR("Failed to initialize udev");
+ return MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION;
+ }
+
+ handler->lih = libinput_udev_create_context(&iface, NULL, udev);
+ if (NULL == handler->lih) {
+ MM_EH_ERROR("Failed to initialize libinput context from udev");
+ udev_unref(udev);
+ return MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION;
+ }
+
+ if (libinput_udev_assign_seat(handler->lih, UDEV_SEAT)) {
+ MM_EH_ERROR("Failed to set seat for context");
+ libinput_unref(handler->lih);
+ handler->lih = NULL;
+ udev_unref(udev);
+ return MM_NAVEVENT_HANDLER_ERROR_INVALID_OPERATION;
+ }
+
+ return MM_NAVEVENT_HANDLER_ERROR_NONE;
+}
+
+static void set_initial_coordinates(mm_navevent_handler_s *handler, struct libinput_event *ev)
+{
+ struct libinput_event_touch *t = libinput_event_get_touch_event(ev);
+ MM_EH_DEBUG("Got touch down event. Time - %f sec", libinput_event_touch_get_time(t)/1000.0);
+
+ pthread_mutex_lock(&handler->event_lock);
+
+ handler->last[0] = libinput_event_touch_get_x(t);
+ handler->last[1] = libinput_event_touch_get_y(t);
+
+ if (handler->cb) {
+ /* Below call simulates mouse depressed move */
+ handler->cb(LIBINPUT_EVENT_TOUCH_MOTION, handler->last[0], handler->last[1], handler->user_data, handler->angles);
+ handler->cb(libinput_event_get_type(ev), handler->last[0], handler->last[1], handler->user_data, handler->angles);
+ }
+
+ pthread_mutex_unlock(&handler->event_lock);
+}
+
+static void set_final_coordinates(mm_navevent_handler_s *handler, struct libinput_event *ev)
+{
+ struct libinput_event_touch *t = libinput_event_get_touch_event(ev);
+ MM_EH_DEBUG("Got touch up event. Time - %f sec", libinput_event_touch_get_time(t)/1000.0);
+
+ pthread_mutex_lock(&handler->event_lock);
+
+ if (handler->cb)
+ handler->cb(libinput_event_get_type(ev), handler->current[0], handler->current[1], handler->user_data, handler->angles);
+
+ pthread_mutex_unlock(&handler->event_lock);
+}
+
+/* NOTE: pointer slides the image, thus the direction of view moves in opposit
+ * direction.
+ * Orientation (degrees):
+ * 0 yaw: last_x - x; pitch: y - last_y;
+ * 0,0 ------> X
+ * |
+ * |
+ * |
+ * v Y
+ *
+ * 90 yaw: y - last_y; pitch: x - last_x;
+ * Y <------ 0,0
+ * |
+ * |
+ * |
+ * X v
+ *
+ * 180 yaw: x - last_x; pitch: last_y - y;
+ * Y ^
+ * |
+ * |
+ * |
+ * X <------ 0,0
+ *
+ * 270 yaw: last_y - y; pitch: last_x - x;
+ * ^ X
+ * |
+ * |
+ * |
+ * 0,0 ------> Y
+ */
+static void update_angles(mm_navevent_handler_s *handler)
+{
+ float x, last_x, y, last_y;
+
+ switch (handler->window_orientation) {
+ case MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_0:
+ x = handler->last[0];
+ last_x = handler->current[0];
+ y = handler->current[1];
+ last_y = handler->last[1];
+ break;
+ case MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_90:
+ x = handler->current[1];
+ last_x = handler->last[1];
+ y = handler->current[0];
+ last_y = handler->last[0];
+ break;
+ case MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_180:
+ x = handler->current[0];
+ last_x = handler->last[0];
+ y = handler->last[1];
+ last_y = handler->current[1];
+ break;
+ case MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_270:
+ x = handler->last[1];
+ last_x = handler->current[1];
+ y = handler->last[0];
+ last_y = handler->current[0];
+ break;
+ default:
+ return;
+ }
+
+ handler->angles[0] += ((float)handler->fov.width * (x - last_x) / (float)handler->window_size.width) * M_PI / 180.0;
+ handler->angles[1] += ((float)handler->fov.height * (y - last_y) / (float)handler->window_size.height) * M_PI / 180.0;
+
+ /* Fix yaw angle */
+ if (handler->angles[0] <= -(M_PI)) handler->angles[0] += 2 * M_PI;
+ else if (handler->angles[0] > M_PI) handler->angles[0] -= 2 * M_PI;
+
+ /* Fix pitch angle */
+ if (handler->angles[1] < -(M_PI_2)) handler->angles[1] = -(M_PI_2);
+ else if (handler->angles[1] > M_PI_2) handler->angles[1] = M_PI_2;
+}
+
+static void process_move(mm_navevent_handler_s *handler, struct libinput_event *ev)
+{
+ struct libinput_event_touch *t = libinput_event_get_touch_event(ev);
+ MM_EH_DEBUG("Got touch event. Time - %f sec", libinput_event_touch_get_time(t)/1000.0);
+
+ pthread_mutex_lock(&handler->event_lock);
+
+ handler->current[0] = libinput_event_touch_get_x(t);
+ handler->current[1] = libinput_event_touch_get_y(t);
+
+ update_angles(handler);
+
+ handler->last[0] = handler->current[0];
+ handler->last[1] = handler->current[1];
+
+ if (handler->cb) {
+ MM_EH_INFO("Sending position to user code");
+ handler->cb(libinput_event_get_type(ev), handler->current[0], handler->current[1], handler->user_data, handler->angles);
+ }
+
+ pthread_mutex_unlock(&handler->event_lock);
+}
+
+static void handle_events(mm_navevent_handler_s *handler)
+{
+ struct libinput_event *ev = NULL;
+
+ MM_EH_INFO("Process events");
+
+ libinput_dispatch(handler->lih);
+
+ while ((ev = libinput_get_event(handler->lih))) {
+ switch (libinput_event_get_type(ev)) {
+ case LIBINPUT_EVENT_TOUCH_MOTION:
+ MM_EH_DEBUG("Got touch event with coords");
+ /* Process coordinates and send event */
+ if (handler->dev == MM_NAVEVENT_HANDLER_DEVICE_TYPE_TOUCH)
+ process_move(handler, ev);
+ break;
+ case LIBINPUT_EVENT_TOUCH_DOWN:
+ if (handler->dev == MM_NAVEVENT_HANDLER_DEVICE_TYPE_TOUCH)
+ set_initial_coordinates(handler, ev);
+ break;
+ case LIBINPUT_EVENT_TOUCH_UP:
+ if (handler->dev == MM_NAVEVENT_HANDLER_DEVICE_TYPE_TOUCH)
+ set_final_coordinates(handler, ev);
+ /* Do nothing as we don't get any coordinates here */
+ MM_EH_DEBUG("Got touch event");
+ break;
+ default:
+ break;
+ }
+
+ libinput_event_destroy(ev);
+ libinput_dispatch(handler->lih);
+ }
+}
+
+static void *__mm_navevent_handler_handle_event(void *data)
+{
+ struct pollfd fds;
+ mm_navevent_handler_s *handler = (mm_navevent_handler_s *)data;
+
+ fds.fd = libinput_get_fd(handler->lih);
+ fds.events = POLLIN;
+ fds.revents = 0;
+
+ MM_EH_INFO("Start processing navigation event");
+ while (poll(&fds, 1, -1))
+ handle_events(handler);
+ MM_EH_INFO("End processing navigation event");
+
+ return NULL;
+}
+
+mm_navevent_handler_s *_mm_navevent_handler_create(mm_navevent_handler_device_type_e device)
+{
+ int res = 0;
+ mm_navevent_handler_s *handle = (mm_navevent_handler_s *)calloc(sizeof(mm_navevent_handler_s), 1);
+ if (NULL == handle) {
+ MM_EH_ERROR("Cannot allocate memory for event handler");
+ return NULL;
+ }
+
+ handle->dev = device;
+
+ res = system_info_get_platform_int("http://tizen.org/feature/screen.width", &handle->screen_size.width);
+ if (SYSTEM_INFO_ERROR_NONE != res) {
+ MM_EH_ERROR("Failed to get Device screen width from System Info with error - [%d]", res);
+ free(handle);
+ return NULL;
+ }
+
+ res = system_info_get_platform_int("http://tizen.org/feature/screen.height", &handle->screen_size.height);
+ if (SYSTEM_INFO_ERROR_NONE != res) {
+ MM_EH_ERROR("Failed to get Device screen height from System Info with error - [%d]", res);
+ free(handle);
+ return NULL;
+ }
+
+ res = __mm_navevent_handler_init_input(handle);
+ if (MM_NAVEVENT_HANDLER_ERROR_NONE != res) {
+ MM_EH_ERROR("Failed to initialize input for event handling with error - [%d]", res);
+ free(handle);
+ return NULL;
+ }
+
+ pthread_mutex_init(&handle->event_lock, NULL);
+
+ handle->window_orientation = MM_NAVEVENT_HANDLER_ORIENTATION_DEGREE_0;
+ handle->window_size.width = handle->screen_size.width;
+ handle->window_size.height = handle->screen_size.height;
+ handle->fov.width = MM_NAVEVENT_HANDLER_DEFAULT_HORIZONTAL_FOV_DEGREE;
+ handle->fov.height = MM_NAVEVENT_HANDLER_DEFAULT_VERTICAL_FOV_DEGREE;
+ handle->angles[0] = handle->angles[1] = handle->angles[2] = .0f;
+
+ pthread_create(&handle->event_thread, NULL, __mm_navevent_handler_handle_event, handle);
+
+ return handle;
+}
+
+int _mm_navevent_handler_destroy(mm_navevent_handler_s *handler)
+{
+ if (NULL == handler) {
+ MM_EH_ERROR("Invalid pointer to event handler");
+ return MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER;
+ }
+
+ pthread_mutex_lock(&handler->event_lock);
+ pthread_cancel(handler->event_thread);
+ pthread_mutex_unlock(&handler->event_lock);
+
+ void *thread_res = NULL;
+ pthread_join(handler->event_thread, &thread_res);
+
+ pthread_mutex_destroy(&handler->event_lock);
+
+ libinput_unref(handler->lih);
+
+ free(handler);
+
+ return MM_NAVEVENT_HANDLER_ERROR_NONE;
+}
+
+int _mm_navevent_handler_set_cb(mm_navevent_handler_s *handler, mm_navevent_handler_cb cb, void *data)
+{
+ if (NULL == handler) {
+ MM_EH_ERROR("Invalid pointer to event handler");
+ return MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER;
+ }
+
+ handler->cb = cb;
+ handler->user_data = data;
+
+ return MM_NAVEVENT_HANDLER_ERROR_NONE;
+}
+
+int _mm_navevent_handler_unset_cb(mm_navevent_handler_s *handler)
+{
+ if (NULL == handler) {
+ MM_EH_ERROR("Invalid pointer to event handler");
+ return MM_NAVEVENT_HANDLER_ERROR_INVALID_PARAMETER;
+ }
+
+ handler->cb = NULL;
+ handler->user_data = NULL;
+
+ return MM_NAVEVENT_HANDLER_ERROR_NONE;
+}
+
+int _mm_navevent_handler_set_window_parameters(mm_navevent_handler_s *handler, mm_navevent_handler_orientation_e wo, mm_navevent_handler_size_s ws)
+{
+ handler->window_size = ws;
+ handler->window_orientation = wo;
+
+ return MM_NAVEVENT_HANDLER_ERROR_NONE;
+}
+
+int _mm_navevent_handler_set_fov_size(mm_navevent_handler_s *handler, mm_navevent_handler_size_s fovs)
+{
+ handler->fov = fovs;
+
+ return MM_NAVEVENT_HANDLER_ERROR_NONE;
+}
+
+int _mm_navevent_handler_get_screen_size(mm_navevent_handler_s *handler, mm_navevent_handler_size_s *size)
+{
+ memcpy(size, &handler->screen_size, sizeof(*size));
+
+ return MM_NAVEVENT_HANDLER_ERROR_NONE;
+}
+
+int _mm_navevent_handler_set_angles(mm_navevent_handler_s *handler, float angles[3])
+{
+ memcpy(handler->angles, angles, sizeof(*angles) * 3);
+
+ return MM_NAVEVENT_HANDLER_ERROR_NONE;
+}
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define USE_EVENT_HANDLER
+
#include <player.h>
#include <player_internal.h>
#include <sound_manager.h>
#include <eom.h>
#endif
+#ifdef USE_EVENT_HANDLER
+#include <mm_navevent_handler.h>
+#endif
+
#ifdef PACKAGE
#undef PACKAGE
#endif
int rebuffer_ms;
} buffer_size_t;
+#ifdef USE_EVENT_HANDLER
+static void event_handler_cb(enum libinput_event_type ev_t, int x, int y, void * data, float e[3]);
+static void event_handler_set_dov_fov();
+static void event_handler_set_window_parameters();
+mm_navevent_handler_h event_handler;
+mm_navevent_handler_size_s image_size;
+#endif
+
static tizen_profile_t _get_tizen_profile()
{
char *profileName;
CURRENT_STATUS_SET_AUDIO_ONLY,
CURRENT_STATUS_SET_PRE_BUFFERING_SIZE,
CURRENT_STATUS_SET_RE_BUFFERING_SIZE,
+ CURRENT_STATUS_VIDEO360_SET_ENABLE,
+ CURRENT_STATUS_VIDEO360_SET_DOV,
+ CURRENT_STATUS_VIDEO360_SET_DOV1,
+ CURRENT_STATUS_VIDEO360_SET_FOV,
+ CURRENT_STATUS_VIDEO360_SET_FOV1,
+ CURRENT_STATUS_VIDEO360_SET_ZOOM,
};
typedef struct {
#ifdef _ACTIVATE_EOM_
eom_output_mode_e output_mode = EOM_OUTPUT_MODE_NONE;
#endif
+
/* use gl backend */
elm_config_accel_preference_set("opengl");
eom_set_mode_changed_cb(eom_notify_cb_mode_changed, ad);
eom_set_attribute_changed_cb(eom_notify_cb_attribute_changed, ad);
#endif
+
+#ifdef USE_EVENT_HANDLER
+ if (mm_navevent_handler_create(&event_handler,
+ MM_NAVEVENT_HANDLER_DEVICE_TYPE_TOUCH) != MM_NAVEVENT_HANDLER_ERROR_NONE) {
+ g_print ("Error during handler creation\n");
+ return -1;
+ }
+
+ if (mm_navevent_handler_set_cb(event_handler, event_handler_cb, NULL) !=
+ MM_NAVEVENT_HANDLER_ERROR_NONE) {
+ g_print ("Error during callback set\n");
+ return -1;
+ }
+#endif
+
return 0;
}
appdata *ad = data;
int i = 0;
+#ifdef USE_EVENT_HANDLER
+ mm_navevent_handler_destroy(event_handler);
+#endif
+
for (i = 0; i < MAX_HANDLE; i++) {
if (g_eo[i]) {
evas_object_del(g_eo[i]);
static void video_changed_cb(int width, int height, int fps, int bit_rate, void *user_data)
{
g_print("[Player_Test] video_changed_cb!!!! %d x %d, %d, %d \n", width, height, fps, bit_rate);
+
+#ifdef USE_EVENT_HANDLER
+ image_size.width = width;
+ image_size.height = height;
+ event_handler_set_window_parameters();
+#endif
}
#if 0
if (is_es_push_mode)
pthread_create(&g_feed_video_thread_id, NULL, (void *)feed_video_data_thread_func, NULL);
+#ifdef USE_EVENT_HANDLER
+ event_handler_set_dov_fov();
+#endif
}
static void _player_unprepare()
{
if (player_set_display_rotation(g_player[0], rotation) != PLAYER_ERROR_NONE)
g_print("failed to set_display_rotation\n");
+#ifdef USE_EVENT_HANDLER
+ event_handler_set_window_parameters();
+#endif
}
static void get_display_rotation()
g_print(" ==> [Player_Test] eq bands frequency range: [%d] \n", value);
}
+static void video360_set_enable(bool enable)
+{
+#ifdef USE_EVENT_HANDLER
+ event_handler_set_dov_fov();
+#endif
+
+ if (player_360_set_enable(g_player[0], enable) != PLAYER_ERROR_NONE)
+ g_print("failed to %s video 360 mode\n", enable ? "enable" : "disable");
+}
+
+static void video360_get_enable()
+{
+ bool enable;
+
+ if (player_360_is_enabled(g_player[0], &enable) != PLAYER_ERROR_NONE)
+ g_print("failed to get video 360 mode status\n");
+ else
+ g_print(" ==> [Player_Test] Video 360 mode = %s\n", enable ? "enabled" : "disabled");
+}
+
+static void video360_set_fov(int hfov, int vfov)
+{
+#ifdef USE_EVENT_HANDLER
+ mm_navevent_handler_size_s fov;
+
+ fov.width = hfov;
+ fov.height = vfov;
+ mm_navevent_handler_set_fov_size(event_handler, fov);
+#endif
+ if (player_360_set_field_of_view(g_player[0], hfov, vfov) != PLAYER_ERROR_NONE)
+ g_print("failed to set video 360 field of view\n");
+}
+
+static void video360_get_fov()
+{
+ int hfov, vfov;
+
+ if (player_360_get_field_of_view(g_player[0], &hfov, &vfov) != PLAYER_ERROR_NONE)
+ g_print("failed to get video 360 field of view\n");
+ else
+ g_print(" ==> [Player_Test] Video 360 FOV = %dx%d deg.\n", hfov, vfov);
+}
+
+static void video360_set_dov(int yaw_deg, int pitch_deg)
+{
+ float angles[3];
+
+ angles[0] = M_PI * yaw_deg / 180.0f;
+ angles[1] = M_PI * pitch_deg / 180.0f;
+ angles[2] = 0;
+
+#ifdef USE_EVENT_HANDLER
+ mm_navevent_handler_set_angles(event_handler, angles);
+#endif
+ if (player_360_set_direction_of_view(g_player[0], angles[0], angles[1]) != PLAYER_ERROR_NONE)
+ g_print("failed to set video 360 direction of view\n");
+}
+
+static void video360_get_dov()
+{
+ float yaw, pitch;
+
+ if (player_360_get_direction_of_view(g_player[0], &yaw, &pitch) != PLAYER_ERROR_NONE)
+ g_print("failed to get video 360 direction of view\n");
+ else
+ g_print(" ==> [Player_Test] Video 360 DOV yaw = %d, pitch = %d deg.\n", (int)(yaw * 180.0f / M_PI), (int)(pitch * 180.0f / M_PI));
+}
+
+static void video360_set_zoom(float zoom)
+{
+ if (player_360_set_zoom(g_player[0], zoom) != PLAYER_ERROR_NONE)
+ g_print("failed to set video 360 zoom\n");
+}
+
+static void video360_get_zoom()
+{
+ float zoom;
+
+ if (player_360_get_zoom(g_player[0], &zoom) != PLAYER_ERROR_NONE)
+ g_print("failed to get video 360 zoom\n");
+ else
+ g_print(" ==> [Player_Test] Video 360 zoom = %f\n", zoom);
+}
+
+#ifdef USE_EVENT_HANDLER
+static void event_handler_cb(enum libinput_event_type ev_t, int x, int y, void * data, float e[3])
+{
+ if (ev_t == LIBINPUT_EVENT_TOUCH_MOTION)
+ if (player_360_set_direction_of_view(g_player[0], e[0], e[1]) != PLAYER_ERROR_NONE)
+ g_print("Event handler callback: failed to set direction of view\n");
+}
+
+static void event_handler_set_dov_fov()
+{
+ float angles[3];
+ mm_navevent_handler_size_s fov;
+
+ if (player_360_get_direction_of_view(g_player[0], &angles[0], &angles[1]) != PLAYER_ERROR_NONE) {
+ g_print("Failed to get video360 direction of view\n");
+ return;
+ }
+ if (player_360_get_field_of_view(g_player[0], &fov.width, &fov.height) != PLAYER_ERROR_NONE) {
+ g_print("Failed to get video360 field of view\n");
+ return;
+ }
+ mm_navevent_handler_set_angles(event_handler, angles);
+ mm_navevent_handler_set_fov_size(event_handler, fov);
+}
+
+static void event_handler_set_window_parameters()
+{
+ player_display_rotation_e window_orientation;
+ mm_navevent_handler_size_s window_size;
+ float image_ratio;
+
+ player_get_display_rotation(g_player[0], &window_orientation);
+ elm_win_screen_size_get(selected_win_id, NULL, NULL, &window_size.width, &window_size.height);
+
+ image_ratio = (float) image_size.width / (float) image_size.height;
+
+ if (window_orientation == PLAYER_DISPLAY_ROTATION_NONE ||
+ window_orientation == PLAYER_DISPLAY_ROTATION_180) {
+ window_size.height = (int)((float) window_size.width / image_ratio);
+ } else {
+ window_size.height = window_size.width;
+ window_size.width = (int)((float) window_size.width * image_ratio);
+ }
+
+ mm_navevent_handler_set_window_parameters(event_handler,
+ (mm_navevent_handler_orientation_e) window_orientation, window_size);
+}
+#endif
+
void quit_program()
{
} else {
g_print("unknown menu \n");
}
- } else {
+ } else if (len == 3) {
if (strncmp(cmd, "trs", 3) == 0)
g_menu_state = CURRENT_STATUS_STREAMING_PLAYBACK_RATE;
else
g_print("unknown menu \n");
- }
+ } else if (len == 4) {
+ if (!strncmp(cmd, "v3se", 4))
+ g_menu_state = CURRENT_STATUS_VIDEO360_SET_ENABLE;
+ else if (!strncmp(cmd, "v3ge", 4))
+ video360_get_enable();
+ else if (!strncmp(cmd, "v3sd", 4))
+ g_menu_state = CURRENT_STATUS_VIDEO360_SET_DOV;
+ else if (!strncmp(cmd, "v3gd", 4))
+ video360_get_dov();
+ else if (!strncmp(cmd, "v3sf", 4))
+ g_menu_state = CURRENT_STATUS_VIDEO360_SET_FOV;
+ else if (!strncmp(cmd, "v3gf", 4))
+ video360_get_fov();
+ else if (!strncmp(cmd, "v3sz", 4))
+ g_menu_state = CURRENT_STATUS_VIDEO360_SET_ZOOM;
+ else if (!strncmp(cmd, "v3gz", 4))
+ video360_get_zoom();
+ else
+ g_print("unknown menu \n");
+ } else
+ g_print("unknown menu \n");
}
void display_sub_basic()
g_print("X4. set audio_cb with async \n");
g_print("[video_frame_decoded_cb] ep. enable tbm surface pool\n");
g_print("[buffering] bf. set new buffering size\n");
+ g_print("[Video 360] v3se. Set Enable\t\t");
+ g_print("v3ge. Get Enable\n");
+ g_print("[Video 360] v3sd. Set Direction Of View\t");
+ g_print("v3gd. Get Direction Of View\n");
+ g_print("[Video 360] v3sf. Set Field Of View\t");
+ g_print("v3gf. Get Field Of View\n");
+ g_print("[Video 360] v3sz. Set Zoom\t\t");
+ g_print("v3gz. Get Zoom\n");
g_print("[etc] sp. Set Progressive Download\t");
g_print("gp. Get Progressive Download status\t");
g_print("mp. memory playback\n");
g_print("*** set audio only mode (0:disable, 1:enable) \n");
} else if (g_menu_state == CURRENT_STATUS_SET_PRE_BUFFERING_SIZE) {
g_print("*** set pre buffering size (ms) \n");
+ } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_ENABLE) {
+ g_print("*** input video 360 status (0: disabled (full panorama), 1: enabled)\n");
+ } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_DOV) {
+ g_print("*** input direction of view yaw angle (+/- 180 deg.)\n");
+ } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_DOV1) {
+ g_print("*** input direction of view pitch angle (+/- 90 deg.)\n");
+ } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_FOV) {
+ g_print("*** input horizontal field of view angle (1~360 deg.)\n");
+ } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_FOV1) {
+ g_print("*** input vertical field of view angle (1~180 deg.)\n");
+ } else if (g_menu_state == CURRENT_STATUS_VIDEO360_SET_ZOOM) {
+ g_print("*** input zoom factor.(1.0~10.0, where 1.0 - no zoom, actual image) \n");
} else {
g_print("*** unknown status.\n");
quit_program();
static void interpret(char *cmd)
{
+ static int value1, value2;
+
switch (g_menu_state) {
case CURRENT_STATUS_MAINMENU:
{
reset_menu_state();
}
break;
+ case CURRENT_STATUS_VIDEO360_SET_ENABLE:
+ {
+ int enable = atoi(cmd);
+ video360_set_enable(enable);
+ reset_menu_state();
+ }
+ break;
+ case CURRENT_STATUS_VIDEO360_SET_DOV:
+ {
+ value1 = atoi(cmd);
+ g_menu_state = CURRENT_STATUS_VIDEO360_SET_DOV1;
+ }
+ break;
+ case CURRENT_STATUS_VIDEO360_SET_DOV1:
+ {
+ value2 = atoi(cmd);
+ video360_set_dov(value1, value2);
+ reset_menu_state();
+ }
+ break;
+ case CURRENT_STATUS_VIDEO360_SET_FOV:
+ {
+ value1 = atoi(cmd);
+ g_menu_state = CURRENT_STATUS_VIDEO360_SET_FOV1;
+ }
+ break;
+ case CURRENT_STATUS_VIDEO360_SET_FOV1:
+ {
+ value2 = atoi(cmd);
+ video360_set_fov(value1, value2);
+ reset_menu_state();
+ }
+ break;
+ case CURRENT_STATUS_VIDEO360_SET_ZOOM:
+ {
+ float zoom = atof(cmd);
+ video360_set_zoom(zoom);
+ reset_menu_state();
+ }
+ break;
}