Add UIBC related functions, enum, and structure 20/321720/10
authorGilbok Lee <gilbok.lee@samsung.com>
Thu, 27 Mar 2025 07:57:11 +0000 (16:57 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Fri, 18 Apr 2025 05:47:13 +0000 (14:47 +0900)
- scmirroring_sink_set_window_size()
- scmirroring_sink_enable_uibc()
- scmirroring_sink_send_generic_mouse_event()
- scmirroring_sink_send_generic_key_event()

[Version] 0.3.4
[Issue type] New APIs

Change-Id: I8c708bbe26ec1caaa1842cad20de23d49c968dd9

include/scmirroring_internal.h
include/scmirroring_private.h
include/scmirroring_type_internal.h
packaging/capi-media-screen-mirroring.spec
src/scmirroring_sink_internal.c
src/scmirroring_util.c

index e75990505298a89dc83291ee67afeb55b849fe3b..75c4bb2cfdd8f57b6794d33dfcfcd8a9dd4dceaf 100644 (file)
@@ -99,9 +99,113 @@ typedef void(*scmirroring_state_cb)(scmirroring_error_e error, scmirroring_state
  * @see scmirroring_sink_create()
  */
 int scmirroring_sink_set_ecore_wl_display(scmirroring_sink_h scmirroring_sink, void *display_surface);
+
+/**
+ * @internal
+ * @brief Sets the window size for UIBC events within the specified region.
+ * @details Configuration of the UIBC area for calculation internal coordinates of UIBC events.
+ *
+ * @since_tizen 10.0
+ *
+ * @remarks This function must be called before scmirroring_sink_enable_uibc().
+ * @remarks This function is related to the following feature:\n
+ *          %http://tizen.org/feature/network.wifi.direct.display\n
+ * @param[in] scmirroring_sink The handle to the screen mirroring sink
+ * @param[in] width The width of application window
+ * @param[in] height The height of application window
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #SCMIRRORING_ERROR_NONE Successful
+ * @retval #SCMIRRORING_ERROR_NOT_SUPPORTED Not supported
+ * @retval #SCMIRRORING_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SCMIRRORING_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #SCMIRRORING_ERROR_UNKNOWN Unknown Error
+ * @pre Call scmirroring_sink_prepare() before calling this function.
+ * @see scmirroring_sink_enable_uibc()
+ *
+ */
+int scmirroring_sink_set_window_size(scmirroring_sink_h scmirroring_sink, int width, int height);
+
+/**
+ * @internal
+ * @brief Enable UIBC.
+ *
+ *  @since_tizen 10.0
+ *
+ * @remarks This function is related to the following feature:\n
+ *          %http://tizen.org/feature/network.wifi.direct.display\n
+ * @remarks This function must be called before scmirroring_sink_connect().
+ * @param[in] scmirroring_sink The handle to the screen mirroring sink
+ * @param[in] mode UIBC capture mode
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #SCMIRRORING_ERROR_NONE Successful
+ * @retval #SCMIRRORING_ERROR_NOT_SUPPORTED Not supported
+ * @retval #SCMIRRORING_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SCMIRRORING_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #SCMIRRORING_ERROR_UNKNOWN Unknown Error
+ * @pre Call scmirroring_sink_set_window_size() before calling this function.
+ * @pre Call scmirroring_sink_prepare() before calling this function.
+ * @see scmirroring_sink_set_window_size()
+ * @see scmirroring_sink_prepare()
+ * @see scmirroring_sink_connect()
+ */
+int scmirroring_sink_enable_uibc(scmirroring_sink_h scmirroring_sink, scmirroring_uibc_capture_mode_e mode);
+
+/**
+ * @internal
+ * @brief Sends UIBC generic mouse event to the screen mirroring source.
+ *
+ * @since_tizen 10.0
+ *
+ * @remarks This function is related to the following feature:\n
+ *          %http://tizen.org/feature/network.wifi.direct.display\n
+ * @remarks   This function support only mouse-left-down, mouse-left-move and mouse-left-up event.
+ *
+ * @param[in] scmirroring_sink The handle to the screen mirroring sink
+ * @param[in] uibc_event UIBC mouse event
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #SCMIRRORING_ERROR_NONE Successful
+ * @retval #SCMIRRORING_ERROR_NOT_SUPPORTED Not supported
+ * @retval #SCMIRRORING_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SCMIRRORING_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #SCMIRRORING_ERROR_UNKNOWN Unknown Error
+ * @pre Call scmirroring_sink_connect() before calling this function.
+ * @see scmirroring_sink_connect()
+ * @see #scmirroring_uibc_mouse_s
+ * @see #scmirroring_uibc_mouse_event_s
+ */
+int scmirroring_sink_send_generic_mouse_event(scmirroring_sink_h scmirroring_sink, scmirroring_uibc_mouse_event_s *uibc_event);
+
+/**
+ * @internal
+ * @brief Sends UIBC generic key event to the screen mirroring source.
+ *
+ * @since_tizen 10.0
+ *
+ * @remarks This function is related to the following feature:\n
+ *          %http://tizen.org/feature/network.wifi.direct.display\n
+ * @param[in] scmirroring_sink The handle to the screen mirroring sink
+ * @param[in] event_type Key event type
+ * @param[in] key_code_1 Key code 1 (ASCII), The key code of the first key down/up event. The basic/extended ASCII code uses the lower one byte.
+ *                 The higher one byte is reserved for future ASCII compatible key codes.
+ * @param[in] key_code_2 Key code 2 (ASCII), The key code for the second key down/up event. The value is set to 0x0000(NULL), if the second key code is not present.
+ *                 The basic/extended ASCII code uses the lower one byte. The higher one byte is reserved for future ASCII compatible key codes.
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #SCMIRRORING_ERROR_NONE Successful
+ * @retval #SCMIRRORING_ERROR_NOT_SUPPORTED Not supported
+ * @retval #SCMIRRORING_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #SCMIRRORING_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #SCMIRRORING_ERROR_UNKNOWN Unknown Error
+ * @pre Call scmirroring_sink_connect() before calling this function.
+ * @see scmirroring_sink_connect()
+ */
+int scmirroring_sink_send_generic_key_event(scmirroring_sink_h scmirroring_sink, scmirroring_key_event_type_e event_type, unsigned short key_code_1, unsigned short key_code_2);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
 #endif /* __TIZEN_MEDIA_SCMIRRORING_INTERNAL_H__ */
-
index 57d2bfe9a3941e2c1624e658e07373401e26ac42..c0ddd0e1b72ac3917142bc19acb767ec62de1588 100644 (file)
@@ -88,6 +88,13 @@ extern "C" {
                } \
        } while (0)
 
+#define scmirroring_range_arg_check(expr, min, max, fmt, arg...) do { \
+               if ((expr < min) || (expr > max)) { \
+                       LOGE(FONT_COLOR_RED""fmt""FONT_COLOR_RESET, ##arg);     \
+                       return SCMIRRORING_ERROR_INVALID_PARAMETER; \
+               } \
+       } while (0)
+
 #define scmirroring_sucure_info(fmt, arg...) do { \
                SECURE_LOGI(FONT_COLOR_GREEN""fmt""FONT_COLOR_RESET, ##arg);     \
        } while (0)
@@ -287,6 +294,10 @@ int _scmirroring_sink_get_negotiated_audio_channel(MMHandleType handle, int *cha
 int _scmirroring_sink_get_negotiated_audio_sample_rate(MMHandleType handle, int *sample_rate);
 int _scmirroring_sink_get_negotiated_audio_bitwidth(MMHandleType handle, int *bitwidth);
 int _scmirroring_sink_get_current_state(MMHandleType handle, scmirroring_sink_state_e *state);
+int _scmirroring_sink_set_window_size(MMHandleType handle, int width, int height);
+int _scmirroring_sink_enable_uibc(MMHandleType handle , scmirroring_uibc_capture_mode_e mode);
+int _scmirroring_sink_send_generic_mouse_event(MMHandleType handle, scmirroring_uibc_mouse_event_s *uibc_event);
+int _scmirroring_sink_send_generic_key_event(MMHandleType handle, scmirroring_key_event_type_e event_type, unsigned short key_code_1, unsigned short key_code_2);
 int _scmirroring_src_send_cmd_to_server(int sock, const char *cmd);
 int _scmirroring_src_send_set_cm(int sock, int connect_mode);
 int _scmirroring_src_send_set_ip(int sock, const char *ip, const char *port);
index 89ed15f24b83aff39b1f9498f5bf79fd384823d8..8173b59d5f6a409550624e456d7687fb2b8b587a 100644 (file)
@@ -18,6 +18,7 @@
 #define __TIZEN_MEDIA_SCMIRRORING_TYPE_INTERNAL_H__
 
 #include <tizen.h>
+#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -40,6 +41,18 @@ typedef void *scmirroring_primary_sink_h;
  */
 typedef void *scmirroring_secondary_sink_h;
 
+/**
+ * @brief      The handle to the screen mirroring UIBC mouse.
+ * @since_tizen 10.0
+ */
+typedef void *scmirroring_sink_mouse_h;
+
+/**
+ * @brief      The handle to the screen mirroring UIBC mouse event.
+ * @since_tizen 10.0
+ */
+typedef void *scmirroring_sink_mouse_event_h;
+
 /**
  * @brief Enumeration for screen mirroring coupling mode.
  * @since_tizen 5.5
@@ -60,6 +73,57 @@ typedef enum {
        SCMIRRORING_COUPLING_STATUS_MAX
 } scmirroring_coupled_sink_status_e;
 
+/**
+ * @brief Enumerations for key event type.
+ * @since_tizen 10.0
+ */
+typedef enum
+{
+       SCMIRRORING_EVENT_KEY_DOWN,           /**< Key down event */
+       SCMIRRORING_EVENT_KEY_UP              /**< Key up event */
+} scmirroring_key_event_type_e;
+
+/**
+ * @brief Enumerations for mouse event type.
+ * @since_tizen 10.0
+ */
+typedef enum
+{
+       SCMIRRORING_EVENT_MOUSE_LEFT_DOWN,    /**< Mouse left button down event */
+       SCMIRRORING_EVENT_MOUSE_LEFT_UP,      /**< Mouse left button up event */
+       SCMIRRORING_EVENT_MOUSE_MOVE          /**< Mouse move event */
+} scmirroring_mouse_event_type_e;
+
+/**
+ * @brief Enumerations for UIBC capture mode.
+ * @since_tizen 10.0
+ */
+typedef enum
+{
+       SCMIRRORING_CAPTURE_FROM_APPLICATION,   /**< Capture from application (Generic input) */
+       SCMIRRORING_CAPTURE_FROM_RAW_INTERFACE  /**< Capture from raw interface (Human Interface Device) */
+} scmirroring_uibc_capture_mode_e;
+
+/**
+ * @brief Structure for UIBC mouse information.
+ * @since_tizen 10.0
+ */
+typedef struct {
+       uint16_t id; /**< ID for pointer */
+       uint16_t x;  /**< X-coordicate for mouse */
+       uint16_t y;  /**< Y-coordicate for mouse */
+} scmirroring_uibc_mouse_s;
+
+/**
+ * @brief Structure for UIBC event information.
+ * @since_tizen 10.0
+ */
+typedef struct {
+       int num_objects;                            /**< Number of uibc_object pointer */
+       scmirroring_mouse_event_type_e event_type;  /**< Mouse event type */
+       scmirroring_uibc_mouse_s *uibc_object;      /**< UIBC mouse */
+} scmirroring_uibc_mouse_event_s;
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 9ddf86676df634a746e5886120a3e49c82425684..e84109fd9e4b8fb2f68ef9d02797a76270aa1f1a 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-screen-mirroring
 Summary:    A screen mirroring library in Tizen C API
-Version:    0.3.3
+Version:    0.3.4
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index c66d602f8b48f3fa18e139774eb1b77c642696a0..fa1c5d2feee63badb168f397069ecc3c0d800e5a 100644 (file)
@@ -37,3 +37,53 @@ int scmirroring_sink_set_ecore_wl_display(scmirroring_sink_h scmirroring_sink, v
 
        return _scmirroring_sink_set_display(handle->mm_handle, SCMIRRORING_DISPLAY_TYPE_OVERLAY, display_surface, MM_DISPLAY_TYPE_OVERLAY_EXT);
 }
+
+int scmirroring_sink_set_window_size(scmirroring_sink_h scmirroring_sink, int width, int height)
+{
+       scmirroring_sink_s *handle = (scmirroring_sink_s *)scmirroring_sink;
+
+       CHECK_FEATURE_SUPPORTED(WIFIDIRECT_DISPLAY_FEATURE);
+
+       scmirroring_debug_fenter();
+
+       scmirroring_retvm_if(!__is_valid_handle(handle), SCMIRRORING_ERROR_INVALID_PARAMETER, "scmirroring_sink is invalid");
+
+       return _scmirroring_sink_set_window_size(handle->mm_handle, width, height);
+}
+
+int scmirroring_sink_enable_uibc(scmirroring_sink_h scmirroring_sink , scmirroring_uibc_capture_mode_e mode)
+{
+       scmirroring_sink_s *handle = (scmirroring_sink_s *)scmirroring_sink;
+
+       CHECK_FEATURE_SUPPORTED(WIFIDIRECT_DISPLAY_FEATURE);
+
+       scmirroring_debug_fenter();
+
+       scmirroring_retvm_if(!__is_valid_handle(handle), SCMIRRORING_ERROR_INVALID_PARAMETER, "scmirroring_sink is invalid");
+
+       return _scmirroring_sink_enable_uibc(handle->mm_handle, mode);
+}
+
+int scmirroring_sink_send_generic_mouse_event(scmirroring_sink_h scmirroring_sink, scmirroring_uibc_mouse_event_s *uibc_event)
+{
+       scmirroring_sink_s *handle = (scmirroring_sink_s *)scmirroring_sink;
+
+       CHECK_FEATURE_SUPPORTED(WIFIDIRECT_DISPLAY_FEATURE);
+
+       scmirroring_debug_fenter();
+
+       scmirroring_retvm_if(!__is_valid_handle(handle), SCMIRRORING_ERROR_INVALID_PARAMETER, "scmirroring_sink is invalid");
+
+       return _scmirroring_sink_send_generic_mouse_event(handle->mm_handle, uibc_event);
+}
+
+int scmirroring_sink_send_generic_key_event(scmirroring_sink_h scmirroring_sink, scmirroring_key_event_type_e event_type, unsigned short key_code_1, unsigned short key_code_2)
+{
+       scmirroring_sink_s *handle = (scmirroring_sink_s *)scmirroring_sink;
+
+       CHECK_FEATURE_SUPPORTED(WIFIDIRECT_DISPLAY_FEATURE);
+
+       scmirroring_retvm_if(!__is_valid_handle(handle), SCMIRRORING_ERROR_INVALID_PARAMETER, "scmirroring_sink is invalid");
+
+       return _scmirroring_sink_send_generic_key_event(handle->mm_handle, event_type, key_code_1, key_code_2);
+}
index 029cbd99d8c1615511efbc8790a346f9a7b5ac52..694dc95d59de1818d66072fc98cffd6f8c7c3cb1 100644 (file)
@@ -495,6 +495,87 @@ int _scmirroring_sink_get_current_state(MMHandleType handle, scmirroring_sink_st
        return SCMIRRORING_ERROR_NONE;
 }
 
+int _scmirroring_sink_set_window_size(MMHandleType handle, int width, int height)
+{
+       int ret = MM_ERROR_NONE;
+
+       scmirroring_debug_fenter();
+
+       scmirroring_retvm_if(width <= 0 || height <= 0, SCMIRRORING_ERROR_INVALID_PARAMETER,
+               "invalid parameter, width %d height %d", width, height);
+
+       ret = mm_wfd_sink_set_attribute(handle, NULL, "window_width", width, "window_height", height, NULL);
+       if (ret != MM_ERROR_NONE) {
+               scmirroring_error("Fail to Set Window Width/Height");
+               return _scmirroring_error_convert(__func__, ret);
+       }
+
+       scmirroring_debug("Window width (%d), height (%d)", width, height);
+
+       return SCMIRRORING_ERROR_NONE;
+}
+
+int _scmirroring_sink_enable_uibc(MMHandleType handle , scmirroring_uibc_capture_mode_e mode)
+{
+       int ret = MM_ERROR_NONE;
+
+       scmirroring_debug_fenter();
+
+       scmirroring_range_arg_check(mode, SCMIRRORING_CAPTURE_FROM_APPLICATION, SCMIRRORING_CAPTURE_FROM_RAW_INTERFACE,
+               "invalid UIBC capture mode");
+
+       ret = mm_wfd_sink_enable_uibc(handle, (MMWFDSinkCaptureMode)mode);
+       if (ret != MM_ERROR_NONE) {
+               scmirroring_error("Fail to enable UIBC[%d] mode", (int)mode);
+               return _scmirroring_error_convert(__func__, ret);
+       }
+
+       scmirroring_debug("Enable UIBC [%d] mode", (int)mode);
+
+       return SCMIRRORING_ERROR_NONE;
+}
+
+int _scmirroring_sink_send_generic_mouse_event(MMHandleType handle, scmirroring_uibc_mouse_event_s *uibc_event)
+{
+       int ret = MM_ERROR_NONE;
+
+       scmirroring_debug_fenter();
+
+       scmirroring_retvm_if(uibc_event == NULL, SCMIRRORING_ERROR_INVALID_PARAMETER, "uibc_event is null");
+
+       ret = mm_wfd_sink_send_generic_mouse_event(handle, (MMWFDUIBCMouseEvent *)uibc_event);
+       if (ret != MM_ERROR_NONE) {
+               scmirroring_error("Fail to send mouse event_type[%d]", uibc_event->event_type);
+               return _scmirroring_error_convert(__func__, ret);
+       }
+
+       scmirroring_debug("Send mouse event_type[%d]", uibc_event->event_type);
+
+       return SCMIRRORING_ERROR_NONE;
+}
+
+int _scmirroring_sink_send_generic_key_event(MMHandleType handle, scmirroring_key_event_type_e event_type, unsigned short key_code_1, unsigned short key_code_2)
+{
+       int ret = MM_ERROR_NONE;
+
+       scmirroring_debug_fenter();
+
+       scmirroring_range_arg_check(event_type, SCMIRRORING_EVENT_KEY_DOWN, SCMIRRORING_EVENT_KEY_UP,
+               "invalid key event type");
+
+       ret = mm_wfd_sink_send_generic_key_event(handle, (int)event_type, (guint16)key_code_1, (guint16)key_code_2);
+       if (ret != MM_ERROR_NONE)       {
+               scmirroring_error("Fail to send scmirroring_event_type_e[%d] key_code_1[%u] key_code_2[%u]",
+                       event_type, key_code_1, key_code_2);
+               return _scmirroring_error_convert(__func__, ret);
+       }
+
+       scmirroring_debug("Send generic key event_type[%d] key_code_1[%u] key_code_2[%u]",
+               event_type, key_code_1, key_code_2);
+
+       return SCMIRRORING_ERROR_NONE;
+}
+
 int _scmirroring_src_send_cmd_to_server(int sock, const char *cmd)
 {
        int cmd_len = 0;