SET(INC_DIR include)
INCLUDE_DIRECTORIES(${INC_DIR})
-SET(dependents "dlog utilX elementary capi-base-common")
+OPTION(USE_DRI2 "Use dri2 in screenshot" OFF)
+
+IF (USE_DRI2)
+ ADD_DEFINITIONS(-DUSE_DRI2)
+ENDIF (USE_DRI2)
+
+SET(dependents "dlog utilX elementary capi-base-common x11 xv libdri2 xext xdamage libdrm libtbm xtst x11-xcb xcb xcb-dri3")
INCLUDE(FindPkgConfig)
pkg_check_modules(${fw_name} REQUIRED ${dependents})
ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution)
ADD_CUSTOM_COMMAND(
- DEPENDS clean
+ DEPENDS clean
COMMENT "distribution clean"
COMMAND find
- ARGS .
+ ARGS .
-not -name config.cmake -and \(
-name tester.c -or
-name Testing -or
/testcase/utc_efl_util_set_notification_window_level
+/testcase/utc_efl_util_input_generation
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <tet_api.h>
+#include <efl_util.h>
+#include <Elementary.h>
+#include <Ecore_X.h>
+
+#define API_INPUT_GENERATE_INIT "efl_util_input_generate_init"
+#define API_INPUT_GENERATE_KEY "efl_util_input_generate_key"
+#define API_INPUT_GENERATE_TOUCH "efl_util_input_generate_touch"
+
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+static void utc_efl_util_input_initialize_generator_negative(void);
+static void utc_efl_util_input_initialize_generator_positive(void);
+static void utc_efl_util_input_generate_key_negative(void);
+static void utc_efl_util_input_generate_key_positive(void);
+static void utc_efl_util_input_generate_touch_negative(void);
+static void utc_efl_util_input_generate_touch_positive(void);
+
+struct tet_testlist tet_testlist[] = {
+ { utc_efl_util_input_initialize_generator_negative, 1 },
+ { utc_efl_util_input_initialize_generator_positive, 1 },
+ { utc_efl_util_input_generate_key_negative, 1 },
+ { utc_efl_util_input_generate_key_positive, 1 },
+ { utc_efl_util_input_generate_touch_negative, 1 },
+ { utc_efl_util_input_generate_touch_positive, 1 },
+ { NULL, 0 },
+};
+
+
+static void startup(void)
+{
+}
+
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Negative test case of efl_util_input_initialize_generator()
+ */
+static void utc_efl_util_input_initialize_generator_negative(void)
+{
+ int ret;
+
+ ret = efl_util_input_initialize_generator(EFL_UTIL_INPUT_DEVTYPE_NONE);
+ if (ret != EFL_UTIL_ERROR_NONE)
+ {
+ dts_pass(API_INPUT_GENERATE_INIT, "passed");
+ }
+ else
+ {
+ dts_fail(API_INPUT_GENERATE_INIT, "failed");
+ efl_util_input_deinitialize_generator();
+ }
+}
+
+/**
+ * @brief Positive test case of efl_util_input_initialize_generator()
+ */
+static void utc_efl_util_input_initialize_generator_positive(void)
+{
+ int ret;
+
+ ret = efl_util_input_initialize_generator(EFL_UTIL_INPUT_DEVTYPE_ALL);
+ if (ret == EFL_UTIL_ERROR_NONE)
+ {
+ dts_pass(API_INPUT_GENERATE_INIT, "passed");
+ efl_util_input_deinitialize_generator();
+ }
+ else
+ {
+ dts_fail(API_INPUT_GENERATE_INIT, "failed");
+ }
+}
+
+
+/**
+ * @brief Negative test case of efl_util_input_generate_key()
+ */
+static void utc_efl_util_input_generate_key_negative(void)
+{
+ int ret;
+
+ ret = efl_util_input_initialize_generator(EFL_UTIL_INPUT_DEVTYPE_KEYBOARD);
+ if (ret != EFL_UTIL_ERROR_NONE)
+ {
+ dts_fail(API_INPUT_GENERATE_KEY, "failed to find keyboard device");
+ return;
+ }
+ ret = efl_util_input_generate_key("None", 1);
+ if (ret == EFL_UTIL_ERROR_INVALID_PARAMETER)
+ {
+ dts_pass(API_INPUT_GENERATE_KEY, "passed");
+ }
+ else
+ {
+ dts_fail(API_INPUT_GENERATE_KEY, "failed");
+ }
+ efl_util_input_deinitialize_generator();
+}
+
+/**
+ * @brief Positive test case of efl_util_input_generate_key()
+ */
+static void utc_efl_util_input_generate_key_positive(void)
+{
+ int ret;
+
+ ret = efl_util_input_initialize_generator(EFL_UTIL_INPUT_DEVTYPE_KEYBOARD);
+ if (ret != EFL_UTIL_ERROR_NONE)
+ {
+ dts_fail(API_INPUT_GENERATE_KEY, "failed to find keyboard device");
+ return;
+ }
+ ret = efl_util_input_generate_key("XF86Back", 1);
+ if (ret == EFL_UTIL_ERROR_INVALID_PARAMETER)
+ {
+ dts_fail(API_INPUT_GENERATE_KEY, "failed");
+ }
+ else
+ {
+ dts_pass(API_INPUT_GENERATE_KEY, "passed");
+ ret = efl_util_input_generate_key("XF86Back", 0);
+ }
+ efl_util_input_deinitialize_generator();
+}
+
+
+/**
+ * @brief Negative test case of efl_util_input_generate_touch()
+ */
+static void utc_efl_util_input_generate_touch_negative(void)
+{
+ int ret;
+
+ ret = efl_util_input_initialize_generator(EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN);
+ if (ret != EFL_UTIL_ERROR_NONE)
+ {
+ dts_fail(API_INPUT_GENERATE_TOUCH, "failed to find keyboard device");
+ return;
+ }
+ ret = efl_util_input_generate_touch(0, EFL_UTIL_INPUT_TOUCH_NONE, -1, -1);
+ if (ret == EFL_UTIL_ERROR_INVALID_PARAMETER)
+ {
+ dts_pass(API_INPUT_GENERATE_TOUCH, "passed");
+ }
+ else
+ {
+ dts_fail(API_INPUT_GENERATE_TOUCH, "failed");
+ }
+ efl_util_input_deinitialize_generator();
+}
+
+/**
+ * @brief Positive test case of efl_util_input_generate_touch()
+ */
+static void utc_efl_util_input_generate_touch_positive(void)
+{
+ int ret;
+
+ ret = efl_util_input_initialize_generator(EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN);
+ if (ret != EFL_UTIL_ERROR_NONE)
+ {
+ dts_fail(API_INPUT_GENERATE_TOUCH, "failed to find keyboard device");
+ return;
+ }
+ ret = efl_util_input_generate_touch(0, EFL_UTIL_INPUT_TOUCH_BEGIN, 100, 150);
+ if (ret == EFL_UTIL_ERROR_INVALID_PARAMETER)
+ {
+ dts_fail(API_INPUT_GENERATE_TOUCH, "failed");
+ }
+ else
+ {
+ dts_pass(API_INPUT_GENERATE_TOUCH, "passed");
+ ret = efl_util_input_generate_touch(0, EFL_UTIL_INPUT_TOUCH_END, 100, 150);
+ }
+ efl_util_input_deinitialize_generator();
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 __TIZEN_UI_EFL_UTIL_INPUT_DOC_H__
+#define __TIZEN_UI_EFL_UTIL_INPUT_DOC_H__
+
+ /**
+ * @ingroup CAPI_EFL_UTIL_MODULE
+ * @defgroup CAPI_EFL_UTIL_INPUT_MODULE EFL UTIL INPUT
+ * @brief Generate touch and key events
+ *
+ * @section CAPI_EFL_UTIL_INPUT_MODULE_HEADER Required Header
+ * \#include <efl_util.h>
+ *
+ * @section CAPI_EFL_UTIL_INPUT_MODULE_OVERVIEW Overview
+ * The EFL UTIL API provides functions to initialize/deinitialize input devices
+ * and to generation touch / key events.
+ *
+ */
+
+#endif /* __TIZEN_UI_EFL_UTIL_INPUT_DOC_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 __TIZEN_UI_EFL_UTIL_SCREENSHOT_DOC_H__
+#define __TIZEN_UI_EFL_UTIL_SCREENSHOT_DOC_H__
+
+ /**
+ * @ingroup CAPI_EFL_UTIL_MODULE
+ * @defgroup CAPI_EFL_UTIL_SCREENSHOT_MODULE EFL UTIL SCREENSHOT
+ * @brief Provides functions to capture screen shot
+ *
+ * @section CAPI_EFL_UTIL_SCREENSHOT_MODULE_HEADER Required Header
+ * \#include <efl_util.h>
+ *
+ * @section CAPI_EFL_UTIL_SCREENSHOT_MODULE_OVERVIEW Overview
+ * The EFL UTIL SCREENSHOT API provides functions to capture screenshot.
+ * Client can get screenshot image by efl_util_screenshot_take_tbm_surface
+ * API with tbm_surface handler.
+ *
+ */
+
+#endif /* __TIZEN_UI_EFL_UTIL_SCREENSHOT_DOC_H__ */
/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-
#ifndef __TIZEN_UI_EFL_UTIL_H__
#define __TIZEN_UI_EFL_UTIL_H__
#include <tizen.h>
#include <Evas.h>
+#include <tbm_surface.h>
#ifdef __cplusplus
extern "C" {
#endif
+#ifdef __GNUC__
+# if __GNUC__ >= 4
+# ifndef API
+# define API __attribute__ ((visibility("default")))
+# endif
+# endif
+#endif
+
/**
* @file efl_util.h
*/
* @{
*/
-
/**
* @brief Enumeration for EFL UTIL ERROR.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*/
typedef enum
{
- EFL_UTIL_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
- EFL_UTIL_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
- EFL_UTIL_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
- EFL_UTIL_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permisson denied */
- EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE = TIZEN_ERROR_EFL_UTIL | 0x01 /**< Window type not supported */
+ EFL_UTIL_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+ EFL_UTIL_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+ EFL_UTIL_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+ EFL_UTIL_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permisson denied */
+ EFL_UTIL_ERROR_NO_SUCH_DEVICE = TIZEN_ERROR_NO_SUCH_DEVICE, /**< @platform No such device or address (@b Since: 2.4) */
+ EFL_UTIL_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< @platform Function not implemented (@b Since: 2.4) */
+ EFL_UTIL_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< @platform Not supported (@b Since: 2.4) */
+ EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE = TIZEN_ERROR_EFL_UTIL | 0x01, /**< Window type not supported */
+ EFL_UTIL_ERROR_SCREENSHOT_INIT_FAIL = TIZEN_ERROR_EFL_UTIL | 0x02, /**< @platform Screenshot initialization fail (@b Since: 2.4) */
+ EFL_UTIL_ERROR_SCREENSHOT_EXECUTION_FAIL = TIZEN_ERROR_EFL_UTIL | 0x03 /**< @platform Screenshot execution fail (@b Since: 2.4) */
} efl_util_error_e;
-
/**
* @brief Enumeration of notification window's priority level.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
*/
typedef enum
{
- EFL_UTIL_NOTIFICATION_LEVEL_1, /**< Default notification level */
- EFL_UTIL_NOTIFICATION_LEVEL_2, /**< Higher notification level than default */
- EFL_UTIL_NOTIFICATION_LEVEL_3, /**< The highest notification level */
+ EFL_UTIL_NOTIFICATION_LEVEL_1, /**< Default notification level. (Deprecated since 2.4. Use EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT instead.) */
+ EFL_UTIL_NOTIFICATION_LEVEL_2, /**< Higher notification level than default. (Deprecated since 2.4. Use EFL_UTIL_NOTIFICATION_LEVEL_MEDIUM instead.) */
+ EFL_UTIL_NOTIFICATION_LEVEL_3, /**< The highest notification level. (Deprecated since 2.4. Use EFL_UTIL_NOTIFICATION_LEVEL_TOP instead.) */
+ EFL_UTIL_NOTIFICATION_LEVEL_NONE = -1, /**< No (reset) notification level. This value makes the window place in normal layer. (@b Since: 2.4) */
+ EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT = 10, /**< Default notification level. (@b Since: 2.4) */
+ EFL_UTIL_NOTIFICATION_LEVEL_MEDIUM = 20, /**< Higher notification level than default. (@b Since: 2.4) */
+ EFL_UTIL_NOTIFICATION_LEVEL_HIGH = 30, /**< Higher notification level than medium. (@b Since: 2.4) */
+ EFL_UTIL_NOTIFICATION_LEVEL_TOP = 40 /**< The highest notification level. (@b Since: 2.4) */
} efl_util_notification_level_e;
-
+/**
+ * @brief Enumeration of screen mode.
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+ EFL_UTIL_SCREEN_MODE_DEFAULT, /**< The mode which turns the screen off after a timeout. */
+ EFL_UTIL_SCREEN_MODE_ALWAYS_ON, /**< The mode which keeps the screen turned on. */
+} efl_util_screen_mode_e;
/**
* @brief Sets the priority level for the specified notification window, asynchronously.
* @remarks This API can be used for a notification type window only.
* @param[in] window The EFL window
* @param[in] level The notification window level
- * @return @c 0 on success,
- * otherwise a negative error value
+ * @return @c 0 on success, otherwise a negative error value
* @retval #EFL_UTIL_ERROR_NONE Successful
* @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE Window type not supported
*/
-int efl_util_set_notification_window_level (Evas_Object *window, efl_util_notification_level_e level);
-
+API int efl_util_set_notification_window_level(Evas_Object *window, efl_util_notification_level_e level);
/**
* @brief Gets the priority level for the specified notification window, asynchronously.
* @remarks This API can be used for a notification type window only.
* @param[in] window The EFL window
* @param[out] level The notification window level
- * @return @c 0 on success,
- * otherwise a negative error value
+ * @return @c 0 on success, otherwise a negative error value
* @retval #EFL_UTIL_ERROR_NONE Successful
* @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE Window type not supported
*/
-int efl_util_get_notification_window_level (Evas_Object *window, efl_util_notification_level_e* level);
-
+API int efl_util_get_notification_window_level(Evas_Object *window, efl_util_notification_level_e *level);
/**
* @brief Called when an error occurs for setting notification window level
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] window The EFL window
- * @param[in] error_code The error code (#EFL_UTIL_ERROR_PERMISSION_DENIED)
- * @param[in] user_data The user data passed from the callback registration function
+ * @param[in] window The EFL window
+ * @param[in] error_code The error code (#EFL_UTIL_ERROR_PERMISSION_DENIED)
+ * @param[in] user_data The user data passed from the callback registration function
* @see efl_util_set_notification_window_level_error_cb()
* @see efl_util_unset_notification_window_level_error_cb()
*/
typedef void (*efl_util_notification_window_level_error_cb)(Evas_Object *window, int error_code, void *user_data);
-
/**
* @brief Registers a callback function to be invoked when an error which set the notification level occurs.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- * @param[in] window The EFL window
- * @param[in] callback The callback function to register
+ * @param[in] window The EFL window
+ * @param[in] callback The callback function to register
* @param[in] user_data The user data to be passed to the callback function
- * @return @c 0 on success,
- * otherwise a negative error value
+ * @return @c 0 on success, otherwise a negative error value
* @retval #EFL_UTIL_ERROR_NONE Successful
* @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #EFL_UTIL_ERROR_OUT_OF_MEMORY Out of memory
- * @post efl_util_notification_window_level_error_cb() will be invoked.
+ * @post efl_util_notification_window_level_error_cb() will be invoked.
* @see efl_util_unset_notification_window_level_error_cb()
* @see efl_util_notification_window_level_error_cb()
*/
-int efl_util_set_notification_window_level_error_cb(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data);
-
+API int efl_util_set_notification_window_level_error_cb(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data);
/**
* @brief Unregisters the callback function.
* @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
* @param[in] window The EFL window
- * @return @c 0 on success,
- * otherwise a negative error value
+ * @return @c 0 on success, otherwise a negative error value
* @retval #EFL_UTIL_ERROR_NONE Successful
* @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
* @see efl_util_set_notification_window_level_error_cb()
*/
-int efl_util_unset_notification_window_level_error_cb(Evas_Object *window);
+API int efl_util_unset_notification_window_level_error_cb(Evas_Object *window);
+
+/**
+ * @brief Sets the alpha window's visual state to opaque state
+ * @details This API sets the alpha window's visual state to opaque state.
+ * If the alpha window sets the visual state to the opaque,
+ * then the window manager could handle it as the opaque window while calculating visibility.
+ * This API will have no effect when used by a non-alpha window.
+ * @since_tizen 2.4
+ * @param[in] window The EFL window
+ * @param[in] opaque The value that indicates whether the window has set a visual state to opaque (0: unset, 1: set)
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #EFL_UTIL_ERROR_NONE Successful
+ * @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+API int efl_util_set_window_opaque_state(Evas_Object *window, int opaque);
+/**
+ * @brief Sets the window's screen mode.
+ * @details This API is useful when the application need to keep the display turned on.
+ * If the application set the mode to #EFL_UTIL_SCREEN_MODE_ALWAYS_ON to its window and the window is shown wholly or partially,
+ * the window manager requests the display system to keep the display on as long as the window is shown.
+ * If the window is no longer shown, then the window manger request the display system to go back to normal operation.
+ * Default screen mode of window is #EFL_UTIL_SCREEN_MODE_DEFAULT.
+ * @since_tizen 2.4
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/display
+ * @remarks This API needs the privilege.
+ * If the application which is not get the privilege use this API, the window manager generates the permission deny error.
+ * The application can notice this error if it set the callback function using the efl_util_set_window_screen_mode_error_cb().
+ * @param[in] window The EFL window
+ * @param[in] mode The screen mode
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #EFL_UTIL_ERROR_NONE Successful
+ * @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+API int efl_util_set_window_screen_mode(Evas_Object *window, efl_util_screen_mode_e mode);
+
+/**
+ * @brief Gets the screen mode of the specified window.
+ * @since_tizen 2.4
+ * @param[in] window The EFL window
+ * @param[out] mode The screen mode
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #EFL_UTIL_ERROR_NONE Successful
+ * @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+API int efl_util_get_window_screen_mode(Evas_Object *window, efl_util_screen_mode_e *mode);
+
+/**
+ * @brief Called when an error occurs for setting window's screen mode
+ * @since_tizen 2.4
+ * @param[in] window The EFL window
+ * @param[in] error_code The error code (#EFL_UTIL_ERROR_PERMISSION_DENIED)
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see efl_util_set_window_screen_mode_error_cb()
+ * @see efl_util_unset_window_screen_mode_error_cb()
+ */
+typedef void (*efl_util_window_screen_mode_error_cb)(Evas_Object *window, int error_code, void *user_data);
+
+/**
+ * @brief Registers a callback function to be invoked when an error which set the screen mode.
+ * @since_tizen 2.4
+ * @param[in] window The EFL window
+ * @param[in] callback The callback function to register
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #EFL_UTIL_ERROR_NONE Successful
+ * @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #EFL_UTIL_ERROR_OUT_OF_MEMORY Out of memory
+ * @post efl_util_window_screen_mode_error_cb() will be invoked.
+ * @see efl_util_unset_window_screen_mode_error_cb()
+ * @see efl_util_window_screen_mode_error_cb()
+ */
+API int efl_util_set_window_screen_mode_error_cb(Evas_Object *window, efl_util_window_screen_mode_error_cb callback, void *user_data);
+
+/**
+ * @brief Unregisters the callback function.
+ * @since_tizen 2.4
+ * @param[in] window The EFL window
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #EFL_UTIL_ERROR_NONE Successful
+ * @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see efl_util_set_window_screen_mode_error_cb()
+ */
+API int efl_util_unset_window_screen_mode_error_cb(Evas_Object *window);
/**
* @}
*/
+/**
+ * @addtogroup CAPI_EFL_UTIL_INPUT_MODULE
+ * @{
+ */
+
+ /**
+ * @platform
+ * @brief Definition for the input generator handle.
+ * @since_tizen 2.4
+ */
+
+typedef struct _efl_util_inputgen_h *efl_util_inputgen_h;
+
+/**
+ * @platform
+ * @brief Enumeration of device type generated events.
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+ EFL_UTIL_INPUT_DEVTYPE_NONE = 0x0,
+ EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN = (1 << 0), /**< Touch screen device */
+ EFL_UTIL_INPUT_DEVTYPE_KEYBOARD = (1 << 1), /**< Keyboard device */
+ EFL_UTIL_INPUT_DEVTYPE_ALL = EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN |
+ EFL_UTIL_INPUT_DEVTYPE_KEYBOARD, /**< Both of touch screen and keyboard device */
+ EFL_UTIL_INPUT_DEVTYPE_MAX = (1 << 10)
+} efl_util_input_device_type_e;
+
+/**
+ * @platform
+ * @brief Enumeration of touch event types.
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+ EFL_UTIL_INPUT_TOUCH_NONE,
+ EFL_UTIL_INPUT_TOUCH_BEGIN, /**< Finger press. It is same a behavior put your finger on touch screen */
+ EFL_UTIL_INPUT_TOUCH_UPDATE, /**< Finger move. It is same a behavior move your finger on touch screen */
+ EFL_UTIL_INPUT_TOUCH_END, /**< Finger release. It is same a behavior release your finger on touch screen */
+ EFL_UTIL_INPUT_TOUCH_MAX = 10
+} efl_util_input_touch_type_e;
+
+/**
+ * @platform
+ * @brief Initializes system and check input generate functions are supported, open devices generated events.
+ * @since_tizen 2.4
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/inputgenerator
+ * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section.
+ * @param[in] dev_type The device type want to generate events (ex> EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN, EFL_UTIL_INPUT_DEVTYPE_KEYBOARD, EFL_UTIL_INPUT_DEVTYPE_ALL)
+ * @return #efl_util_inputgen_h on success, otherwise @c NULL
+ * @retval #efl_util_inputgen_h The input generator handle
+ * @exception #EFL_UTIL_ERROR_NONE Successful
+ * @exception #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #EFL_UTIL_ERROR_NO_SUCH_DEVICE No such device or address
+ * @exception #EFL_UTIL_ERROR_INVALID_OPERATION Function not implemented
+ * @exception #EFL_UTIL_ERROR_OUT_OF_MEMORY Memory allocation failure
+ * @see efl_util_input_deinitialize_generator()
+ */
+API efl_util_inputgen_h efl_util_input_initialize_generator(efl_util_input_device_type_e dev_type);
+
+/**
+ * @platform
+ * @brief Deinitializes system and close opened devices.
+ * @since_tizen 2.4
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/inputgenerator
+ * @param[in] inputgen_h The efl_util_inputgen_h handle
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #EFL_UTIL_ERROR_NONE Successful
+ * @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see efl_util_input_initialize_generator()
+ */
+API int efl_util_input_deinitialize_generator(efl_util_inputgen_h inputgen_h);
+
+/**
+ * @platform
+ * @brief Generates all of key events using a opened device.
+ * @since_tizen 2.4
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/inputgenerator
+ * @param[in] key_name The key name want to generate
+ * @param[in] pressed The value that select key press or release (0: release, 1: press)
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #EFL_UTIL_ERROR_NONE Successful
+ * @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #EFL_UTIL_ERROR_PERMISSION_DENIED Has no permission to generate key
+ */
+API int efl_util_input_generate_key(efl_util_inputgen_h inputgen_h, const char *key_name, int pressed);
+
+/**
+ * @platform
+ * @brief Generates a touch event using a opened device.
+ * @since_tizen 2.4
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/inputgenerator
+ * @param[in] idx The index of touched finger
+ * @param[in] efl_util_input_touch_type_e The touch type (ex> EFL_UTIL_INPUT_TOUCH_BEGIN, EFL_UTIL_INPUT_TOUCH_UPDATE, EFL_UTIL_INPUT_TOUCH_END)
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #EFL_UTIL_ERROR_NONE Successful
+ * @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #EFL_UTIL_ERROR_PERMISSION_DENIED Has no permission to generate touch
+ */
+API int efl_util_input_generate_touch(efl_util_inputgen_h inputgen_h, int idx, efl_util_input_touch_type_e touch_type, int x, int y);
+
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup CAPI_EFL_UTIL_SCREENSHOT_MODULE
+ * @{
+ */
+
+/**
+ * @platform
+ * @brief Definition for the screenshot handle.
+ * @since_tizen 2.4
+ */
+typedef struct _efl_util_screenshot_h * efl_util_screenshot_h;
+
+/**
+ * @platform
+ * @brief Initializes the screenshot.
+ * @since_tizen 2.4
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/screenshot
+ * @remarks The specific error code can be obtained using the get_last_result().
+ * method. Error codes are dedescribed in Exception section.
+ * @param[in] width The width of the screenshot surface
+ * @param[in] height The height of the screenshot surface
+ * @return #efl_util_screenshot_h on success, otherwise @c NULL
+ * @retval #efl_util_screenshot_h The screenshot handle
+ * @exception #EFL_UTIL_ERROR_NONE Successful
+ * @exception #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #EFL_UTIL_ERROR_OUT_OF_MEMORY Memory allocation failure
+ * @exception #EFL_UTIL_ERROR_SCREENSHOT_INIT_FAIL Initialization failure
+ * @see efl_util_screenshot_deinitialize()
+ */
+API efl_util_screenshot_h efl_util_screenshot_initialize(int width, int height);
+
+/**
+ * @platform
+ * @brief Takes a screenshot and get a tbm_surface handle.
+ * @since_tizen 2.4
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/screenshot
+ * @remarks The specific error code can be obtained using the get_last_result().
+ * The tbm_surface_h must be free by caller.
+ * @param[in] screenshot The efl_util_screenshot_h handle
+ * @return #tbm_surface_h on success, otherwise @c NULL
+ * @retval #tbm_surface_h The TBM surface handle
+ * @exception #EFL_UTIL_ERROR_NONE Successful
+ * @exception #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #EFL_UTIL_ERROR_SCREENSHOT_EXECUTION_FAIL Execution failure
+ * @exception #EFL_UTIL_ERROR_PERMISSION_DENIED Permission denied
+ * @see efl_util_screenshot_initialize()
+ * @see efl_util_screenshot_deinitialize()
+ */
+API tbm_surface_h efl_util_screenshot_take_tbm_surface(efl_util_screenshot_h screenshot);
+
+/**
+ * @platform
+ * @brief Deinitializes the screenshot.
+ * @since_tizen 2.4
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/screenshot
+ * @param[in] screenshot The efl_util_screenshot_h handle
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #EFL_UTIL_ERROR_NONE Successful
+ * @retval #EFL_UTIL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see efl_util_screenshot_initialize()
+ */
+API int efl_util_screenshot_deinitialize(efl_util_screenshot_h screenshot);
+
+/**
+ * @}
+ */
#ifdef __cplusplus
}
#endif
-#endif /* __TIZEN_UI_EFL_UTIL_H__ */
+#endif /* __TIZEN_UI_EFL_UTIL_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 __TIZEN_UI_EFL_UTIL_PRIVATE_H__
+#define __TIZEN_UI_EFL_UTIL_PRIVATE_H__
+
+#include <efl_util.h>
+#include <Ecore_X.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/XInput.h>
+
+#define TOUCH_DEVICE_NAME "Virtual core XTEST touch"
+#define HWKEY_DEVICE_NAME "Virtual core XTEST functionkeys"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+typedef struct
+{
+ Ecore_X_Display *dpy;
+ int devid_key;
+ int devid_touch;
+ XDevice *devInfo_key;
+ XDevice *devInfo_touch;
+}_input_generate_info;
+
+struct _efl_util_inputgen_h
+{
+ _input_generate_info input_generate_info;
+};
+
+static int _efl_util_input_initialize_xi2_system(Ecore_X_Display *dpy, int *opcode, int *event, int *error);
+static int _efl_util_input_initialize_input_generator(efl_util_inputgen_h inputgen_h);
+static void _efl_util_input_get_device_id(efl_util_inputgen_h inputgen_h, efl_util_input_device_type_e devtype);
+static int _efl_util_input_open_generate_device(efl_util_inputgen_h inputgen_h, efl_util_input_device_type_e devtype);
+static void _efl_util_input_close_generate_device(efl_util_inputgen_h inputgen_h);
+static int _efl_util_input_keyname_to_keycode(Ecore_X_Display *dpy, const char * name);
+static int _efl_util_input_generate_key_event(Ecore_X_Display *dpy, XDevice *key_device_info, int keycode, int pressed);
+static int _efl_util_input_generate_touch_event(Ecore_X_Display *dpy, XDevice *touch_device_info, int touchid, efl_util_input_touch_type_e type, int x, int y);
+static int _efl_util_input_find_all_request_devices(efl_util_inputgen_h inputgen_h, efl_util_input_device_type_e request_type);
+static void _efl_util_input_deinitialize_input_generator(efl_util_inputgen_h inputgen_h);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __TIZEN_UI_EFL_UTIL_PRIVATE_H__
/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
extern "C" {
#endif
+#define LOG_TAG "TIZEN_N_EFL_UTIL"
+
typedef struct _notification_error_cb_info
{
Evas_Object *window;
Name: capi-ui-efl-util
Summary: An EFL utility library in SLP C API
-Version: 0.1.5
+Version: 0.2.6
Release: 1
Group: TO_BE/FILLED_IN
-License: TO BE FILLED IN
+License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
BuildRequires: cmake
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(x11)
+BuildRequires: pkgconfig(xtst)
BuildRequires: pkgconfig(utilX)
BuildRequires: pkgconfig(ecore-x)
BuildRequires: pkgconfig(elementary)
BuildRequires: pkgconfig(capi-base-common)
+BuildRequires: pkgconfig(libdri2)
+BuildRequires: pkgconfig(dri2proto)
+BuildRequires: pkgconfig(xext)
+BuildRequires: pkgconfig(xv)
+BuildRequires: pkgconfig(xdamage)
+BuildRequires: pkgconfig(libdrm)
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(x11-xcb)
+BuildRequires: pkgconfig(xcb)
+BuildRequires: pkgconfig(xcb-dri3)
%description
%build
MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
-%cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
+%cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER} -DUSE_DRI2=ON
make %{?jobs:-j%jobs}
%install
/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
#define LOG_TAG "TIZEN_N_EFL_UTIL"
#include <efl_util.h>
-#include <efl_util_private.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <Elementary.h>
#include <Ecore_X.h>
#include <utilX.h>
-
-int efl_util_set_notification_window_level (Evas_Object* window, efl_util_notification_level_e level)
-{
- Ecore_X_Window_Type window_type;
-
- if(window == NULL)
- {
- return EFL_UTIL_ERROR_INVALID_PARAMETER;
- }
-
- Ecore_X_Window xwin = elm_win_xwindow_get(window);
-
- if(ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
- {
- // success to get window type
- if(window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
- {
- // given EFL window's type is not notification type.
- return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
- }
- }
- else
- {
- // fail to get window type
- return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
- }
-
- // this api doesn't have return type
- if(level == EFL_UTIL_NOTIFICATION_LEVEL_1) {
- utilx_set_system_notification_level(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_LEVEL_LOW);
- }
- else if(level == EFL_UTIL_NOTIFICATION_LEVEL_2)
- {
- utilx_set_system_notification_level(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_LEVEL_NORMAL);
- }
- else if(level == EFL_UTIL_NOTIFICATION_LEVEL_3)
- {
- utilx_set_system_notification_level(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_LEVEL_HIGH);
- }
- else
- {
- return EFL_UTIL_ERROR_INVALID_PARAMETER;
- }
-
- return EFL_UTIL_ERROR_NONE;
-}
-
-
-
-int efl_util_get_notification_window_level (Evas_Object* window, efl_util_notification_level_e* level)
+API int efl_util_set_window_opaque_state(Evas_Object *window, int opaque)
{
- Ecore_X_Window_Type window_type;
-
- Utilx_Notification_Level utilx_level;
-
- if(window == NULL)
- {
- return EFL_UTIL_ERROR_INVALID_PARAMETER;
- }
-
- Ecore_X_Window xwin = elm_win_xwindow_get(window);
-
- if(ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
- {
- // success to get window type
- if(window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
- {
- // given EFL window's type is not notification type.
- return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
- }
-
- utilx_level = utilx_get_system_notification_level (ecore_x_display_get(), xwin);
-
- if(utilx_level == UTILX_NOTIFICATION_LEVEL_LOW)
- {
- *level = EFL_UTIL_NOTIFICATION_LEVEL_1;
- }
- else if(utilx_level == UTILX_NOTIFICATION_LEVEL_NORMAL)
- {
- *level = EFL_UTIL_NOTIFICATION_LEVEL_2;
- }
- else if(utilx_level == UTILX_NOTIFICATION_LEVEL_HIGH)
- {
- *level = EFL_UTIL_NOTIFICATION_LEVEL_3;
- }
- else
- {
- return EFL_UTIL_ERROR_INVALID_PARAMETER;
- }
- }
- else
- {
- // fail to get window type
- return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
- }
-
- return EFL_UTIL_ERROR_NONE;
-}
-
-
-
-int efl_util_set_notification_window_level_error_cb(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data)
-{
- Eina_Bool ret = EINA_FALSE;
-
- if (!window) return EFL_UTIL_ERROR_INVALID_PARAMETER;
-
- ret = _efl_util_notification_info_add(window, callback, user_data);
- if (ret)
- {
- if (!_noti_level_access_result_atom)
- _noti_level_access_result_atom = ecore_x_atom_get("_E_NOTIFICATION_LEVEL_ACCESS_RESULT");
-
- if (!_noti_level_access_result_handler)
- _noti_level_access_result_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _efl_util_client_message, NULL);
- _noti_handler_count++;
-
- return EFL_UTIL_ERROR_NONE;
- }
- else
- {
- return EFL_UTIL_ERROR_OUT_OF_MEMORY;
- }
-}
-
-
-
-int efl_util_unset_notification_window_level_error_cb(Evas_Object *window)
-{
- Eina_Bool ret = EINA_FALSE;
-
- if (!window) return EFL_UTIL_ERROR_INVALID_PARAMETER;
-
- ret = _efl_util_notification_info_del(window);
- if (ret)
- {
- _noti_handler_count--;
- if (_noti_handler_count == 0)
- {
- if (_noti_level_access_result_handler)
- {
- ecore_event_handler_del(_noti_level_access_result_handler);
- _noti_level_access_result_handler = NULL;
- }
- }
- return EFL_UTIL_ERROR_NONE;
- }
- else
- {
- return EFL_UTIL_ERROR_INVALID_PARAMETER;
- }
-}
+ int ret;
+ Ecore_X_Window xwin;
+ if(window == NULL)
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+ xwin = elm_win_xwindow_get(window);
-static Eina_Bool _efl_util_client_message(void *data, int type, void *event)
-{
- Ecore_X_Event_Client_Message *ev;
-
- ev = event;
- if (!ev) return ECORE_CALLBACK_PASS_ON;
-
- if (ev->message_type == _noti_level_access_result_atom)
- {
- Ecore_X_Window xwin;
- xwin = ev->win;
-
- notification_error_cb_info *cb_info = NULL;
- cb_info = _notification_error_cb_info_find_by_xwin(xwin);
- if (cb_info)
- {
- int access = ev->data.l[1];
- if (access == 0) // permission denied
- {
- if (cb_info->err_cb)
- {
- cb_info->err_cb(cb_info->window, EFL_UTIL_ERROR_PERMISSION_DENIED, cb_info->user_data);
- }
- }
- }
- }
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-
-
-static notification_error_cb_info *_notification_error_cb_info_find_by_xwin(Ecore_X_Window xwin)
-{
- Eina_List *l;
- notification_error_cb_info* temp;
- Ecore_X_Window temp_xwin;
-
- EINA_LIST_FOREACH(_g_notification_error_cb_info_list, l, temp)
- {
- if (temp->window)
- {
- temp_xwin = elm_win_xwindow_get(temp->window);
- if (xwin == temp_xwin)
- {
- return temp;
- }
- }
- }
-
- return NULL;
-}
-
-
-
-static notification_error_cb_info *_notification_error_cb_info_find(Evas_Object *window)
-{
- Eina_List *l;
- notification_error_cb_info* temp;
-
- EINA_LIST_FOREACH(_g_notification_error_cb_info_list, l, temp)
- {
- if (temp->window == window)
- {
- return temp;
- }
- }
-
- return NULL;
-}
-
-
-
-static Eina_Bool _efl_util_notification_info_add(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data)
-{
- notification_error_cb_info* _err_info = _notification_error_cb_info_find(window);
-
- if (_err_info)
- {
- _g_notification_error_cb_info_list = eina_list_remove(_g_notification_error_cb_info_list, _err_info);
- free(_err_info);
- _err_info = NULL;
- }
-
- _err_info = (notification_error_cb_info*)calloc(1, sizeof(notification_error_cb_info));
- if (!_err_info)
- {
- return EINA_FALSE;
- }
- _err_info->window = window;
- _err_info->err_cb = callback;
- _err_info->user_data = user_data;
-
- _g_notification_error_cb_info_list = eina_list_append(_g_notification_error_cb_info_list, _err_info);
-
- return EINA_TRUE;
-}
-
-
-
-static Eina_Bool _efl_util_notification_info_del(Evas_Object *window)
-{
- notification_error_cb_info* _err_info = _notification_error_cb_info_find(window);
- if (!_err_info)
- {
- return EINA_FALSE;
- }
-
- _g_notification_error_cb_info_list = eina_list_remove(_g_notification_error_cb_info_list, _err_info);
- free(_err_info);
+ if (opaque == 0)
+ ret = utilx_set_window_opaque_state(ecore_x_display_get(), xwin, UTILX_OPAQUE_STATE_OFF);
+ else if (opaque == 1)
+ ret = utilx_set_window_opaque_state(ecore_x_display_get(), xwin, UTILX_OPAQUE_STATE_ON);
+ else
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
- return EINA_TRUE;
+ if (!ret)
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ else
+ return EFL_UTIL_ERROR_NONE;
}
--- /dev/null
+/*
+ * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 LOG_TAG "TIZEN_N_EFL_UTIL_INPUT"
+
+#include <efl_util.h>
+#include <efl_util_input_private.h>
+#include <string.h>
+#include <X11/extensions/XTest.h>
+#include <X11/extensions/XInput2.h>
+
+API efl_util_inputgen_h
+efl_util_input_initialize_generator(efl_util_input_device_type_e dev_type)
+{
+ int res = EFL_UTIL_ERROR_NONE;
+ efl_util_inputgen_h inputgen_h;
+
+ inputgen_h = (efl_util_inputgen_h)calloc(1, sizeof(struct _efl_util_inputgen_h));
+ if (!inputgen_h)
+ {
+ fprintf(stderr, "Failed to allocate memory for efl_util_inputgen_h\n");
+ set_last_result(EFL_UTIL_ERROR_OUT_OF_MEMORY);
+ goto out;
+ }
+
+ /* initialize system */
+ res = _efl_util_input_initialize_input_generator(inputgen_h);
+ if (EFL_UTIL_ERROR_NONE != res)
+ {
+ fprintf(stderr, "Failed to initialize input generator system\n");
+ set_last_result(res);
+ free(inputgen_h);
+ inputgen_h = NULL;
+ goto out;
+ }
+
+ /* open a touch device */
+ _efl_util_input_get_device_id(inputgen_h, dev_type);
+ res = _efl_util_input_open_generate_device(inputgen_h, dev_type);
+ if (EFL_UTIL_ERROR_NONE != res)
+ {
+ fprintf(stderr, "Failed to find device\n");
+ set_last_result(res);
+ free(inputgen_h);
+ inputgen_h = NULL;
+ goto out;
+ }
+
+ set_last_result(res);
+
+out:
+ return inputgen_h;
+}
+
+API int
+efl_util_input_deinitialize_generator(efl_util_inputgen_h inputgen_h)
+{
+ if (!inputgen_h)
+ {
+ fprintf(stderr, "No initialized efl_util_inputgen_h\n");
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ _efl_util_input_deinitialize_input_generator(inputgen_h);
+
+ return EFL_UTIL_ERROR_NONE;
+}
+
+API int
+efl_util_input_generate_key(efl_util_inputgen_h inputgen_h, const char *key_name, int pressed)
+{
+ int keycode = 0;
+
+ if (!inputgen_h)
+ {
+ fprintf(stderr, "No initialized efl_util_inputgen_h\n");
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ /* get a keycode using keysym */
+ keycode = _efl_util_input_keyname_to_keycode(inputgen_h->input_generate_info.dpy, key_name);
+ if (0 >= keycode)
+ {
+ fprintf(stderr, "Invalide keyname(%s) keycode(%d)\n", key_name, keycode);
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ /* send a key event */
+ return _efl_util_input_generate_key_event(inputgen_h->input_generate_info.dpy, inputgen_h->input_generate_info.devInfo_key, keycode, pressed);
+}
+
+API int
+efl_util_input_generate_touch(efl_util_inputgen_h inputgen_h, int idx, efl_util_input_touch_type_e touch_type, int x, int y)
+{
+ if (!inputgen_h)
+ {
+ fprintf(stderr, "No initialized efl_util_inputgen_h\n");
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (idx < 0 || x < 0 || y < 0)
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ if (touch_type <= EFL_UTIL_INPUT_TOUCH_NONE || touch_type >= EFL_UTIL_INPUT_TOUCH_MAX)
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+
+ return _efl_util_input_generate_touch_event(inputgen_h->input_generate_info.dpy, inputgen_h->input_generate_info.devInfo_touch, idx, touch_type, x, y);
+}
+
+static int
+_efl_util_input_initialize_xi2_system(Ecore_X_Display *dpy, int *opcode, int *event, int *error)
+{
+ int major=XI_2_Major, minor=XI_2_Minor;
+
+ /* X Input Extension available? */
+ if(!XQueryExtension((Display *)dpy, "XInputExtension", opcode, event, error))
+ {
+ fprintf(stderr, "X Input extension not available\n");
+ return 0;
+ }
+
+ /* Which version of XI2? We support 2.0 */
+ if (XIQueryVersion((Display *)dpy, &major, &minor) == BadRequest)
+ {
+ fprintf(stderr, "XI2 not available. Server supports %d.%d\n", major, minor);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+_efl_util_input_initialize_input_generator(efl_util_inputgen_h inputgen_h)
+{
+ int opcode=0, event=0, error=0;
+ /* Init the ecore_x system */
+ if(!ecore_x_init(NULL)) goto out;
+
+ /* Init global struct valuables */
+ inputgen_h->input_generate_info.dpy = NULL;
+ inputgen_h->input_generate_info.devInfo_key = NULL;
+ inputgen_h->input_generate_info.devInfo_touch = NULL;
+ inputgen_h->input_generate_info.devid_key = 0;
+ inputgen_h->input_generate_info.devid_touch = 0;
+
+ /* get display id */
+ inputgen_h->input_generate_info.dpy= ecore_x_display_get();
+ if(!inputgen_h->input_generate_info.dpy)
+ {
+ fprintf(stderr, "failed to get dpy\n");
+ goto out;
+ }
+
+ /* initialize xi2 system */
+ if(!_efl_util_input_initialize_xi2_system(inputgen_h->input_generate_info.dpy, &opcode, &event, &error))
+ {
+ fprintf(stderr, "failed to initialize xi2 system\n");
+ goto out;
+ }
+
+ return EFL_UTIL_ERROR_NONE;
+out:
+ return EFL_UTIL_ERROR_INVALID_OPERATION;
+}
+
+/* query X devices and find wanted device's id (such as a touch device and a hwkey device) */
+static void
+_efl_util_input_get_device_id(efl_util_inputgen_h inputgen_h, efl_util_input_device_type_e devtype)
+{
+ XIDeviceInfo *info=NULL;
+ int i, ndevices;
+
+ if (devtype <= EFL_UTIL_INPUT_DEVTYPE_NONE || EFL_UTIL_INPUT_DEVTYPE_MAX <= devtype)
+ {
+ fprintf(stderr, "Invalid devtype(%d)\n", devtype);
+ return;
+ }
+
+ info = XIQueryDevice(inputgen_h->input_generate_info.dpy, XIAllDevices, &ndevices);
+
+ for(i=0; i<ndevices; i++)
+ {
+ XIDeviceInfo *dev = &info[i];
+ switch(dev->use)
+ {
+ case XISlavePointer:
+ if ((0 == inputgen_h->input_generate_info.devid_touch) &&
+ (devtype & EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN) &&
+ !strncmp(dev->name, TOUCH_DEVICE_NAME, strlen(TOUCH_DEVICE_NAME)))
+ {
+ fprintf(stderr, "pointer device id: %d, name: %s, attachment: %d\n", dev->deviceid, dev->name, dev->attachment);
+ inputgen_h->input_generate_info.devid_touch = dev->deviceid;
+
+ if (_efl_util_input_find_all_request_devices(inputgen_h, devtype))
+ {
+ goto finish;
+ }
+ }
+ break;
+ case XISlaveKeyboard:
+ if ((devtype & EFL_UTIL_INPUT_DEVTYPE_KEYBOARD) &&
+ !strncmp(dev->name, HWKEY_DEVICE_NAME, strlen(HWKEY_DEVICE_NAME)))
+ {
+ fprintf(stderr, "keyboard device id: %d, name: %s, attachment: %d\n", dev->deviceid, dev->name, dev->attachment);
+ inputgen_h->input_generate_info.devid_key = dev->deviceid;
+
+ if (_efl_util_input_find_all_request_devices(inputgen_h, devtype))
+ {
+ goto finish;
+ }
+ }
+ break;
+ case XIFloatingSlave:
+ if ((devtype & EFL_UTIL_INPUT_DEVTYPE_KEYBOARD) &&
+ !strncmp(dev->name, HWKEY_DEVICE_NAME, strlen(HWKEY_DEVICE_NAME)))
+ {
+ fprintf(stderr, "floating device id: %d, name: %s, attachment: %d\n", dev->deviceid, dev->name, dev->attachment);
+ inputgen_h->input_generate_info.devid_key = dev->deviceid;
+
+ if (_efl_util_input_find_all_request_devices(inputgen_h, devtype))
+ {
+ goto finish;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+finish:
+ if (info) free(info);
+}
+
+static int
+_efl_util_input_open_generate_device(efl_util_inputgen_h inputgen_h, efl_util_input_device_type_e devtype)
+{
+ XDevice *tmp_device_key = NULL, *tmp_device_touch = NULL;
+ int res = EFL_UTIL_ERROR_NO_SUCH_DEVICE;
+
+ if (devtype & EFL_UTIL_INPUT_DEVTYPE_KEYBOARD)
+ {
+ tmp_device_key = XOpenDevice(inputgen_h->input_generate_info.dpy, inputgen_h->input_generate_info.devid_key);
+ if (!tmp_device_key)
+ {
+ fprintf(stderr, "failed to open device (id: %d)\n", inputgen_h->input_generate_info.devid_key);
+ res = EFL_UTIL_ERROR_NO_SUCH_DEVICE;
+ goto out;
+ }
+ else
+ {
+ inputgen_h->input_generate_info.devInfo_key = tmp_device_key;
+ res = EFL_UTIL_ERROR_NONE;
+ }
+ }
+
+ if (devtype & EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN)
+ {
+ tmp_device_touch = XOpenDevice(inputgen_h->input_generate_info.dpy, inputgen_h->input_generate_info.devid_touch);
+ if (!tmp_device_touch)
+ {
+ fprintf(stderr, "failed to open device (id: %d)\n", inputgen_h->input_generate_info.devid_touch);
+ res = EFL_UTIL_ERROR_NO_SUCH_DEVICE;
+ goto out;
+ }
+ else
+ {
+ inputgen_h->input_generate_info.devInfo_touch = tmp_device_touch;
+ res = EFL_UTIL_ERROR_NONE;
+ }
+ }
+
+out:
+ return res;
+}
+
+static void
+_efl_util_input_close_generate_device(efl_util_inputgen_h inputgen_h)
+{
+ if (inputgen_h->input_generate_info.devInfo_key)
+ {
+ XCloseDevice(inputgen_h->input_generate_info.dpy, inputgen_h->input_generate_info.devInfo_key);
+ inputgen_h->input_generate_info.devInfo_key = NULL;
+ inputgen_h->input_generate_info.devid_key = 0;
+ }
+ if (inputgen_h->input_generate_info.devInfo_touch)
+ {
+ XCloseDevice(inputgen_h->input_generate_info.dpy, inputgen_h->input_generate_info.devInfo_touch);
+ inputgen_h->input_generate_info.devInfo_touch = NULL;
+ inputgen_h->input_generate_info.devid_touch = 0;
+ }
+}
+
+static int
+_efl_util_input_keyname_to_keycode(Ecore_X_Display *dpy, const char * name)
+{
+ int keycode;
+ KeySym keysym;
+
+ if (!strncmp(name, "Keycode-", 8))
+ {
+ keycode = atoi(name + 8);
+ }
+ else
+ {
+ keysym = XStringToKeysym(name);
+ if (keysym == NoSymbol) return 0;
+ keycode = XKeysymToKeycode((Display *)dpy, XStringToKeysym(name));
+ }
+
+ return keycode;
+}
+
+static int
+_efl_util_input_generate_key_event(Ecore_X_Display *dpy, XDevice *key_device_info, int keycode, int pressed)
+{
+ int res = -1;
+ Bool press = (pressed==1)?True:False;
+
+ res = XTestFakeDeviceKeyEvent((Display *)dpy, key_device_info, keycode, press, NULL, 0, CurrentTime);
+ XSync((Display *)dpy, False);
+
+ if (res == 1)
+ {
+ return EFL_UTIL_ERROR_NONE;
+ }
+ return EFL_UTIL_ERROR_PERMISSION_DENIED;
+}
+
+static int
+_efl_util_input_generate_touch_event(Ecore_X_Display *dpy, XDevice *touch_device_info, int touchid, efl_util_input_touch_type_e type, int x, int y)
+{
+ int touch_axis[2]={0,0};
+ int res = -1;
+
+ touch_axis[0] = x;
+ touch_axis[1] = y;
+
+ switch(type)
+ {
+ case EFL_UTIL_INPUT_TOUCH_BEGIN:
+ res = XTestFakeDeviceTouchEvent(dpy, touch_device_info, touchid, True, touch_axis, 2, CurrentTime);
+ break;
+ case EFL_UTIL_INPUT_TOUCH_UPDATE:
+ res = XTestFakeDeviceTouchUpdateEvent(dpy, touch_device_info, touchid, touch_axis, 2, CurrentTime);
+ break;
+ case EFL_UTIL_INPUT_TOUCH_END:
+ res = XTestFakeDeviceTouchEvent(dpy, touch_device_info, touchid, False, touch_axis, 2, CurrentTime);
+ break;
+ default:
+ fprintf(stderr, "Invalid touch type (%d)\n", type);
+ break;
+ }
+ XSync(dpy, False);
+
+ if (res == 1)
+ {
+ return EFL_UTIL_ERROR_NONE;
+ }
+ return EFL_UTIL_ERROR_PERMISSION_DENIED;
+}
+
+static int
+_efl_util_input_find_all_request_devices(efl_util_inputgen_h inputgen_h, efl_util_input_device_type_e request_type)
+{
+ if (EFL_UTIL_INPUT_DEVTYPE_KEYBOARD & request_type)
+ {
+ if (inputgen_h->input_generate_info.devid_key == 0)
+ {
+ return 0;
+ }
+ }
+
+ if (EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN & request_type)
+ {
+ if (inputgen_h->input_generate_info.devid_touch == 0)
+ {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static void
+_efl_util_input_deinitialize_input_generator(efl_util_inputgen_h inputgen_h)
+{
+ _efl_util_input_close_generate_device(inputgen_h);
+ free(inputgen_h);
+ inputgen_h = NULL;
+
+ ecore_x_shutdown();
+}
--- /dev/null
+/*
+ * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 LOG_TAG "TIZEN_N_EFL_UTIL"
+
+#include <efl_util.h>
+#include <efl_util_private.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <Elementary.h>
+#include <Ecore_X.h>
+#include <utilX.h>
+
+API int efl_util_set_notification_window_level(Evas_Object* window, efl_util_notification_level_e level)
+{
+ Ecore_X_Window_Type window_type;
+
+ if(window == NULL)
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ Ecore_X_Window xwin = elm_win_xwindow_get(window);
+
+ if(ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
+ {
+ // success to get window type
+ if(window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
+ {
+ // given EFL window's type is not notification type.
+ return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
+ }
+ }
+ else
+ {
+ // fail to get window type
+ return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
+ }
+
+ // this api doesn't have return type
+ if(level == EFL_UTIL_NOTIFICATION_LEVEL_1)
+ {
+ utilx_set_system_notification_level(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_LEVEL_LOW);
+ }
+ else if(level == EFL_UTIL_NOTIFICATION_LEVEL_2)
+ {
+ utilx_set_system_notification_level(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_LEVEL_NORMAL);
+ }
+ else if(level == EFL_UTIL_NOTIFICATION_LEVEL_3)
+ {
+ utilx_set_system_notification_level(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_LEVEL_HIGH);
+ }
+ else if(level == EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT)
+ {
+ utilx_set_system_notification_priority(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_PRIORITY_DEFAULT);
+ }
+ else if(level == EFL_UTIL_NOTIFICATION_LEVEL_MEDIUM)
+ {
+ utilx_set_system_notification_priority(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_PRIORITY_MEDIUM);
+ }
+ else if(level == EFL_UTIL_NOTIFICATION_LEVEL_HIGH)
+ {
+ utilx_set_system_notification_priority(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_PRIORITY_HIGH);
+ }
+ else if(level == EFL_UTIL_NOTIFICATION_LEVEL_TOP)
+ {
+ utilx_set_system_notification_priority(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_PRIORITY_TOP);
+ }
+ else if(level == EFL_UTIL_NOTIFICATION_LEVEL_NONE)
+ {
+ utilx_set_system_notification_priority(ecore_x_display_get(), xwin, UTILX_NOTIFICATION_PRIORITY_NONE);
+ }
+ else
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ return EFL_UTIL_ERROR_NONE;
+}
+
+
+
+API int efl_util_get_notification_window_level(Evas_Object* window, efl_util_notification_level_e* level)
+{
+ Ecore_X_Window_Type window_type;
+
+ Utilx_Notification_Level utilx_level;
+ Utilx_Notification_Priority utilx_priority;
+
+ if(window == NULL)
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ Ecore_X_Window xwin = elm_win_xwindow_get(window);
+
+ if(ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
+ {
+ // success to get window type
+ if(window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
+ {
+ // given EFL window's type is not notification type.
+ return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
+ }
+
+ utilx_priority = utilx_get_system_notification_priority(ecore_x_display_get(), xwin);
+ if(utilx_priority == UTILX_NOTIFICATION_PRIORITY_DEFAULT)
+ {
+ *level = EFL_UTIL_NOTIFICATION_LEVEL_DEFAULT;
+ }
+ else if(utilx_priority == UTILX_NOTIFICATION_PRIORITY_MEDIUM)
+ {
+ *level = EFL_UTIL_NOTIFICATION_LEVEL_MEDIUM;
+ }
+ else if(utilx_priority == UTILX_NOTIFICATION_PRIORITY_HIGH)
+ {
+ *level = EFL_UTIL_NOTIFICATION_LEVEL_HIGH;
+ }
+ else if(utilx_priority == UTILX_NOTIFICATION_PRIORITY_TOP)
+ {
+ *level = EFL_UTIL_NOTIFICATION_LEVEL_TOP;
+ }
+ else if(utilx_priority == UTILX_NOTIFICATION_PRIORITY_NONE)
+ {
+ *level = EFL_UTIL_NOTIFICATION_LEVEL_NONE;
+ }
+ else if(utilx_priority == UTILX_NOTIFICATION_PRIORITY_UNKNOWN)
+ {
+ utilx_level = utilx_get_system_notification_level(ecore_x_display_get(), xwin);
+ if(utilx_level == UTILX_NOTIFICATION_LEVEL_LOW)
+ {
+ *level = EFL_UTIL_NOTIFICATION_LEVEL_1;
+ }
+ else if(utilx_level == UTILX_NOTIFICATION_LEVEL_NORMAL)
+ {
+ *level = EFL_UTIL_NOTIFICATION_LEVEL_2;
+ }
+ else if(utilx_level == UTILX_NOTIFICATION_LEVEL_HIGH)
+ {
+ *level = EFL_UTIL_NOTIFICATION_LEVEL_3;
+ }
+ else
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ // fail to get window type
+ return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
+ }
+
+ return EFL_UTIL_ERROR_NONE;
+}
+
+
+
+API int efl_util_set_notification_window_level_error_cb(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data)
+{
+ Eina_Bool ret = EINA_FALSE;
+
+ if (!window) return EFL_UTIL_ERROR_INVALID_PARAMETER;
+
+ ret = _efl_util_notification_info_add(window, callback, user_data);
+ if (ret)
+ {
+ if (!_noti_level_access_result_atom)
+ _noti_level_access_result_atom = ecore_x_atom_get("_E_NOTIFICATION_LEVEL_ACCESS_RESULT");
+
+ if (!_noti_level_access_result_handler)
+ _noti_level_access_result_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _efl_util_client_message, NULL);
+ _noti_handler_count++;
+
+ return EFL_UTIL_ERROR_NONE;
+ }
+ else
+ {
+ return EFL_UTIL_ERROR_OUT_OF_MEMORY;
+ }
+}
+
+
+
+API int efl_util_unset_notification_window_level_error_cb(Evas_Object *window)
+{
+ Eina_Bool ret = EINA_FALSE;
+
+ if (!window) return EFL_UTIL_ERROR_INVALID_PARAMETER;
+
+ ret = _efl_util_notification_info_del(window);
+ if (ret)
+ {
+ _noti_handler_count--;
+ if (_noti_handler_count == 0)
+ {
+ if (_noti_level_access_result_handler)
+ {
+ ecore_event_handler_del(_noti_level_access_result_handler);
+ _noti_level_access_result_handler = NULL;
+ }
+ }
+ return EFL_UTIL_ERROR_NONE;
+ }
+ else
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+}
+
+
+
+static Eina_Bool _efl_util_client_message(void *data, int type, void *event)
+{
+ Ecore_X_Event_Client_Message *ev;
+
+ ev = event;
+ if (!ev) return ECORE_CALLBACK_PASS_ON;
+
+ if (ev->message_type == _noti_level_access_result_atom)
+ {
+ Ecore_X_Window xwin;
+ xwin = ev->win;
+
+ notification_error_cb_info *cb_info = NULL;
+ cb_info = _notification_error_cb_info_find_by_xwin(xwin);
+ if (cb_info)
+ {
+ int access = ev->data.l[1];
+ if (access == 0) // permission denied
+ {
+ if (cb_info->err_cb)
+ {
+ cb_info->err_cb(cb_info->window, EFL_UTIL_ERROR_PERMISSION_DENIED, cb_info->user_data);
+ }
+ }
+ }
+ }
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+
+
+static notification_error_cb_info *_notification_error_cb_info_find_by_xwin(Ecore_X_Window xwin)
+{
+ Eina_List *l;
+ notification_error_cb_info* temp;
+ Ecore_X_Window temp_xwin;
+
+ EINA_LIST_FOREACH(_g_notification_error_cb_info_list, l, temp)
+ {
+ if (temp->window)
+ {
+ temp_xwin = elm_win_xwindow_get(temp->window);
+ if (xwin == temp_xwin)
+ {
+ return temp;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+
+static notification_error_cb_info *_notification_error_cb_info_find(Evas_Object *window)
+{
+ Eina_List *l;
+ notification_error_cb_info* temp;
+
+ EINA_LIST_FOREACH(_g_notification_error_cb_info_list, l, temp)
+ {
+ if (temp->window == window)
+ {
+ return temp;
+ }
+ }
+
+ return NULL;
+}
+
+
+
+static Eina_Bool _efl_util_notification_info_add(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data)
+{
+ notification_error_cb_info* _err_info = _notification_error_cb_info_find(window);
+
+ if (_err_info)
+ {
+ _g_notification_error_cb_info_list = eina_list_remove(_g_notification_error_cb_info_list, _err_info);
+ free(_err_info);
+ _err_info = NULL;
+ }
+
+ _err_info = (notification_error_cb_info*)calloc(1, sizeof(notification_error_cb_info));
+ if (!_err_info)
+ {
+ return EINA_FALSE;
+ }
+ _err_info->window = window;
+ _err_info->err_cb = callback;
+ _err_info->user_data = user_data;
+
+ _g_notification_error_cb_info_list = eina_list_append(_g_notification_error_cb_info_list, _err_info);
+
+ return EINA_TRUE;
+}
+
+
+
+static Eina_Bool _efl_util_notification_info_del(Evas_Object *window)
+{
+ notification_error_cb_info* _err_info = _notification_error_cb_info_find(window);
+ if (!_err_info)
+ {
+ return EINA_FALSE;
+ }
+
+ _g_notification_error_cb_info_list = eina_list_remove(_g_notification_error_cb_info_list, _err_info);
+ free(_err_info);
+
+ return EINA_TRUE;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 LOG_TAG "TIZEN_N_EFL_UTIL"
+
+#include <efl_util.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <Elementary.h>
+#include <Ecore_X.h>
+
+#define _STR_CMP(a, b) (strncmp(a, b, strlen(b)) == 0)
+
+typedef struct _screen_mode_error_cb_info
+{
+ Evas_Object *window;
+ efl_util_window_screen_mode_error_cb err_cb;
+ void *user_data;
+} screen_mode_error_cb_info;
+
+Eina_List *_g_screen_mode_error_cb_info_list;
+static Ecore_Event_Handler* _screen_mode_access_result_handler = NULL;
+static int _screen_mode_handler_count = 0;
+static Ecore_X_Atom _screen_mode_access_result_atom;
+
+static Eina_Bool _efl_util_client_message(void *data, int type, void *event);
+static screen_mode_error_cb_info *_screen_mode_error_cb_info_find_by_xwin(Ecore_X_Window xwin);
+static screen_mode_error_cb_info *_screen_mode_error_cb_info_find(Evas_Object *window);
+static Eina_Bool _efl_util_screen_mode_info_add(Evas_Object *window, efl_util_window_screen_mode_error_cb callback, void *user_data);
+static Eina_Bool _efl_util_screen_mode_info_del(Evas_Object *window);
+
+
+API int efl_util_set_window_screen_mode(Evas_Object *window, efl_util_screen_mode_e mode)
+{
+ Evas *e;
+ Ecore_Evas *ee;
+ int id;
+
+ if(window == NULL)
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ e = evas_object_evas_get(window);
+ if (!e) return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ ee = ecore_evas_ecore_evas_get(e);
+ if (!ee) return EFL_UTIL_ERROR_INVALID_PARAMETER;
+
+ id = ecore_evas_aux_hint_id_get(ee, "wm.policy.win.lcd.lock");
+ if (mode == EFL_UTIL_SCREEN_MODE_ALWAYS_ON)
+ {
+ if (id == -1) ecore_evas_aux_hint_add(ee, "wm.policy.win.lcd.lock", "1");
+ else ecore_evas_aux_hint_val_set(ee, id, "1");
+ }
+ else if (mode == EFL_UTIL_SCREEN_MODE_DEFAULT)
+ {
+ if (id == -1) ecore_evas_aux_hint_add(ee, "wm.policy.win.lcd.lock", "0");
+ else ecore_evas_aux_hint_val_set(ee, id, "0");
+ }
+ else
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ return EFL_UTIL_ERROR_NONE;
+}
+
+
+
+API int efl_util_get_window_screen_mode(Evas_Object *window, efl_util_screen_mode_e *mode)
+{
+ Evas *e;
+ Ecore_Evas *ee;
+ const char *value_str;
+ int id;
+
+ if(window == NULL || mode == NULL)
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ e = evas_object_evas_get(window);
+ if (!e) return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ ee = ecore_evas_ecore_evas_get(e);
+ if (!ee) return EFL_UTIL_ERROR_INVALID_PARAMETER;
+
+ id = ecore_evas_aux_hint_id_get(ee, "wm.policy.win.lcd.lock");
+ if (id == -1)
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ value_str = ecore_evas_aux_hint_val_get(ee, id);
+ if (value_str == NULL)
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (_STR_CMP(value_str, "1"))
+ {
+ *mode = EFL_UTIL_SCREEN_MODE_ALWAYS_ON;
+ }
+ else
+ {
+ *mode = EFL_UTIL_SCREEN_MODE_DEFAULT;
+ }
+
+ return EFL_UTIL_ERROR_NONE;
+}
+
+
+
+API int efl_util_set_window_screen_mode_error_cb(Evas_Object *window, efl_util_window_screen_mode_error_cb callback, void *user_data)
+{
+ Eina_Bool ret = EINA_FALSE;
+
+ if (!window) return EFL_UTIL_ERROR_INVALID_PARAMETER;
+
+ ret = _efl_util_screen_mode_info_add(window, callback, user_data);
+ if (ret)
+ {
+ if (!_screen_mode_access_result_atom)
+ _screen_mode_access_result_atom = ecore_x_atom_get("_E_SCREEN_MODE_ACCESS_RESULT");
+
+ if (!_screen_mode_access_result_handler)
+ _screen_mode_access_result_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _efl_util_client_message, NULL);
+ _screen_mode_handler_count++;
+
+ return EFL_UTIL_ERROR_NONE;
+ }
+ else
+ {
+ return EFL_UTIL_ERROR_OUT_OF_MEMORY;
+ }
+}
+
+
+
+API int efl_util_unset_window_screen_mode_error_cb(Evas_Object *window)
+{
+ Eina_Bool ret = EINA_FALSE;
+
+ if (!window) return EFL_UTIL_ERROR_INVALID_PARAMETER;
+
+ ret = _efl_util_screen_mode_info_del(window);
+ if (ret)
+ {
+ _screen_mode_handler_count--;
+ if (_screen_mode_handler_count == 0)
+ {
+ if (_screen_mode_access_result_handler)
+ {
+ ecore_event_handler_del(_screen_mode_access_result_handler);
+ _screen_mode_access_result_handler = NULL;
+ }
+ }
+ return EFL_UTIL_ERROR_NONE;
+ }
+ else
+ {
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+ }
+}
+
+
+
+static Eina_Bool _efl_util_client_message(void *data, int type, void *event)
+{
+ Ecore_X_Event_Client_Message *ev;
+
+ ev = event;
+ if (!ev) return ECORE_CALLBACK_PASS_ON;
+
+ if (ev->message_type == _screen_mode_access_result_atom)
+ {
+ Ecore_X_Window xwin;
+ xwin = ev->win;
+
+ screen_mode_error_cb_info *cb_info = NULL;
+ cb_info = _screen_mode_error_cb_info_find_by_xwin(xwin);
+ if (cb_info)
+ {
+ int access = ev->data.l[1];
+ if (access == 0) // permission denied
+ {
+ if (cb_info->err_cb)
+ {
+ cb_info->err_cb(cb_info->window, EFL_UTIL_ERROR_PERMISSION_DENIED, cb_info->user_data);
+ }
+ }
+ }
+ }
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+
+
+static screen_mode_error_cb_info *_screen_mode_error_cb_info_find_by_xwin(Ecore_X_Window xwin)
+{
+ Eina_List *l;
+ screen_mode_error_cb_info* temp;
+ Ecore_X_Window temp_xwin;
+
+ EINA_LIST_FOREACH(_g_screen_mode_error_cb_info_list, l, temp)
+ {
+ if (temp->window)
+ {
+ temp_xwin = elm_win_xwindow_get(temp->window);
+ if (xwin == temp_xwin)
+ {
+ return temp;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+
+static screen_mode_error_cb_info *_screen_mode_error_cb_info_find(Evas_Object *window)
+{
+ Eina_List *l;
+ screen_mode_error_cb_info* temp;
+
+ EINA_LIST_FOREACH(_g_screen_mode_error_cb_info_list, l, temp)
+ {
+ if (temp->window == window)
+ {
+ return temp;
+ }
+ }
+
+ return NULL;
+}
+
+
+
+static Eina_Bool _efl_util_screen_mode_info_add(Evas_Object *window, efl_util_window_screen_mode_error_cb callback, void *user_data)
+{
+ screen_mode_error_cb_info* _err_info = _screen_mode_error_cb_info_find(window);
+
+ if (_err_info)
+ {
+ _g_screen_mode_error_cb_info_list = eina_list_remove(_g_screen_mode_error_cb_info_list, _err_info);
+ free(_err_info);
+ _err_info = NULL;
+ }
+
+ _err_info = (screen_mode_error_cb_info*)calloc(1, sizeof(screen_mode_error_cb_info));
+ if (!_err_info)
+ {
+ return EINA_FALSE;
+ }
+ _err_info->window = window;
+ _err_info->err_cb = callback;
+ _err_info->user_data = user_data;
+
+ _g_screen_mode_error_cb_info_list = eina_list_append(_g_screen_mode_error_cb_info_list, _err_info);
+
+ return EINA_TRUE;
+}
+
+
+
+static Eina_Bool _efl_util_screen_mode_info_del(Evas_Object *window)
+{
+ screen_mode_error_cb_info* _err_info = _screen_mode_error_cb_info_find(window);
+ if (!_err_info)
+ {
+ return EINA_FALSE;
+ }
+
+ _g_screen_mode_error_cb_info_list = eina_list_remove(_g_screen_mode_error_cb_info_list, _err_info);
+ free(_err_info);
+
+ return EINA_TRUE;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <efl_util.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <Elementary.h>
+#include <Ecore_X.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/Xvproto.h>
+#include <X11/extensions/Xdamage.h>
+#include <xf86drm.h>
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+
+#ifdef USE_DRI2
+#include <dri2.h>
+#else
+#include <X11/Xlib-xcb.h>
+#include <xcb/xcb.h>
+#include <xcb/dri3.h>
+#include <xcb/xcbext.h>
+#endif
+
+struct _efl_util_screenshot_h
+{
+ tbm_surface_h surface;
+ int width;
+ int height;
+
+ Ecore_X_Display *dpy;
+ int internal_display;
+ int screen;
+ Window root;
+ Pixmap pixmap;
+ GC gc;
+ Atom atom_capture;
+
+ /* port */
+ int port;
+
+ /* damage */
+ Damage damage;
+ int damage_base;
+
+#ifdef USE_DRI2
+ /* dri2 */
+ int eventBase, errorBase;
+ int dri2Major, dri2Minor;
+ char *driver_name, *device_name;
+ drm_magic_t magic;
+#endif
+
+ /* drm */
+ int drm_fd;
+
+ /* tbm bufmgr */
+ tbm_bufmgr bufmgr;
+};
+
+#define FOURCC(a,b,c,d) (((unsigned)d&0xff)<<24 | ((unsigned)c&0xff)<<16 | ((unsigned)b&0xff)<<8 | ((unsigned)a&0xff))
+
+#define FOURCC_RGB32 FOURCC('R','G','B','4')
+#define TIMEOUT_CAPTURE 3
+
+/* scrrenshot handle */
+static efl_util_screenshot_h g_screenshot;
+
+
+/* x error handling */
+static Bool g_efl_util_x_error_caught;
+static Bool g_efl_util_x_error_permission;
+
+static int _efl_util_screenshot_x_error_handle(Display *dpy, XErrorEvent *ev)
+{
+ if (!g_screenshot || (dpy != g_screenshot->dpy))
+ return 0;
+
+ g_efl_util_x_error_caught = True;
+ if (ev->error_code == BadAccess)
+ g_efl_util_x_error_permission = True;
+
+ return 0;
+}
+
+static int _efl_util_screenshot_get_port(Display *dpy, unsigned int id, Window win)
+{
+ unsigned int ver, rev, req_base, evt_base, err_base;
+ unsigned int adaptors;
+ XvAdaptorInfo *ai = NULL;
+ XvImageFormatValues *fo = NULL;
+ int formats;
+ int i, j, p;
+
+ if (XvQueryExtension(dpy, &ver, &rev, &req_base, &evt_base, &err_base) != Success)
+ {
+ fprintf (stderr, "[EFL_UTIL] no XV extension. \n");
+ return -1;
+ }
+
+ if (XvQueryAdaptors(dpy, win, &adaptors, &ai) != Success)
+ {
+ fprintf(stderr, "[EFL_UTIL] fail : query adaptors. \n");
+ return -1;
+ }
+
+ if (!ai)
+ {
+ fprintf(stderr, "[EFL_UTIL] fail : get adaptor info. \n");
+ return -1;
+ }
+
+ for (i = 0; i < adaptors; i++)
+ {
+ int support_format = False;
+
+ if (!(ai[i].type & XvInputMask) ||
+ !(ai[i].type & XvStillMask))
+ continue;
+
+ p = ai[i].base_id;
+
+ fo = XvListImageFormats (dpy, p, &formats);
+ for (j = 0; j < formats; j++)
+ if (fo[j].id == (int)id)
+ support_format = True;
+
+ if (fo)
+ XFree(fo);
+
+ if (!support_format)
+ continue;
+
+ for (; p < ai[i].base_id + ai[i].num_ports; p++)
+ {
+ if (XvGrabPort(dpy, p, 0) == Success)
+ {
+ XvFreeAdaptorInfo(ai);
+ return p;
+ }
+ }
+
+ fprintf(stderr, "[EFL_UTIL] fail : grab port. \n");
+ }
+
+ XvFreeAdaptorInfo(ai);
+
+ XSync(dpy, False);
+
+ return -1;
+}
+
+static int _efl_util_screenshot_get_best_size(Display *dpy, int port, int width, int height, unsigned int *best_width, unsigned int *best_height)
+{
+ XErrorHandler old_handler = NULL;
+
+ Atom atom_capture = XInternAtom(dpy, "_USER_WM_PORT_ATTRIBUTE_CAPTURE", False);
+
+ g_efl_util_x_error_caught = False;
+ old_handler = XSetErrorHandler(_efl_util_screenshot_x_error_handle);
+
+ XvSetPortAttribute(dpy, port, atom_capture, 1);
+ XSync(dpy, False);
+
+ g_efl_util_x_error_caught = False;
+ XSetErrorHandler(old_handler);
+
+ XvQueryBestSize(dpy, port, 0, 0, 0, width, height, best_width, best_height);
+ if (*best_width <= 0 || *best_height <= 0)
+ return 0;
+
+ return 1;
+}
+
+static Bool _efl_util_screenshot_predicate_proc(Display *dpy, XEvent *event, char *arg)
+{
+ efl_util_screenshot_h screenshot = (efl_util_screenshot_h)arg;
+
+ if(event->type == (screenshot->damage_base + XDamageNotify))
+ return True;
+ else
+ return False;
+}
+
+API efl_util_screenshot_h efl_util_screenshot_initialize(int width, int height)
+{
+ efl_util_screenshot_h screenshot = NULL;
+ int depth = 0;
+ int damage_err_base = 0;
+ unsigned int best_width = 0;
+ unsigned int best_height = 0;
+
+ if (width < 1 || height < 1)
+ {
+ printf("invalid parameter.\n");
+ set_last_result(EFL_UTIL_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ if (g_screenshot != NULL)
+ {
+ if (g_screenshot->width != width || g_screenshot->height != height)
+ {
+ // TODO: recreate pixmap and update information
+ if (!_efl_util_screenshot_get_best_size(g_screenshot->dpy, g_screenshot->port, width, height, &best_width, &best_height))
+ {
+ set_last_result(EFL_UTIL_ERROR_SCREENSHOT_INIT_FAIL);
+ return NULL;
+ }
+
+ g_screenshot->width = width;
+ g_screenshot->height = height;
+ }
+
+ return g_screenshot;
+ }
+
+ screenshot = calloc(1, sizeof(struct _efl_util_screenshot_h));
+ if (!screenshot)
+ {
+ printf("fails screenshot allocation.\n");
+ set_last_result(EFL_UTIL_ERROR_OUT_OF_MEMORY);
+ return NULL;
+ }
+
+ /* set dpy */
+ screenshot->dpy = ecore_x_display_get();
+ if (!screenshot->dpy)
+ {
+ screenshot->dpy = XOpenDisplay(0);
+ if (!screenshot->dpy)
+ {
+ printf("fails XOpenDisplay.\n");
+ goto fail;
+ }
+ /* for XCloseDisplay at denitialization */
+ screenshot->internal_display = 1;
+ }
+
+ /* set screen */
+ screenshot->screen = DefaultScreen(screenshot->dpy);
+
+ /* set root window */
+ screenshot->root = DefaultRootWindow(screenshot->dpy);
+
+ /* initialize capture adaptor */
+ screenshot->port = _efl_util_screenshot_get_port(screenshot->dpy, FOURCC_RGB32, screenshot->root);
+ if (screenshot->port <= 0)
+ {
+ printf("fails to get a port.\n");
+ goto fail;
+ }
+
+ /* get the best size */
+ if (!_efl_util_screenshot_get_best_size(screenshot->dpy, screenshot->port, width, height, &best_width, &best_height))
+ {
+ printf("fails to get a best size.\n");
+ goto fail;
+ }
+
+ /* set the width and the height */
+ screenshot->width = best_width;
+ screenshot->height = best_height;
+
+ /* create a pixmap */
+ depth = DefaultDepth(screenshot->dpy, screenshot->screen);
+ screenshot->pixmap = XCreatePixmap(screenshot->dpy, screenshot->root, screenshot->width, screenshot->height, depth);
+ if (!screenshot->pixmap)
+ {
+ printf("fails XCreatePixmap.\n");
+ goto fail;
+ }
+
+ screenshot->gc = XCreateGC(screenshot->dpy, screenshot->pixmap, 0, 0);
+ if (!screenshot->gc)
+ {
+ printf("fails XCreateGC.\n");
+ goto fail;
+ }
+ XSetForeground(screenshot->dpy, screenshot->gc, 0xFF000000);
+ XFillRectangle(screenshot->dpy, screenshot->pixmap, screenshot->gc, 0, 0, width, height);
+
+ /* initialize damage */
+ if (!XDamageQueryExtension(screenshot->dpy, &screenshot->damage_base, &damage_err_base))
+ goto fail;
+ screenshot->damage = XDamageCreate(screenshot->dpy, screenshot->pixmap, XDamageReportNonEmpty);
+ if (screenshot->damage <= 0)
+ {
+ printf("fails XDamageCreate.\n");
+ goto fail;
+ }
+
+ /* initialize dri3 and dri2 */
+
+#ifdef USE_DRI2
+ if (!DRI2QueryExtension(screenshot->dpy, &screenshot->eventBase, &screenshot->errorBase))
+ {
+ printf("fails DRI2QueryExtention\n");
+ goto fail;
+ }
+
+ if (!DRI2QueryVersion(screenshot->dpy, &screenshot->dri2Major, &screenshot->dri2Minor))
+ {
+ printf("fails DRI2QueryVersion\n");
+ goto fail;
+ }
+
+ if (!DRI2Connect(screenshot->dpy, screenshot->root, &screenshot->driver_name, &screenshot->device_name))
+ {
+ printf("fails DRI2Connect\n");
+ goto fail;
+ }
+
+ screenshot->drm_fd = open(screenshot->device_name, O_RDWR);
+ if (screenshot->drm_fd < 0)
+ {
+ printf("cannot open drm device (%s)\n", screenshot->device_name);
+ goto fail;
+ }
+
+ if (drmGetMagic(screenshot->drm_fd, &screenshot->magic))
+ {
+ printf("fails drmGetMagic\n");
+ goto fail;
+ }
+
+ if (!DRI2Authenticate(screenshot->dpy, screenshot->root, screenshot->magic))
+ {
+ printf("fails DRI2Authenticate\n");
+ goto fail;
+ }
+
+ if (!drmAuthMagic(screenshot->drm_fd, screenshot->magic))
+ {
+ printf("fails drmAuthMagic\n");
+ goto fail;
+ }
+
+ DRI2CreateDrawable(screenshot->dpy, screenshot->pixmap);
+#else
+ xcb_connection_t *c = XGetXCBConnection(screenshot->dpy);
+ xcb_generic_error_t *error = NULL;
+
+ xcb_dri3_query_version_cookie_t dri3_cookie;
+ xcb_dri3_query_version_reply_t *dri3_reply = NULL;
+ const xcb_query_extension_reply_t *extension = NULL;
+ xcb_extension_t xcb_dri3_id = { "DRI3", 0 };
+
+ xcb_prefetch_extension_data(c, &xcb_dri3_id);
+ extension = xcb_get_extension_data(c, &xcb_dri3_id);
+ if (!(extension && extension->present))
+ {
+ printf("fails DRI3 xcb_get_extension_data\n");
+ goto fail;
+ }
+
+ dri3_cookie = xcb_dri3_query_version(c, XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION);
+ dri3_reply = xcb_dri3_query_version_reply(c, dri3_cookie, &error);
+ if (!dri3_reply)
+ {
+ printf("fails xcb_dri3_query_version\n");
+ free(error);
+ goto fail;
+ }
+ free(dri3_reply);
+
+ xcb_dri3_open_cookie_t cookie;
+ xcb_dri3_open_reply_t *reply = NULL;
+ int drm_fd;
+
+ cookie = xcb_dri3_open(c, screenshot->root, 0);
+ reply = xcb_dri3_open_reply(c, cookie, NULL);
+ if (!reply)
+ {
+ printf("fails xcb_dri3_open\n");
+ goto fail;
+ }
+
+ if (reply->nfd != 1)
+ {
+ printf("fails get drm fd\n");
+ free(reply);
+ goto fail;
+ }
+
+ drm_fd = xcb_dri3_open_reply_fds(c, reply)[0];
+ fcntl(drm_fd, F_SETFD, FD_CLOEXEC);
+ if (drm_fd < 0)
+ {
+ printf("fails open drm fd\n");
+ free(reply);
+ goto fail;
+ }
+ free(reply);
+
+ screenshot->drm_fd = drm_fd;
+#endif
+
+ /* tbm bufmgr */
+ screenshot->bufmgr = tbm_bufmgr_init(screenshot->drm_fd);
+ if (!screenshot->bufmgr)
+ {
+ printf("fails tbm_bufmgr_init\n");
+ goto fail;
+ }
+
+ XFlush(screenshot->dpy);
+
+ g_screenshot = screenshot;
+ set_last_result(EFL_UTIL_ERROR_NONE);
+
+ return g_screenshot;
+fail:
+ if (screenshot)
+ efl_util_screenshot_deinitialize(screenshot);
+ set_last_result(EFL_UTIL_ERROR_SCREENSHOT_INIT_FAIL);
+
+ return NULL;
+}
+
+API int efl_util_screenshot_deinitialize(efl_util_screenshot_h screenshot)
+{
+ if (!screenshot)
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+
+ if (!screenshot->dpy)
+ return EFL_UTIL_ERROR_INVALID_PARAMETER;
+
+ /* tbm bufmgr */
+ if (screenshot->bufmgr)
+ tbm_bufmgr_deinit(screenshot->bufmgr);
+
+#ifdef USE_DRI2
+ /* dri2 */
+ DRI2DestroyDrawable(screenshot->dpy, screenshot->pixmap);
+
+ if (screenshot->driver_name)
+ free (screenshot->driver_name);
+ if (screenshot->device_name)
+ free (screenshot->device_name);
+#endif
+
+ if (screenshot->drm_fd >= 0)
+ close(screenshot->drm_fd);
+
+ /* xv */
+ if (screenshot->port > 0 && screenshot->pixmap > 0)
+ XvStopVideo(screenshot->dpy, screenshot->port, screenshot->pixmap);
+
+ /* damage */
+ if (screenshot->damage)
+ XDamageDestroy(screenshot->dpy, screenshot->damage);
+
+ /* gc */
+ if (screenshot->gc)
+ XFreeGC(screenshot->dpy, screenshot->gc);
+
+ /* pixmap */
+ if (screenshot->pixmap > 0)
+ XFreePixmap(screenshot->dpy, screenshot->pixmap);
+
+ /* port */
+ if (screenshot->port > 0)
+ XvUngrabPort(screenshot->dpy, screenshot->port, 0);
+
+ XSync(screenshot->dpy, False);
+
+ /* dpy */
+ if (screenshot->internal_display == 1)
+ XCloseDisplay(screenshot->dpy);
+
+ free(screenshot);
+ g_screenshot = NULL;
+
+ return EFL_UTIL_ERROR_NONE;
+}
+
+
+API tbm_surface_h efl_util_screenshot_take_tbm_surface(efl_util_screenshot_h screenshot)
+{
+ XEvent ev = {0,};
+ XErrorHandler old_handler = NULL;;
+ tbm_bo t_bo = NULL;
+ tbm_surface_h t_surface = NULL;
+ int buf_width = 0;
+ int buf_height = 0;
+ int buf_pitch = 0;
+ tbm_surface_info_s surf_info;
+ int i;
+#ifdef USE_DRI2
+ unsigned int attachment = DRI2BufferFrontLeft;
+ int nbufs = 0;
+ DRI2Buffer *bufs = NULL;
+#endif
+
+ if (screenshot != g_screenshot)
+ {
+ set_last_result(EFL_UTIL_ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ /* for flush other pending requests and pending events */
+ XSync(screenshot->dpy, 0);
+
+ g_efl_util_x_error_caught = False;
+ old_handler = XSetErrorHandler(_efl_util_screenshot_x_error_handle);
+
+ /* dump here */
+ XvPutStill(screenshot->dpy, screenshot->port, screenshot->pixmap, screenshot->gc,
+ 0, 0, screenshot->width, screenshot->height,
+ 0, 0, screenshot->width, screenshot->height);
+
+ XSync(screenshot->dpy, 0);
+
+ if (g_efl_util_x_error_caught)
+ {
+ g_efl_util_x_error_caught = False;
+ XSetErrorHandler(old_handler);
+ goto fail;
+ }
+
+ g_efl_util_x_error_caught = False;
+ XSetErrorHandler(old_handler);
+
+ if (!XCheckIfEvent(screenshot->dpy, &ev, _efl_util_screenshot_predicate_proc, (char *)screenshot))
+ {
+ int fd = ConnectionNumber(screenshot->dpy);
+ fd_set mask;
+ struct timeval tv;
+ int ret;
+
+ FD_ZERO(&mask);
+ FD_SET(fd, &mask);
+
+ tv.tv_usec = 0;
+ tv.tv_sec = TIMEOUT_CAPTURE;
+
+ ret = select(fd + 1, &mask, 0, 0, &tv);
+ if (ret < 0)
+ fprintf(stderr, "[UTILX] fail: select.\n");
+ else if (ret == 0)
+ fprintf(stderr, "[UTILX] timeout(%d sec)!\n", TIMEOUT_CAPTURE);
+ else if (XPending(screenshot->dpy))
+ XNextEvent(screenshot->dpy, &ev);
+ else
+ fprintf(stderr, "[UTILX] fail: not passed a event!\n");
+ }
+
+ /* check if the capture is done by xserver and pixmap has got the captured image */
+ if (ev.type == (screenshot->damage_base + XDamageNotify))
+ {
+ XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *)&ev;
+ if (damage_ev->drawable == screenshot->pixmap)
+ {
+#ifdef USE_DRI2
+ /* Get DRI2 FrontLeft buffer of the pixmap */
+ bufs = DRI2GetBuffers(screenshot->dpy, screenshot->pixmap, &buf_width, &buf_height, &attachment, 1, &nbufs);
+ if (!bufs)
+ {
+ fprintf(stderr, "[UTILX] fail to get dri2 buffers!\n");
+ goto fail;
+ }
+
+ buf_pitch = bufs->pitch;
+
+ t_bo = tbm_bo_import(screenshot->bufmgr, bufs[0].name);
+ if (!t_bo)
+ {
+ fprintf(stderr, "[UTILX] fail to get dri2 buffers!\n");
+ goto fail;
+ }
+
+ free(bufs);
+ bufs = NULL;
+#else
+ /* Get DRI3 Front buffer of the pixmap */
+
+ xcb_connection_t *c = XGetXCBConnection(screenshot->dpy);
+ xcb_generic_error_t *error = NULL;
+ xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie;
+ xcb_dri3_buffer_from_pixmap_reply_t *bp_reply = NULL;
+ int *fds;
+
+ bp_cookie = xcb_dri3_buffer_from_pixmap(c, screenshot->pixmap);
+ bp_reply = xcb_dri3_buffer_from_pixmap_reply(c, bp_cookie, &error);
+ if (!bp_reply)
+ {
+ fprintf(stderr, "[UTILX] fail to xcb_dri3_buffer_from_pixmap error:%d!\n", error->error_code);
+ free(error);
+ goto fail;
+ }
+ fds = xcb_dri3_buffer_from_pixmap_reply_fds(c, bp_reply);
+
+ buf_pitch = bp_reply->stride;
+ buf_width = bp_reply->width;
+ buf_height = bp_reply->height;
+
+ t_bo = tbm_bo_import_fd(screenshot->bufmgr, fds[0]);
+ if (!t_bo)
+ {
+ fprintf(stderr, "[UTILX] fail to get tbm_bo from fd!\n");
+ close(fds[0]);
+ free (bp_reply);
+ goto fail;
+ }
+
+ close(fds[0]);
+ free(bp_reply);
+#endif
+
+ surf_info.width = buf_width;
+ surf_info.height = buf_height;
+ surf_info.format = TBM_FORMAT_XRGB8888;
+ surf_info.bpp = 32;
+ surf_info.size = buf_pitch * surf_info.height;
+ surf_info.num_planes = 1;
+ for (i = 0; i < surf_info.num_planes; i++)
+ {
+ surf_info.planes[i].size = buf_pitch * surf_info.height;
+ surf_info.planes[i].stride = buf_pitch;
+ surf_info.planes[i].offset = 0;
+ }
+
+ t_surface = tbm_surface_internal_create_with_bos(&surf_info, &t_bo, 1);
+ if (!t_surface)
+ {
+ fprintf(stderr, "[UTILX] fail to get tbm_surface!\n");
+ goto fail;
+ }
+
+ tbm_bo_unref(t_bo);
+
+ XDamageSubtract(screenshot->dpy, screenshot->damage, None, None);
+
+ set_last_result(EFL_UTIL_ERROR_NONE);
+
+ return t_surface;
+ }
+
+ XDamageSubtract(screenshot->dpy, screenshot->damage, None, None);
+ }
+
+fail:
+
+ if (t_bo)
+ tbm_bo_unref(t_bo);
+
+#ifdef USE_DRI2
+ if (bufs)
+ free(bufs);
+#endif
+
+ if (g_efl_util_x_error_permission)
+ {
+ g_efl_util_x_error_permission = False;
+ set_last_result(EFL_UTIL_ERROR_PERMISSION_DENIED);
+ }
+ else
+ set_last_result(EFL_UTIL_ERROR_SCREENSHOT_EXECUTION_FAIL);
+
+ return NULL;
+}
+
+