From: ky85.kim Date: Thu, 11 Jun 2015 12:56:41 +0000 (+0900) Subject: Init commit from tizen 2.4 X-Git-Tag: submit/tizen/20150612.011920~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=968f60a3eaa77d8b5f324b71b7f545aa60b40694;p=platform%2Fcore%2Fuifw%2Fvoice-control-elm.git Init commit from tizen 2.4 Change-Id: Ie851d1b61d8acfc1ede591a0e8933d69a367c4bf --- diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..ba70524 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,5 @@ +Dongyeol Lee +Wonnam Jang +Kwangyoun Kim +Witold Goralski +Jakub Borowski \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..52b1acf --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,132 @@ +# @file CMakeLists.txt +# @author Lukasz Wrzosek (l.wrzosek@samsung.com) +# @version 1.0 +# @brief +# + +# Check minimum CMake version +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# Project name +PROJECT(voice-control-elm) + +SET(LIBRARY_NAME "vc-elm") +#SET(VOICE_CONTROL_ELM_VERSION_MAJOR 0) +#SET(VOICE_CONTROL_ELM_VERSION_MINOR 2) +#SET(VOICE_CONTROL_ELM_VERSION_PATCH 0) +SET(VERSION 0.2.0) + +# pkg config tool +INCLUDE(FindPkgConfig) + +# Build type +SET(CMAKE_BUILD_TYPE "Release") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -fprofile-arcs -ftest-coverage -D_GNU_SOURCE") + +# CMake settings +MESSAGE(STATUS "========================================") +MESSAGE(STATUS "CMAKE_BINARY_DIR: " ${CMAKE_BINARY_DIR}) +MESSAGE(STATUS "CMAKE_CURRENT_BINARY_DIR: " ${CMAKE_CURRENT_BINARY_DIR}) +MESSAGE(STATUS "CMAKE_SOURCE_DIR: " ${CMAKE_SOURCE_DIR}) +MESSAGE(STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR}) +MESSAGE(STATUS "PROJECT_BINARY_DIR: " ${PROJECT_BINARY_DIR}) +MESSAGE(STATUS "PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR}) +MESSAGE(STATUS "EXECUTABLE_OUTPUT_PATH: " ${EXECUTABLE_OUTPUT_PATH}) +MESSAGE(STATUS "LIBRARY_OUTPUT_PATH: " ${LIBRARY_OUTPUT_PATH}) +MESSAGE(STATUS "CMAKE_MODULE_PATH: " ${CMAKE_MODULE_PATH}) +MESSAGE(STATUS "CMAKE_COMMAND: " ${CMAKE_COMMAND}) +MESSAGE(STATUS "CMAKE_ROOT: " ${CMAKE_ROOT}) +MESSAGE(STATUS "CMAKE_CURRENT_LIST_FILE: " ${CMAKE_CURRENT_LIST_FILE}) +MESSAGE(STATUS "CMAKE_CURRENT_LIST_LINE: " ${CMAKE_CURRENT_LIST_LINE}) +MESSAGE(STATUS "CMAKE_INCLUDE_PATH: " ${CMAKE_INCLUDE_PATH}) +MESSAGE(STATUS "CMAKE_LIBRARY_PATH: " ${CMAKE_LIBRARY_PATH}) +MESSAGE(STATUS "CMAKE_SYSTEM: " ${CMAKE_SYSTEM}) +MESSAGE(STATUS "CMAKE_SYSTEM_NAME: " ${CMAKE_SYSTEM_NAME}) +MESSAGE(STATUS "CMAKE_SYSTEM_VERSION: " ${CMAKE_SYSTEM_VERSION}) +MESSAGE(STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR}) +MESSAGE(STATUS "UNIX: " ${UNIX}) +MESSAGE(STATUS "WIN32: " ${WIN32}) +MESSAGE(STATUS "APPLE: " ${APPLE}) +MESSAGE(STATUS "MINGW: " ${MINGW}) +MESSAGE(STATUS "CYGWIN: " ${CYGWIN}) +MESSAGE(STATUS "BORLAND: " ${BORLAND}) +MESSAGE(STATUS "MSVC: " ${MSVC}) +MESSAGE(STATUS "MSVC_IDE: " ${MSVC_IDE}) +MESSAGE(STATUS "MSVC60: " ${MSVC60}) +MESSAGE(STATUS "MSVC70: " ${MSVC70}) +MESSAGE(STATUS "MSVC71: " ${MSVC71}) +MESSAGE(STATUS "MSVC80: " ${MSVC80}) +MESSAGE(STATUS "CMAKE_COMPILER_2005: " ${CMAKE_COMPILER_2005}) +MESSAGE(STATUS "CMAKE_SKIP_RULE_DEPENDENCY: " ${CMAKE_SKIP_RULE_DEPENDENCY}) +MESSAGE(STATUS "CMAKE_SKIP_INSTALL_ALL_DEPENDENCY: " ${CMAKE_SKIP_INSTALL_ALL_DEPENDENCY}) +MESSAGE(STATUS "CMAKE_SKIP_RPATH: " ${CMAKE_SKIP_RPATH}) +MESSAGE(STATUS "CMAKE_VERBOSE_MAKEFILE: " ${CMAKE_VERBOSE_MAKEFILE}) +MESSAGE(STATUS "CMAKE_SUPPRESS_REGENERATION: " ${CMAKE_SUPPRESS_REGENERATION}) +MESSAGE(STATUS "CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS}) +MESSAGE(STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS}) +MESSAGE(STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE}) +MESSAGE(STATUS "BUILD_SHARED_LIBS: " ${BUILD_SHARED_LIBS}) +MESSAGE(STATUS "CMAKE_C_COMPILER: " ${CMAKE_C_COMPILER}) +MESSAGE(STATUS "CMAKE_CXX_COMPILER: " ${CMAKE_CXX_COMPILER}) +MESSAGE(STATUS "CMAKE_COMPILER_IS_GNUCC: " ${CMAKE_COMPILER_IS_GNUCC}) +MESSAGE(STATUS "CMAKE_COMPILER_IS_GNUCXX : " ${CMAKE_COMPILER_IS_GNUCXX}) +MESSAGE(STATUS "CMAKE_AR: " ${CMAKE_AR}) +MESSAGE(STATUS "CMAKE_RANLIB: " ${CMAKE_RANLIB}) +MESSAGE(STATUS "========================================") + +# Warning flags +#ADD_DEFINITIONS("-Werror") # Generate all warnings as errors +ADD_DEFINITIONS("-Wall") # Generate all warnings +ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings +ADD_DEFINITIONS("-pedantic") # Accept only pedantic code +ADD_DEFINITIONS("-Wwrite-strings") # Do not accept writing to constant string memory +ADD_DEFINITIONS("-Winit-self") # Do not accept initializing variable with itself +ADD_DEFINITIONS("-Wcast-align") # Do not accept misaligning with casting +ADD_DEFINITIONS("-Wcast-qual") # Do not accept removing qualifiers with casting +ADD_DEFINITIONS("-Wpointer-arith") # Warn about void pointer arthimetic +ADD_DEFINITIONS("-Wstrict-aliasing") # Ensure strict aliasing +ADD_DEFINITIONS("-Wuninitialized") # Do not accept uninitialized variables +ADD_DEFINITIONS("-Wlong-long") # Do not allow using long long +ADD_DEFINITIONS("-Wunreachable-code") # Warn about unreachable code +ADD_DEFINITIONS("-Wfloat-equal") # Do not accept comparing floating points with equal operator +ADD_DEFINITIONS("-Wabi") # Warn about possible ABI problems +ADD_DEFINITIONS("-Wswitch-enum") # Check switch enumeration +ADD_DEFINITIONS("-Wformat=2") # Check printf formatting +ADD_DEFINITIONS("-Wundef") # Warn if an undefined identifier is evaluated in an @if directive. +ADD_DEFINITIONS("-Wshadow") # Warn whenever a local variable shadows another local variable, parameter or global variable or whenever a built-in function is shadowed +ADD_DEFINITIONS("-Wconversion") # Warn for implicit conversions that may alter a value +ADD_DEFINITIONS("-Wlogical-op") # Warn about suspicious uses of logical operators in expressions +ADD_DEFINITIONS("-Wmissing-field-initializers") # Warn if a structure's initializer has some fields missing. +ADD_DEFINITIONS("-Wredundant-decls") # Warn if anything is declared more than once in the same scope, even in cases where multiple declaration is valid and changes nothing. +ADD_DEFINITIONS("-Wswitch-default") # Warn whenever a switch statement does not have a default case. +ADD_DEFINITIONS("-Wsync-nand") # Warn when __sync_fetch_and_nand and __sync_nand_and_fetch built-in functions are used. These functions changed semantics in GCC 4.4. +ADD_DEFINITIONS("-Wunused") # All the above -Wunused options combined. +ADD_DEFINITIONS("-Wstrict-overflow=5") # Also warn about cases where the compiler reduces the magnitude of a constant involved in a comparison. + + +SET(TARGET_VC_ELM_LIBRARY ${LIBRARY_NAME}) + +SET(VC_ELM_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include) + +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(include) + +# INCLUDE FOR BUILD & INSTALL .PO FILES +ADD_SUBDIRECTORY(data/po) + +ADD_CUSTOM_TARGET(voice-control-elm.edj + COMMAND edje_cc -id ${CMAKE_SOURCE_DIR}/data + ${CMAKE_SOURCE_DIR}/data/${PROJECT_NAME}.edc ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.edj + ) +ADD_DEPENDENCIES(${LIBRARY_NAME} ${PROJECT_NAME}.edj) + +INSTALL(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.edj + DESTINATION share/edje) + +INSTALL(FILES ${PROJECT_SOURCE_DIR}/data/image.png + ${PROJECT_SOURCE_DIR}/data/image_test.png + DESTINATION share/voice/vc-elm) + +INSTALL(FILES ${PROJECT_SOURCE_DIR}/voice-control-elm-config.xml + DESTINATION ${LIBDIR}/voice/vc-elm/1.0) + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..6f31fdc --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) 2011-2015 Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE file for Apache License terms and conditions. diff --git a/changelog b/changelog new file mode 100644 index 0000000..ec2ff78 --- /dev/null +++ b/changelog @@ -0,0 +1,6 @@ +vc-widget-elm (0.2.0) -- Thu, 29 May 2014 + + * Update version 0.2.0 (Kwangyoun Kim ) + +vc-widget-elm (0.0.1) + * Release version 0.1.0 (Lukasz Wrzosek ) diff --git a/data/image.png b/data/image.png new file mode 100644 index 0000000..2446782 Binary files /dev/null and b/data/image.png differ diff --git a/data/image_test.png b/data/image_test.png new file mode 100644 index 0000000..710ea52 Binary files /dev/null and b/data/image_test.png differ diff --git a/data/po/CMakeLists.txt b/data/po/CMakeLists.txt new file mode 100644 index 0000000..8157440 --- /dev/null +++ b/data/po/CMakeLists.txt @@ -0,0 +1,26 @@ +# for i18n + +SET(POFILES en_US.po en.po ko_KR.po pl.po ) + +SET(MSGFMT "/usr/bin/msgfmt") + +FOREACH(pofile ${POFILES}) + SET(pofile ${CMAKE_CURRENT_SOURCE_DIR}/${pofile}) + MESSAGE("PO: ${pofile}") + GET_FILENAME_COMPONENT(absPofile ${pofile} ABSOLUTE) + GET_FILENAME_COMPONENT(lang ${absPofile} NAME_WE) + SET(moFile ${CMAKE_CURRENT_BINARY_DIR}/${lang}.mo) + ADD_CUSTOM_COMMAND( + OUTPUT ${moFile} + COMMAND ${MSGFMT} -o ${moFile} ${absPofile} + DEPENDS ${absPofile} + ) + +INSTALL(FILES ${moFile} DESTINATION /usr/share/locale/${lang}/LC_MESSAGES RENAME ${PROJECT_NAME}.mo) + + +SET(moFiles ${moFiles} ${moFile}) +ENDFOREACH(pofile) + +MESSAGE(".mo files: ${moFiles}") +ADD_CUSTOM_TARGET(po ALL DEPENDS ${moFiles}) diff --git a/data/po/en.po b/data/po/en.po new file mode 100644 index 0000000..f54f86c --- /dev/null +++ b/data/po/en.po @@ -0,0 +1,104 @@ +msgid "IDS_SCROLL_UP" +msgstr "scroll up" + +msgid "IDS_SCROLL_DOWN" +msgstr "scroll down" + +msgid "IDS_CENTER" +msgstr "center" + +msgid "IDS_SCROLL_LEFT" +msgstr "scroll left" + +msgid "IDS_SCROLL_RIGHT" +msgstr "scroll right" + +msgid "IDS_UP" +msgstr "up" + +msgid "IDS_DOWN" +msgstr "down" + +msgid "IDS_LEFT" +msgstr "left" + +msgid "IDS_RIGHT" +msgstr "right" + +msgid "IDS_HOME" +msgstr "home" + +msgid "IDS_END" +msgstr "end" + +msgid "IDS_OUT" +msgstr "out" + +msgid "IDS_IN" +msgstr "in" + +msgid "IDS_FILL" +msgstr "fill" + +msgid "IDS_PRESS" +msgstr "press" + +msgid "IDS_FREE" +msgstr "free" + +msgid "IDS_EDIT" +msgstr "edit" + +msgid "IDS_DONE" +msgstr "done" + +msgid "IDS_HOUR_UP" +msgstr "hourup" + +msgid "IDS_HOUR_DOWN" +msgstr "hourdown" + +msgid "IDS_MINUTE_UP" +msgstr "minuteup" + +msgid "IDS_MINUTE_DOWN" +msgstr "minutedown" + +msgid "IDS_SECOND_UP" +msgstr "secondup" + +msgid "IDS_SECOND_DOWN" +msgstr "seconddown" + +msgid "IDS_MONDAY" +msgstr "Monday" + +msgid "IDS_TUESDAY" +msgstr "Tuesday" + +msgid "IDS_WEDNESDAY" +msgstr "Wednesday" + +msgid "IDS_THURSDAY" +msgstr "Thursday" + +msgid "IDS_FRIDAY" +msgstr "Friday" + +msgid "IDS_SATURDAY" +msgstr "Saturday" + +msgid "IDS_SUNDAY" +msgstr "Sunday" + +msgid "IDS_BACK" +msgstr "back" + +msgid "IDS_HUE" +msgstr "hue" + +msgid "IDS_SATURATION" +msgstr "saturation" + +msgid "IDS_LIGHTNESS" +msgstr "lightness" diff --git a/data/po/en_US.po b/data/po/en_US.po new file mode 100644 index 0000000..f54f86c --- /dev/null +++ b/data/po/en_US.po @@ -0,0 +1,104 @@ +msgid "IDS_SCROLL_UP" +msgstr "scroll up" + +msgid "IDS_SCROLL_DOWN" +msgstr "scroll down" + +msgid "IDS_CENTER" +msgstr "center" + +msgid "IDS_SCROLL_LEFT" +msgstr "scroll left" + +msgid "IDS_SCROLL_RIGHT" +msgstr "scroll right" + +msgid "IDS_UP" +msgstr "up" + +msgid "IDS_DOWN" +msgstr "down" + +msgid "IDS_LEFT" +msgstr "left" + +msgid "IDS_RIGHT" +msgstr "right" + +msgid "IDS_HOME" +msgstr "home" + +msgid "IDS_END" +msgstr "end" + +msgid "IDS_OUT" +msgstr "out" + +msgid "IDS_IN" +msgstr "in" + +msgid "IDS_FILL" +msgstr "fill" + +msgid "IDS_PRESS" +msgstr "press" + +msgid "IDS_FREE" +msgstr "free" + +msgid "IDS_EDIT" +msgstr "edit" + +msgid "IDS_DONE" +msgstr "done" + +msgid "IDS_HOUR_UP" +msgstr "hourup" + +msgid "IDS_HOUR_DOWN" +msgstr "hourdown" + +msgid "IDS_MINUTE_UP" +msgstr "minuteup" + +msgid "IDS_MINUTE_DOWN" +msgstr "minutedown" + +msgid "IDS_SECOND_UP" +msgstr "secondup" + +msgid "IDS_SECOND_DOWN" +msgstr "seconddown" + +msgid "IDS_MONDAY" +msgstr "Monday" + +msgid "IDS_TUESDAY" +msgstr "Tuesday" + +msgid "IDS_WEDNESDAY" +msgstr "Wednesday" + +msgid "IDS_THURSDAY" +msgstr "Thursday" + +msgid "IDS_FRIDAY" +msgstr "Friday" + +msgid "IDS_SATURDAY" +msgstr "Saturday" + +msgid "IDS_SUNDAY" +msgstr "Sunday" + +msgid "IDS_BACK" +msgstr "back" + +msgid "IDS_HUE" +msgstr "hue" + +msgid "IDS_SATURATION" +msgstr "saturation" + +msgid "IDS_LIGHTNESS" +msgstr "lightness" diff --git a/data/po/ko_KR.po b/data/po/ko_KR.po new file mode 100644 index 0000000..ba35866 --- /dev/null +++ b/data/po/ko_KR.po @@ -0,0 +1,104 @@ +msgid "IDS_SCROLL_UP" +msgstr "위로 스크롤" + +msgid "IDS_SCROLL_DOWN" +msgstr "아래로 스크롤" + +msgid "IDS_CENTER" +msgstr "가운데" + +msgid "IDS_SCROLL_LEFT" +msgstr "왼쪽으로 스크롤" + +msgid "IDS_SCROLL_RIGHT" +msgstr "오른쪽으로 스크롤" + +msgid "IDS_UP" +msgstr "위로" + +msgid "IDS_DOWN" +msgstr "아래로" + +msgid "IDS_LEFT" +msgstr "왼쪽으로" + +msgid "IDS_RIGHT" +msgstr "오른쪽으로" + +msgid "IDS_HOME" +msgstr "처음" + +msgid "IDS_END" +msgstr "끝" + +msgid "IDS_OUT" +msgstr "축소" + +msgid "IDS_IN" +msgstr "확대" + +msgid "IDS_FILL" +msgstr "전체" + +msgid "IDS_PRESS" +msgstr "누르기" + +msgid "IDS_FREE" +msgstr "떼기" + +msgid "IDS_EDIT" +msgstr "편집" + +msgid "IDS_DONE" +msgstr "완료" + +msgid "IDS_HOUR_UP" +msgstr "시간 증가" + +msgid "IDS_HOUR_DOWN" +msgstr "시간 감소" + +msgid "IDS_MINUTE_UP" +msgstr "분 증가" + +msgid "IDS_MINUTE_DOWN" +msgstr "분 감소" + +msgid "IDS_SECOND_UP" +msgstr "초 증가" + +msgid "IDS_SECOND_DOWN" +msgstr "초 감소" + +msgid "IDS_MONDAY" +msgstr "월요일" + +msgid "IDS_TUESDAY" +msgstr "화요일" + +msgid "IDS_WEDNESDAY" +msgstr "수요일" + +msgid "IDS_THURSDAY" +msgstr "목요일" + +msgid "IDS_FRIDAY" +msgstr "금요일" + +msgid "IDS_SATURDAY" +msgstr "토요일" + +msgid "IDS_SUNDAY" +msgstr "일요일" + +msgid "IDS_BACK" +msgstr "뒤로" + +msgid "IDS_HUE" +msgstr "색깔" + +msgid "IDS_SATURATION" +msgstr "채도" + +msgid "IDS_LIGHTNESS" +msgstr "명도" diff --git a/data/po/pl.po b/data/po/pl.po new file mode 100644 index 0000000..dfc54e5 --- /dev/null +++ b/data/po/pl.po @@ -0,0 +1,404 @@ +msgid "IDS_CLICK" +msgstr "pociśnij" + +msgid "IDS_DOUBLE" +msgstr "ciśnij" + +msgid "IDS_PRESS" +msgstr "wciśnij" + +msgid "IDS_FREE" +msgstr "zwolnij" + +msgid "IDS_DEFAULT" +msgstr "domyślne" + +msgid "IDS_HELP" +msgstr "pomoc" + +msgid "IDS_DOWN" +msgstr "dół" + +msgid "IDS_UP" +msgstr "góra" + +msgid "IDS_CHANGE" +msgstr "zmień" + +msgid "IDS_LEFT" +msgstr "lewo" + +msgid "IDS_CENTER" +msgstr "środek" + +msgid "IDS_RIGHT" +msgstr "prawo" + +msgid "IDS_SHOW" +msgstr "pokaż" + +msgid "IDS_HIDE" +msgstr "ukryj" + +msgid "IDS_TOP" +msgstr "wierzch" + +msgid "IDS_BOTTOM" +msgstr "spód" + +msgid "IDS_IN" +msgstr "do" + +msgid "IDS_OUT" +msgstr "z" + +msgid "IDS_FIT" +msgstr "dopasuj" + +msgid "IDS_FIT_IN" +msgstr "pasuj" + +msgid "IDS_FILL" +msgstr "wypełnij" + +msgid "IDS_MORE_ALFA" +msgstr "więcej alfa" + +msgid "IDS_LESS_ALFA" +msgstr "mniej alfa" + +msgid "IDS_RED_MORE" +msgstr "więcej czerwieni" + +msgid "IDS_RED_LESS" +msgstr "mniej czerwieni" + +msgid "IDS_GREEN_MORE" +msgstr "więcej zieleni" + +msgid "IDS_GREEN_LESS" +msgstr "mniej zielni" + +msgid "IDS_BLUE_MORE" +msgstr "więcej niebieskiego" + +msgid "IDS_BLUE_LESS" +msgstr "mniej niebieskiego" + +msgid "IDS_EDIT" +msgstr "edytuj" + +msgid "IDS_DONE" +msgstr "zatwierdź" + +msgid "IDS_HOUR_UP" +msgstr "godzina więcej" + +msgid "IDS_HOUR_DOWN" +msgstr "godzina mniej" + +msgid "IDS_MINUTE_UP" +msgstr "minuta więcej" + +msgid "IDS_MINUTE_DOWN" +msgstr "minuta mniej" + +msgid "IDS_SECOND_UP" +msgstr "sekunda więcej" + +msgid "IDS_SECOND_DOWN" +msgstr "sekunda mniej" + +msgid "IDS_NEXT" +msgstr "następny" + +msgid "IDS_PREVIOUS" +msgstr "poprzedni" + +msgid "IDS_ADD" +msgstr "dodaj" + +msgid "IDS_ALPHA" +msgstr "Alfa" + +msgid "IDS_BRAVO" +msgstr "Bravo" + +msgid "IDS_CHARLIE" +msgstr "Charlie" + +msgid "IDS_DELTA" +msgstr "Delta" + +msgid "IDS_ECHO" +msgstr "Echo" + +msgid "IDS_FOXTROT" +msgstr "Foxtrot" + +msgid "IDS_GOLF" +msgstr "Golf" + +msgid "IDS_HOTEL" +msgstr "Hotel" + +msgid "IDS_INDIA" +msgstr "India" + +msgid "IDS_JULIET" +msgstr "Juliet" + +msgid "IDS_KILO" +msgstr "Kilo" + +msgid "IDS_LIMA" +msgstr "Lima" + +msgid "IDS_MIKE" +msgstr "Mike" + +msgid "IDS_NOVEMBER" +msgstr "November" + +msgid "IDS_OSCAR" +msgstr "Oscar" + +msgid "IDS_PAPA" +msgstr "Papa" + +msgid "IDS_QUEBEC" +msgstr "Quebec" + +msgid "IDS_ROMEO" +msgstr "Romeo" + +msgid "IDS_SIERRA" +msgstr "Sierra" + +msgid "IDS_TANGO" +msgstr "Tango" + +msgid "IDS_UNIFORM" +msgstr "Uniform" + +msgid "IDS_VICTOR" +msgstr "Victor" + +msgid "IDS_WHISKEY" +msgstr "Whiskey" + +msgid "IDS_X_RAY" +msgstr "Xray" + +msgid "IDS_YANKEE" +msgstr "Yankee" + +msgid "IDS_ZULU" +msgstr "Zulu" + +msgid "IDS_BACK" +msgstr "wstecz" + +msgid "IDS_MONDAY" +msgstr "poniedziałek" + +msgid "IDS_TUESDAY" +msgstr "wtorek" + +msgid "IDS_WEDNESDAY" +msgstr "środa" + +msgid "IDS_THURSDAY" +msgstr "czwartek" + +msgid "IDS_FRIDAY" +msgstr "piątek" + +msgid "IDS_SATURDAY" +msgstr "sobota" + +msgid "IDS_SUNDAY" +msgstr "niedziela" + +msgid "IDS_MORECOLOR" +msgstr "kolorowy" + +msgid "IDS_LESSCOLOR" +msgstr "szary" + +msgid "IDS_SATURATE" +msgstr "nasyć" + +msgid "IDS_UNSATURATE" +msgstr "nienasycony" + +msgid "IDS_BRIGHTER" +msgstr "jasny" + +msgid "IDS_DARKER" +msgstr "ciemny" + +msgid "IDS_OK" +msgstr "ok" + +msgid "IDS_CANCEL" +msgstr "anuluj" + +msgid "IDS_FILES" +msgstr "pliki" + +msgid "IDS_BUTTON" +msgstr "przycisk" + +msgid "IDS_BUBBLE" +msgstr "dymek" + +msgid "IDS_IMAGE" +msgstr "obraz" + +msgid "IDS_FRAME" +msgstr "ramka" + +msgid "IDS_VIDEO" +msgstr "video" + +msgid "IDS_FLIP" +msgstr "flip" + +msgid "IDS_PHOTOCAM" +msgstr "photocam" + +msgid "IDS_THUMBNAIL" +msgstr "miniatura" + +msgid "IDS_SPINNER" +msgstr "spinner" + +msgid "IDS_PHOTO" +msgstr "foto" + +msgid "IDS_MENU" +msgstr "menu" + +msgid "IDS_CLOCK" +msgstr "zegar" + +msgid "IDS_MAP" +msgstr "mapa" + +msgid "IDS_YES" +msgstr "tak" + +msgid "IDS_NO" +msgstr "nie" + +msgid "IDS_FIRST" +msgstr "pierwszy" + +msgid "IDS_SECOND" +msgstr "drugi" + +msgid "IDS_THIRD" +msgstr "trzeci" + +msgid "IDS_FOURTH" +msgstr "czwarty" + +msgid "IDS_CHOICE" +msgstr "wybór" + +msgid "IDS_PAGE" +msgstr "strona" + +msgid "IDS_CUBE" +msgstr "sześcian" + +msgid "IDS_ROTATE" +msgstr "obrót" + +msgid "IDS_VERTICAL" +msgstr "pionowy" + +msgid "IDS_HORIZONTAL" +msgstr "poziomy" + +msgid "IDS_ALARM" +msgstr "alarm" + +msgid "IDS_DECISION" +msgstr "decyzja" + +msgid "IDS_NUMBERS" +msgstr "liczby" + +msgid "IDS_TOP_LEFT" +msgstr "lewy górny" + +msgid "IDS_TOP_RIGHT" +msgstr "prawy górny" + +msgid "IDS_BOTTOM_LEFT" +msgstr "lewy dolny" + +msgid "IDS_BOTTOM_RIGHT" +msgstr "prawy dolny" + +msgid "IDS_HOME" +msgstr "home" + +msgid "IDS_DELETE" +msgstr "usuń" + +msgid "IDS_INDEX" +msgstr "indeks" + +msgid "IDS_FILE" +msgstr "plik" + +msgid "IDS_LIST" +msgstr "lista" + +msgid "IDS_REWIND" +msgstr "do tyłu" + +msgid "IDS_PLAY" +msgstr "start" + +msgid "IDS_PAUSE" +msgstr "pauza" + +msgid "IDS_FORWARD" +msgstr "do przodu" + +msgid "IDS_HUE" +msgstr "Odcień" + +msgid "IDS_SATURATION" +msgstr "Nasycenie" + +msgid "IDS_LIGHTNESS" +msgstr "Jasność" + +msgid "IDS_SEND" +msgstr "WYŚLIJ" + +msgid "IDS_YEAR" +msgstr "rok" + +msgid "IDS_MONTH" +msgstr "miesiąc" + +msgid "IDS_DAY" +msgstr "dzień" + +msgid "IDS_HOUR" +msgstr "godzina" + +msgid "IDS_MINUTE" +msgstr "minuta" + +msgid "IDS_PLAYER" +msgstr "odtwarzacz" + +msgid "IDS_TOOLBAR" +msgstr "toolbar" diff --git a/data/tooltip.edc b/data/tooltip.edc new file mode 100644 index 0000000..672c338 --- /dev/null +++ b/data/tooltip.edc @@ -0,0 +1,43 @@ +#define OFF_MINUS -7 +#define OFF_PLUS 5 +#define SIZE 12 +#define VISI 0 +collections { + group { + name: "tip_group"; + + parts { + part { + name: "bg"; + type: SWALLOW; + + description { + state: "default" 0.0; + visible: 1; + } + } + + + + part { + name: "content"; + type: SWALLOW; + mouse_events: 0; + description { + state: "default" 0.0; + color: 130 200 228 128; + visible: 1; + rel1 { + to: "bg"; + relative: 0.2 0.2; + } + rel2 { + to: "bg"; + relative: 0.8 0.8; + } + } + } + } + + } +} diff --git a/data/voice-control-elm.edc b/data/voice-control-elm.edc new file mode 100644 index 0000000..4d77722 --- /dev/null +++ b/data/voice-control-elm.edc @@ -0,0 +1 @@ +#include "tooltip.edc" diff --git a/doc/Doxyfile b/doc/Doxyfile new file mode 100644 index 0000000..83c1788 --- /dev/null +++ b/doc/Doxyfile @@ -0,0 +1,1600 @@ +# Doxyfile 1.6.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set +# FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../include/ ../doc/ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = images + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = YES + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/doc/images/hints_orientation.png b/doc/images/hints_orientation.png new file mode 100644 index 0000000..cb45e2c Binary files /dev/null and b/doc/images/hints_orientation.png differ diff --git a/doc/images/sample_app_hints.png b/doc/images/sample_app_hints.png new file mode 100644 index 0000000..f0b728a Binary files /dev/null and b/doc/images/sample_app_hints.png differ diff --git a/doc/images/sample_app_no_hints.png b/doc/images/sample_app_no_hints.png new file mode 100644 index 0000000..3b99120 Binary files /dev/null and b/doc/images/sample_app_no_hints.png differ diff --git a/doc/images/subitem_hints_left_and_right.png b/doc/images/subitem_hints_left_and_right.png new file mode 100644 index 0000000..201ecf8 Binary files /dev/null and b/doc/images/subitem_hints_left_and_right.png differ diff --git a/doc/uix_voice_control_elm_doc.h b/doc/uix_voice_control_elm_doc.h new file mode 100644 index 0000000..2340339 --- /dev/null +++ b/doc/uix_voice_control_elm_doc.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2011-2014 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. + */ + + +/** + * @defgroup VOICE_CONTROL_ELEMENTARY_MODULE Voice control elementary + * @ingroup CAPI_UIX_FRAMEWORK + * @brief The @ref VOICE_CONTROL_ELEMENTARY_MODULE API provides functions to control widget by voice commands. + * + * @section VOICE_CONTROL_ELEMENTARY_MODULE_HEADER Required Header + * \#include + * + * @section VOICE_CONTROL_ELEMENTARY_MODULE_OVERVIEW Overview + * The voice control elementary API is provided for controlling widgets by voice commands. + * The voice UI control provided by voice control elementary is done the following way: + * + * - Each widget supported and currently visible in the application is given a text hint.
+ * - Widget hints are shown on the User's wish.
+ * - User speaks the hint name of the widget he/she wants to trigger and the action he/she wants to perform on that widget.
+ * - The voice command is interpreted and the requested action on the widget is performed.
+ * + * To use of voice control elementary, use the following steps: + * 1. Initialize voice control elementary + * 2. Register callback functions for notifications + * 3. Create a handle after creating an evas object or elementary object item + * 4. Set command and hint + * 5. Set hint direction if you want to change hint position + * 6. Run action mapped widget which is spoken by user + * 7. Destroy handle + * 8. Uninitialize voice control elementary + * + * When window is updated by user's operation with touch, key or etc, it is needed to set command and hint creating evas object or elementary object item.
+ * And the callback function of action related to widget is called internally, when user speaks a particular widget's hint. + * + * @image html sample_app_hints.png Example: your application layout with voice control elementary enabled with default settings. + * + * Here is an example code for supporting voice control elm module : + * @code + * #include + * #include + * + * static int _create_app(void *data) + * { + * vc_elm_initialize(); + * vc_elm_set_current_language_changed_cb(_vc_elm_language_changed_cb, NULL); + * elm_main(0, (char **)NULL); + * return 0; + * } + * + * static int _terminate_app(void *data) + * { + * vc_elm_deinitialize(); + * return 0; + * } + * + * int main(int argc, char **argv) + * { + * struct appcore_ops ops; + * ops.create = _create_app; + * ops.terminate = _terminate_app; + * ops.pause = NULL; + * ops.resume = NULL; + * ops.reset = NULL; + * return appcore_efl_main("vc-elm-test", &argc, &argv, &ops); + * } + * @endcode + * + * If you want to create some widgets with voice control, you can refer below function. + * + * @code + * int elm_main(int argc, char **argv) + * { + * Evas_Object* win; + * Evas_Object* btn; + * vc_elm_h vc_elm_buttons_h; + * + * win = elm_win_add(NULL, "example", ELM_WIN_BASIC); + * elm_win_title_set(win, "example"); + * elm_win_autodel_set(win, EINA_TRUE); + * evas_object_resize(win, 720, 1280); + * evas_object_show(win); + * + * btn = elm_button_add(win); + * elm_object_text_set(btn, "Button"); + * evas_object_move(btn, 50, 50); + * evas_object_resize(btn, 200, 50); + * + * vc_elm_create_object(btn, &vc_elm_buttons_h); + * vc_elm_set_command(vc_elm_buttons_h, "Button"); + * vc_elm_set_hint(vc_elm_buttons_h, "Button"); + * + * evas_object_show(btn); + * return 0; + * } + * @endcode + * + * If you want to support several language for voice control elm module, you need to set language changed callback function. + * + * @code + * void _vc_elm_language_changed_cb(void) + * { + * // You need to update codes in order to change text of command & hint according to changed language. + * } + * @endcode + * + * @section VOICE_CONTROL_ELEMENTARY_MODULE_FEATURE Related Features + * This API is related with the following features:
+ * - http://tizen.org/feature/microphone
+ * + * It is recommended to design feature related codes in your application for reliability.
+ * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.
+ * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.
+ * More details on featuring your application can be found from Feature Element. + * + */ + + + diff --git a/doc/voice-control-elm-doc.dox b/doc/voice-control-elm-doc.dox new file mode 100644 index 0000000..cf2318b --- /dev/null +++ b/doc/voice-control-elm-doc.dox @@ -0,0 +1,276 @@ +/** + + +* @defgroup voice-control-elm-devguide voice-control-elm Developer Guide +* +* +* @addtogroup voice-control-elm-devguide +* @{ +* +* @brief This document is a guide to EFL application developers helping to use voice-control-elm to enable voice-driven UI control in the application. +* @section voice-control-elm-devguide_TOC Table of Contents +* @ref voice-control-elm-devguide_INTRO \n +* In this section you will find basic explanation of voice-control-elm, its default settings and a brief description of additional API.\n\n +* @ref voice-control-elm-devguide_QUICKSTART \n +* In this section you will find how to provide your Elementary widgets-based app with voice control with its default settings.\n\n +* @ref voice-control-elm-devguide_DEFAULT_WIDGETS \n +* Here you will find list of all Elementary widgets that are supported by default.\n\n +* @ref voice-control-elm-devguide_HINTSENABLE \n +* In this section you will learn how to use API to disable and enable widgets' hints.\n\n +* @ref voice-control-elm-devguide_HINTSCUSTOM \n +* In this section you will learn how to use API to create hints with custom names and positions.\n\n +* @ref voice-control-elm-devguide_CUSTOMWIDGETS \n +* In this section you will learn how to use API to support custom widgets.\n\n +* @ref voice-control-elm-devguide_CLIPBOARD \n +* In this section you will learn how to use API to support clipboard operations.\n\n +* @ref voice-control-elm-devguide_CUSTOMCMD \n +* In this section you will learn how to use API to support custom voice commands in your application.\n\n +* +* +* @section voice-control-elm-devguide_INTRO Introduction +* voice-control-elm API is provided for controlling EFL widgets by voice commands. +* UI voice control provided by voice-control-elm is done the following way:\n +* - Each Elementary widget supported and currently visible in the application +* is given a text hint.\n +* - Widget hints are shown on the User's wish (currently hints are shown when the +* Volume Up hardware button is pressed). +* - While still pressing the Volume Up button, User speaks the hint name of the +* widget he/she wants to trigger and the action he/she wants to perform on that +* widget. +* - When the Volume Up button is released, the voice command is interpreted and +* the requested action on the widget is performed. +* - When User speaks only the widget's hint name, default action is performed, +* usually "Click". +* +* By default voice-control-elm provides support for a selection of operations on +* Elementary widgets (see @ref voice-control-elm-devguide_SUPPORTED_WIDGETS_TABLE), +* automatic hints layout and hint names generation. \n +* +* @image html sample_app_hints.png Example: your application layout with voice-control-elm enabled with default settings. +* +* Additionally, the API is provided, which allows the developer enabling voice +* commands support for custom widgets, switching off/on hint labels for chosen +* widgets and changing the hint label text from default to custom. +* +* @section voice-control-elm-devguide_QUICKSTART Quick start guide +* @brief In this section you will learn how to configure your app to work with +* default voice-control-elm support, which means voice control support for default +* Elementary widgets and automatic hints' names and layout generation. +* @details +* Whole voice-control-elm API is included in voice_control_elm.h header file. To use +* voice-control-elm module inclusion of this file is needed. Assuming that +* appcore-efl API is used for main loop, vc_elm_initialize() function should +* be called in create callback and call vc_elm_shutdown() function in terminate +* callback. Here is an example code: +* @code +* #include +* #include +* +* static int _create_app(void *data) +* { +* vc_elm_initialize(); +* return 0; +* } +* +* static int _terminate_app(void *data) +* { +* vc_elm_shutdown(); +* return 0; +* } + +* int main(int argc, char **argv) +* { +* struct appcore_ops ops = +* { +* .create = _create_app, +* .pause = NULL, +* .resume = NULL, +* .reset = NULL, +* .terminate = _terminate_app, +* }; +* ops.data = NULL; +* return appcore_efl_main("example", &argc, &argv, &ops); +* } +* @endcode +* Rpm implementation doesn’t handle security issues, therefore plug-in is +* needed. In Tizen OS MSM plug-in is used which requires a manifest file - an +* xml file which specifies the access control domain in which their application +* should be running and potentially additional security policies for the +* application. To set properly application’s permission include following +* lines in manifest file: +* @code +* +* +* +* +* +* +* +* +* +* +* +* +* @endcode + +* First line in define section defines a new domain with name mydomain. The +* permit section allows some vc-server and dbus domains to have write, read +* and execute access to newly defined mydomain domain. The request section +* requests for the newly created mydomain domain to have write, read and +* execute access to the dbus, sound_server and vc-server domains. +* +* To build application with GBS add checking for the presence of voice-control-elm +* package in CMakeLists.txt: +* @code +* pkg_check_modules(BASE_PKG REQUIRED ... voice-control-elm) +* @endcode +* and add voice-control-elm to list of required packages in .spec file: +* @code +* BuildRequires: pkgconfig(voice-control-elm) +* @endcode +* +* At this moment you will have working application with default widgets' +* operations supported and with automatically created and positioned widgets' +* hints. +* +* @section voice-control-elm-devguide_DEFAULT_WIDGETS Default supported widgets +* The list of supported widgets and commands can be found here: +* @ref voice-control-elm-devguide_SUPPORTED_WIDGETS_TABLE +* +* @section voice-control-elm-devguide_HINTSENABLE Enabling/disabling displaying of widget hints +* The hint which is visible on screen can be hidden manually by calling +* vc_elm_object_hint_hide(). If the hint was made hidden by calling +* vc_elm_object_hint_hide(), it can be showed by vc_elm_object_hint_show() +* function if it will be visible on screen and only for recognized widgets. +* If you still want to show the hint you can use +* vc_elm_object_force_item_hint_show() function which will show the hint even +* though it is considered unvisible by vc_widet_elm module. However, it will +* work only for following widgets: list, ctxpopup, genlist, gengrid, toolbar, +* segment_control. +* +* @section voice-control-elm-devguide_HINTSCUSTOM Customizing widget hints' names and position +* In this section, you will get to know how to add custom hints to widgets +* (custom hint name and orientation).\n +* @par Custom hint name \n +* When you run your application with voice-control-elm enabled and take no +* additional actions, the hints will be generated automatically for each +* supported widget. So in case of such situation: +* @code + submit_btn = elm_button_add(win); + elm_object_text_set(submit_btn, "Submit"); + evas_object_show(submit_btn); +* @endcode +* you will see the button with text "Submit" and on voice-control-elm activation, +* the hint with autogenerated name (for example "Alpha") will be displayed by +* this button in the automatically chosen place. Saying "Alpha" will trigger +* "click" operation on the button.\n +* However you can change the hint name using #vc_elm_object_hint_set function. +* @code + submit_btn = elm_button_add(win); + vc_elm_object_hint_set(submit_btn, "Submit"); + elm_object_text_set(submit_btn, "Submit"); + evas_object_show(submit_btn); +* @endcode +* In this case you will see the button with text "Submit" and on voice-control-elm +* activation, the hint "Submit" will be displayed by this button. Saying +* "Submit" will trigger "click" operation on the button.\n +* Analogically, the function #vc_elm_item_object_hint_set is available for +* setting the custom hints for the elements of containers such as elm_list.\n +* @par Turning on/off autogenerated hints \n +* If you want to disable all hints that were not generated by you using the +* functions above, you can use #vc_elm_name_autogen_enable with EINA_FALSE as +* an argument. You turn it on again with EINA_TRUE. +* @par Custom hint position \n +* When not defined by application developer, widgets' hints are located +* at most suitable places, as calculated by algorithm. The main purpose for +* that is to set them so they do not cover each other. It is the best way of +* displaying widgets' hints in UI with dynamically changing content.\n +* However sometimes you may want to define exactly where the hint should be +* shown. In this case you should call #vc_elm_object_hint_direction_set. This +* function forces the hint position as related to the widget. The positions +* available are defined by the #vc_elm_direction_e enum.\n +* +* @image html hints_orientation.png Example: various hints orientations. +* +* The similar function exists for containers' subitems. +* If you want to set the hints' positions for all widget subitems (for example +* list items), you call #vc_elm_sub_item_hint_direction_set. +* However notice that you set as the parameter the parent object (the container +* widget, not the subobject item) and as a result you can only set the same +* relative position of tooltips for all widget's subitems.\n +* +* @image html subitem_hints_left_and_right.png Example: the list subitems hints with direction set to VC_ELM_SUB_ITEM_DIRECTION_LEFT and VC_ELM_SUB_ITEM_DIRECTION_RIGHT. Notice that when the hint is located inside the object, it contains no arrow even if it is not in the center of the item. +* +* You can also get the current relative position of subobject hints by using +* #vc_elm_sub_item_hint_direction_get function. +* +* @section voice-control-elm-devguide_CUSTOMWIDGETS Registering own widgets and actions supported for them. +* You can register your own widgets by calling vc_elm_register_widget() +* function. It is recommended to use evas_object_data_set() to obtain widget +* name (see #VC_ELM_CUSTOM_WIDGET_NAME). Second and third argument are not used +* and should have NULL values. If widget is a container, the callback for +* getting subobjects should be passed as fourth argument, otherwise NULL value. +* For one widget you can register more than one action by calling +* vc_elm_register_action(). +* +* @section voice-control-elm-devguide_CLIPBOARD Enabling clipboard (copy/paste) operations support +* Clipboard operations supports only container widgets. To perform clipboard +* operation do long press on an element. The popup with available operations +* show up and you will be able to choose one of them by voice command. To +* determine which operations will be available define filter callback returning +* flags from #vc_elm_copy_paste_flags_e enum. \n +* @code +* static vc_elm_copy_paste_flags_e filter_cb(Evas_Object* o, void* event_data) +* { +* vc_elm_copy_paste_flags_e flags = VC_ELM_COPY_PASTE_FLAGS_NONE; +* if (event_data) +* { +* flags = flags | VC_ELM_COPY_PASTE_FLAGS_CUT | VC_ELM_COPY_PASTE_FLAGS_COPY; +* } +* else +* { +* flags = flags | VC_ELM_COPY_PASTE_FLAGS_ALL; +* } +* (void)o; +* return flags; +* } +* @endcode +* +* To determine action performed after receiving clipboard command define +* another callback: +* @code +* static void copy_mode_cb(Evas_Object* o, vc_elm_copy_paste_flags_e cmd, void* event_data) +* { +* if (VC_ELM_COPY_PASTE_FLAGS_CUT == cmd) +* { +* //handle cut command here +* } +* else if (VC_ELM_COPY_PASTE_FLAGS_COPY == cmd) +* { +* //handle copy command here +* } +* else if (VC_ELM_COPY_PASTE_FLAGS_PASTE == cmd) +* { +* //handle paste command here +* } +* } +* @endcode +* +* To enable clipboard operations call vc_elm_object_copy_paste_enable_set +* function passing widget object and above callbacks : +* @code +* vc_elm_object_copy_paste_enable_set(genlist, copy_mode_cb, filter_cb); +* @endcode +* +* @section voice-control-elm-devguide_CUSTOMCMD Customizing voice commands +* There is the set of default voice commands, but can also define your own. +* To add a new command call vc_elm_custom_command_add() function with the name +* of command as argument. You can add more than one custom command. There is +* also vc_elm_custom_command_del() function which deletes the command with +* given name. To define action performed after custom command was recognized, +* use vc_elm_custom_command_callback_add(). You can register only one callback +* for all custom commands and only one time. Please note that these functions +* don’t assign anything to widgets. +* +* @} +*/ diff --git a/doc/voice-control-elm_supported_widgets.dox b/doc/voice-control-elm_supported_widgets.dox new file mode 100644 index 0000000..88b9aa1 --- /dev/null +++ b/doc/voice-control-elm_supported_widgets.dox @@ -0,0 +1,3157 @@ +/** + * + * @addtogroup voice-control-elm-devguide + * @{ + * @section voice-control-elm-devguide_SUPPORTED_WIDGETS_TABLE APPENDIX: Supported default Elementary widgets + * + * @htmlonly + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
voice-control-elm - supported commands for Elementary widgets:
Widget Typesub widgetActionclickscroll upscroll downcenterscroll leftscroll rightupdownleftrighttop/homebottom/endzoom outzoom infill
Command( )scroll upscroll downcenterscroll leftscroll rightupdownleftrighthomeendoutinfill
Actionslider + (CallSlider)-3   moves center    moves leftmoves right     
Background-None               
Bubble-1click              
Button-1click              
Calender-5    previous monthnext monthmove upmoves downmove leftmove right     
Checkbox-1click              
Clockedit1edit              
done1done              
hour2      hour uphour down       
minute2      min upmin down       
second2      sec upsec down       
Colorselectorhue4    move left
+ 5 step
move right
+ 5 step
  move leftmove right     
saturation4    move left
+ 5 step
move right
+ 5 step
  move leftmove right     
lightness4    move left
+ 5 step
move right
+ 5 step
  move leftmove right     
CtxPopup-1click              
Datetimebutton name1click              
scroll + bar5click   scroll leftscroll right  move left move right     
DayselectorMonday1click              
Thueday1click              
Wednesday1click              
Thursday1click              
Firday1click              
Saturday1click              
Sunday1click              
Diskselector-5click   scroll leftscroll right  moves left moves right     
Entry-1click              
File Selector Button-1click              
File + Selector Entry-None               
File Selectorbutton name1click              
list + name7clickscroll upscroll down   moves upmove down  move topmove bottom   
Flip- click     moves upmove downmoves left moves right     
Flip + selector-2      moves upmoves down       
Frame-1click              
Genlistbutton name7clickscroll upscroll down   moves upmove down  move topmove bottom   
GL + View-None               
Hover-None               
Hoverselbutton name1click              
Icon-1click              
Image-1click              
index + (Fast Scroll)sub (A~Z)1click              
Inwinbutton name1click              
Listbutton name7clickscroll upscroll down   moves upmove down  move topmove bottom   
Label-None               
Map-10 scroll upscroll down scroll leftscroll rightmoves upmove downmove leftmove right  zoom outzoom in 
Mapbuf-None               
Menu-None               
Notify-None               
Panel-5clickshow / hideshow / hide show / hideshow / hide         
Photo-1click              
Photocam-14 scroll upscroll downmove centerscroll leftscroll rightmove up smallmove down smallmove left smallmove right smallmove to topmove to bottonzoom outzoom infill window
Popupbutton name1click              
Progress bar-None               
Radio-1click              
Route-None               
SegmentControlbutton name1click              
Separator-None               
Slider-11 move up moremove down
+ more
move centermove left moremove right moremove upmove downmove leftmove rightmove homemove end   
Slideshow-None               
Spinner-6      click leftclick rightclick leftclick rightmove startmove end   
Thumbnail-1click              
Toolbarbutton name10clickmove up moremove down
+ more
 move left moremove right moremoves upmove downmove leftmove rightmove topmove bottom   
Tooltips-None               
videobutton name1click              
Web-None               
+ +
+ + + + + + + + + +* +* @endhtmlonly +* @} +*/ diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100644 index 0000000..02a3dba --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,5 @@ +FILE(GLOB VC_ELM_HEADERS *.h) +INSTALL(FILES ${VC_ELM_HEADERS} DESTINATION ${INCLUDEDIR}) + +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) +INSTALL(FILES ${CMAKE_BINARY_DIR}/include/${PROJECT_NAME}.pc DESTINATION ${LIBDIR}/pkgconfig) diff --git a/include/voice-control-elm.pc.in b/include/voice-control-elm.pc.in new file mode 100644 index 0000000..d92a914 --- /dev/null +++ b/include/voice-control-elm.pc.in @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@/bin +libdir=@CMAKE_INSTALL_PREFIX@/lib +includedir=@CMAKE_INSTALL_PREFIX@/include + +Name: lib@LIBRARY_NAME@ +Description: voice-control-elm library +Requires: elementary evas +Version: @VERSION@ +Libs: -L${libdir} -l@LIBRARY_NAME@ +Cflags: -I${includedir} diff --git a/include/voice_control_elm.h b/include/voice_control_elm.h new file mode 100644 index 0000000..b7b76e7 --- /dev/null +++ b/include/voice_control_elm.h @@ -0,0 +1,618 @@ +/* +* 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 VOICE_CONTROL_ELEMENTARY_H_ +#define VOICE_CONTROL_ELEMENTARY_H_ + + +#include +#include +#include + +/** +* @addtogroup VOICE_CONTROL_ELEMENTARY_MODULE +* @{ +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @file voice_control_elm.h +* @brief This file contains the voice control elementary API and related handle definitions and enums. +*/ + +/** +* @brief This enum describes status of voice control elementary after API call +* @since_tizen 2.4 +*/ +typedef enum { + VC_ELM_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + VC_ELM_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of Memory */ + VC_ELM_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */ + VC_ELM_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + VC_ELM_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + VC_ELM_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< voice control elementary NOT supported */ + VC_ELM_ERROR_INVALID_STATE = TIZEN_ERROR_VOICE_CONTROL | 0x021, /**< Invalid state */ + VC_ELM_ERROR_INVALID_LANGUAGE = TIZEN_ERROR_VOICE_CONTROL | 0x022, /**< Invalid language */ + VC_ELM_ERROR_OPERATION_FAILED = TIZEN_ERROR_VOICE_CONTROL | 0x023, /**< Operation failed */ + VC_ELM_ERROR_OPERATION_REJECTED = TIZEN_ERROR_VOICE_CONTROL | 0x024 /**< Operation rejected */ +} vc_elm_error_e; + +/** +* @brief This enum describes directions of the widget hints. +* @since_tizen 2.4 +* +* @see vc_elm_set_hint_direction() +* +* @image html hints_orientation.png Example: various hints orientations. +*/ +typedef enum { + VC_ELM_DIRECTION_CENTER = 0, /**< Direction displayed to the center of the widget */ + VC_ELM_DIRECTION_LEFT = 1, /**< Direction displayed to the left of the widget */ + VC_ELM_DIRECTION_RIGHT = 2, /**< Direction displayed to the right of the widget */ + VC_ELM_DIRECTION_TOP = 3, /**< Direction displayed to the top of the widget */ + VC_ELM_DIRECTION_BOTTOM = 4, /**< Direction displayed to the bottom of the widget */ + VC_ELM_DIRECTION_LEFT_TOP = 5, /**< Direction displayed to the top left corner of the widget */ + VC_ELM_DIRECTION_LEFT_BOTTOM = 6, /**< Direction displayed to the bottom left corner of the widget */ + VC_ELM_DIRECTION_RIGHT_TOP = 7, /**< Direction displayed to the top right corner of the widget */ + VC_ELM_DIRECTION_RIGHT_BOTTOM = 8 /**< Direction displayed to the bottom right corner of the widget */ +} vc_elm_direction_e; + +/** +* @brief A handle to the voice control elementary for object or item object +* @since_tizen 2.4 +*/ +typedef struct vc_elm_s* vc_elm_h; + +/** +* @brief Called to retrieve supported language. +* @since_tizen 2.4 +* +* @param[in] language A language is specified as an ISO 3166 alpha-2 two letter country-code \n +* followed by ISO 639-1 for the two-letter language code \n +* For example, "ko_KR" for Korean, "en_US" for American English +* @param[in] user_data The user data passed from the foreach function +* +* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop +* @pre The function will invoke this callback. +* +* @see vc_elm_foreach_supported_languages() +*/ +typedef bool (*vc_elm_supported_language_cb)(const char* language, void* user_data); + +/** +* @brief Called when default language is changed. +* @since_tizen 2.4 +* +* @param[in] previous Previous language +* @param[in] current Current language +* @param[in] user_data The user data passed from the callback registration function +* +* @pre An application registers this callback to detect changing language. +* +* @see vc_elm_set_current_language_changed_cb() +*/ +typedef void (*vc_elm_current_language_changed_cb)(const char* previous, const char* current, void* user_data); + +/** +* @brief Called to retrieve supported widget. +* @since_tizen 2.4 +* +* @param[in] widget Widget name +* @param[in] user_data The user data passed from the callback registration function +* +* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop +* @pre The function will invoke this callback. +* +* @see vc_elm_foreach_supported_widgets() +*/ +typedef bool (*vc_elm_widget_cb)(const char* widget, void* user_data); + +/** +* @brief Called to retrieve supported action. +* @since_tizen 2.4 +* +* @param[in] action Action name +* @param[in] user_data The user data passed from the callback registration function +* +* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop +* @pre The function will invoke this callback. +* +* @see vc_elm_foreach_supported_actions() +*/ +typedef bool (*vc_elm_action_cb)(const char* action, void* user_data); + + +/** +* @brief Initializes voice control elementary module. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @remarks If the function succeeds, the voice control elementary must be released with vc_elm_deinitialize(). +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_OUT_OF_MEMORY Out of memory +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @see vc_elm_deinitialize() +*/ +int vc_elm_initialize(void); + +/** +* @brief Deinitializes voice control elementary module. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_OUT_OF_MEMORY Out of memory +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre vc_elm_initialize() should be successful. +* +* @see vc_elm_initialize() +*/ +int vc_elm_deinitialize(void); + +/** +* @brief Retrieves all supported languages using callback function. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] callback Callback function to invoke +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre vc_elm_initialize() should be successful. +* @post This function invokes vc_supported_language_cb() repeatedly for getting languages. +* +* @see vc_elm_supported_language_cb() +* @see vc_elm_get_current_language() +*/ +int vc_elm_foreach_supported_languages(vc_elm_supported_language_cb callback, void* user_data); + +/** +* @brief Gets current language. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @remark If the function succeeds, @a language must be released with free() by you when you no longer need it. +* +* @param[out] language A language is specified as an ISO 3166 alpha-2 two letter country-code \n +* followed by ISO 639-1 for the two-letter language code \n +* For example, "ko_KR" for Korean, "en_US" for American English +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OUT_OF_MEMORY Out of memory +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre vc_elm_initialize() should be successful. +*/ +int vc_elm_get_current_language(char** language); + +/** +* @brief Retrieves all supported widget using callback function. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] callback Callback function to invoke +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre vc_elm_initialize() should be successful. +* @post This function invokes vc_elm_widget_cb() repeatedly for getting widgets. +* +* @see vc_elm_widget_cb() +* @see vc_elm_foreach_supported_actions() +*/ +int vc_elm_foreach_supported_widgets(vc_elm_widget_cb callback, void* user_data); + +/** +* @brief Retrieves all supported actions of widget using callback function. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] widget Widget name +* @param[in] callback Callback function to invoke +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre vc_elm_initialize() should be successful and widget name can get from vc_elm_foreach_supported_widgets(). +* @post This function invokes vc_elm_action_cb() repeatedly for getting actions. +* +* @see vc_elm_action_cb() +* @see vc_elm_foreach_supported_widgets() +*/ +int vc_elm_foreach_supported_actions(const char* widget, vc_elm_action_cb callback, void* user_data); + +/** +* @brief Gets action command of action. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @remark If the function succeeds, @a command must be released with free() by you when you no longer need it. \n +* If command is NULL, the action is default action. The default action works by only command of widget. +* +* @param[in] action Action name +* @param[out] command Command for action +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OUT_OF_MEMORY Out of memory +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre vc_elm_initialize() should be successful. +*/ +int vc_elm_get_action_command(const char* action, char** command); + +/** +* @brief Creates vc elm handle for evas object. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @remarks If the function succeeds, The vc elm handle must be released with vc_elm_destroy(). +* +* @param[in] object Evas object included in handle +* @param[out] vc_elm The voice control elementary handle +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_OUT_OF_MEMORY Out of memory +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_OPERATION_REJECTED Operation rejected when widget is not supported +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre vc_elm_initialize() should be successful. +* +* @see vc_elm_destroy() +*/ +int vc_elm_create_object(Evas_Object* object, vc_elm_h* vc_elm); + +/** +* @brief Creates vc elm handle for elm object item. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @remarks If the function succeeds, The vc elm handle must be released with vc_elm_destroy(). +* +* @param[in] item The elm Object item included in handle +* @param[out] vc_elm Handle containing pointer to widget +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_OUT_OF_MEMORY Out of memory +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre vc_elm_initialize() should be successful. +* +* @see vc_elm_destroy() +*/ +int vc_elm_create_item(Elm_Object_Item* item, vc_elm_h* vc_elm); + +/** +* @brief Destroys the handle. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] vc_elm Handle containing pointer to widget +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre The vc elm handle should be valid with vc_elm_create_object() or vc_elm_create_item(). +* +* @see vc_elm_create() +*/ +int vc_elm_destroy(vc_elm_h vc_elm); + +/** +* @brief Sets command to the handle. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] vc_elm Handle containing pointer to widget +* @param[in] command Command's text +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful. +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre The vc_elm handle should be valid with vc_elm_create_object() or vc_elm_create_item(). +* +* @see vc_elm_unset_command() +*/ +int vc_elm_set_command(vc_elm_h vc_elm, const char* command); + +/** +* @brief Unsets command from the handle. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] vc_elm Handle to include pointer to widget +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre The vc_elm handle should be valid with vc_elm_create_object() or vc_elm_create_item(). +* +* @see vc_elm_set_command() +*/ +int vc_elm_unset_command(vc_elm_h vc_elm); + +/** +* @brief Set command hint for the handle. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] vc_elm Handle containing pointer to widget +* @param[in] hint Hint's text +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre The vc_elm handle should be valid with vc_elm_create_object() or vc_elm_create_item(). +* +* @see vc_elm_unset_command_hint() +*/ +int vc_elm_set_command_hint(vc_elm_h vc_elm, const char* hint); + +/** +* @brief Unset command hint for the handle. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] vc_elm Handle containing pointer to widget +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre The vc_elm handle should be valid with vc_elm_create_object() or vc_elm_create_item(). +* +* @see vc_elm_set_command_hint() +*/ +int vc_elm_unset_command_hint(vc_elm_h vc_elm); + +/** +* @brief Sets the direction of hint to the handle. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @remarks If direction is not set, default direction is pre-configured will be used. +* +* @param[in] vc_elm Handle containing pointer to widget +* @param[in] direction Direction of hint defined by #vc_elm_direction_e +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre The vc_elm handle should be valid with vc_elm_create_object() or vc_elm_create_item(). +* +* @see vc_elm_set_command_hint() +* @see vc_elm_get_command_hint_direction() +*/ +int vc_elm_set_command_hint_direction(vc_elm_h vc_elm, vc_elm_direction_e direction); + +/** +* @brief Unsets the direction of hint from the handle. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] vc_elm Handle containing pointer to widget +* @param[out] direction Direction of hint defined by #vc_elm_direction_e +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre The vc_elm handle should be valid with vc_elm_create_object() or vc_elm_create_item(). +* +* @see vc_elm_set_command_hint_direction() +*/ +int vc_elm_get_command_hint_direction(vc_elm_h vc_elm, vc_elm_direction_e* direction); + +/** +* @brief Sets command hint's x,y position to the handle. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] vc_elm Handle containing pointer to widget +* @param[in] pos_x The x position of hint +* @param[in] pos_y The y position of hint +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre The vc_elm handle should be valid with vc_elm_create_object() or vc_elm_create_item(). +* +* @see vc_elm_set_command_hint() +* @see vc_elm_get_command_hint_offset() +*/ +int vc_elm_set_command_hint_offset(vc_elm_h vc_elm, int pos_x, int pos_y); + +/** +* @brief Gets command hint's x,y position from the handle. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] vc_elm Handle containing pointer to widget +* @param[out] pos_x The x position of hint +* @param[out] pos_y The y position of hint +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_OPERATION_FAILED Operation failed +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre The vc_elm handle should be valid with vc_elm_create_object() or vc_elm_create_item(). +* +* @see vc_elm_set_command_hint_offset() +*/ +int vc_elm_get_command_hint_offset(vc_elm_h vc_elm, int* pos_x, int* pos_y); + + +/** +* @brief Registers a callback function to be called when current language is changed. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] callback Callback function to register +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre vc_elm_initialize() should be successful. +* +* @see vc_elm_unset_current_language_changed_cb() +*/ +int vc_elm_set_current_language_changed_cb(vc_elm_current_language_changed_cb callback, void* user_data); + +/** +* @brief Unregisters the callback function. +* @since_tizen 2.4 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ELM_ERROR_NONE Successful +* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state +* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported +* +* @pre vc_elm_initialize() should be successful. +* +* @see vc_mgr_set_current_language_changed_cb() +*/ +int vc_elm_unset_current_language_changed_cb(); + + +#ifdef _cplusplus +} +#endif + +/** + * @}@} + */ + +#endif /* VOICE_CONTROL_ELEMENTARY_H_ */ diff --git a/packaging/voice-control-elm-devel.manifest b/packaging/voice-control-elm-devel.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/packaging/voice-control-elm-devel.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/voice-control-elm.manifest b/packaging/voice-control-elm.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/packaging/voice-control-elm.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/voice-control-elm.spec b/packaging/voice-control-elm.spec new file mode 100644 index 0000000..a2e8cfa --- /dev/null +++ b/packaging/voice-control-elm.spec @@ -0,0 +1,93 @@ +Name: voice-control-elm +Summary: voice-control-elm library +Version: 0.2.0 +Release: 1 +Group: Graphics & UI Framework/Voice Framework +License: Apache-2.0 +URL: N/A +Source0: %{name}-%{version}.tar.gz +Source1001: %{name}.manifest +Source1002: %{name}-devel.manifest +BuildRequires: cmake +BuildRequires: edje-tools +BuildRequires: pkgconfig(appcore-efl) +BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(evas) +BuildRequires: pkgconfig(eina) +BuildRequires: pkgconfig(ecore) +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(voice-control-widget) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(edje) +BuildRequires: pkgconfig(efl-assist) +BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: gettext-tools + +%description +voice-control-elm library that provides advanced Voice Driven Control over UI + +%package devel +Summary: voice-control-elm library development headers +Group: Development/Libraries +Requires: %{name} = %{version} + +%description devel +voice-control-elm library development headers + +%prep +%setup -q +cp %{SOURCE1001} %{SOURCE1002} . + +%build +export LDFLAGS+="-Wl,--rpath=%{_libdir} -Wl,--hash-style=both -Wl,--as-needed,-lgcov" +rm -rf objdir +mkdir objdir + +%{?SRPOL_DEBUG: +(cd objdir && cmake .. -DVERSION=%{version} \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DLIBDIR=%{_libdir} \ + -DINCLUDEDIR=%{_includedir} \ + -DCMAKE_BUILD_TYPE=Debug \ + -DSRPOL_DEBUG="1") +} +%{!?SRPOL_DEBUG: +(cd objdir && cmake .. -DVERSION=%{version} \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DLIBDIR=%{_libdir} \ + -DINCLUDEDIR=%{_includedir} \ + -DCMAKE_BUILD_TYPE=Debug \ + -DSRPOL_DEBUG="0") +} + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/share/license +install LICENSE %{buildroot}/usr/share/license/%{name} + +(cd objdir && +%make_install) + +%clean +rm -rf %{buildroot} + +%post + +mkdir -p /usr/share/voice +chsmack -a '_' /usr/share/voice + +%files +%manifest %{name}.manifest +%attr(644,root,root) +%defattr(-,root,root,-) +%{_libdir}/*.so +%{_libdir}/*.so.* +%{_datadir}/* +/usr/share/locale/* +%{_libdir}/voice/vc-elm/1.0/voice-control-elm-config.xml + +%files devel +%manifest %{name}-devel.manifest +%{_includedir}/voice_control_elm.h +%{_libdir}/pkgconfig/%{name}.pc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..9cd722a --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,42 @@ +FILE(GLOB VC_ELM_SOURCES *.c) + +SET(VC_ELM_PKGS + capi-base-common + evas + eina + ecore + elementary + dlog + libxml-2.0 + ) + +IF(${SRPOL_DEBUG} EQUAL "1") +ADD_DEFINITIONS("-DSRPOL_DEBUG") +ENDIF(${SRPOL_DEBUG} EQUAL "1") + + SET(VC_ELM_PKGS + ${VC_ELM_PKGS} + voice-control-widget) + +PKG_CHECK_MODULES(VC_ELM_DEPS ${VC_ELM_PKGS} REQUIRED) + +ADD_DEFINITIONS(${VC_ELM_DEPS_CFLAGS}) +ADD_DEFINITIONS(${VC_ELM_DEPS_CFLAGS_OTHER}) + +INCLUDE_DIRECTORIES( + ${VC_ELM_DEPS_INCLUDE_DIRS} + ${VC_ELM_INCLUDE_DIR} + ${PROJECT_SOURCE_DIR}/src + ) + +ADD_LIBRARY(${LIBRARY_NAME} SHARED ${VC_ELM_SOURCES}) +SET_TARGET_PROPERTIES(${LIBRARY_NAME} PROPERTIES + COMPILE_FLAGS -fPIC + SOVERSION "0.2.0" + VERSION "0.2.0") + +TARGET_LINK_LIBRARIES(${LIBRARY_NAME} + ${VC_ELM_DEPS_LIBRARIES}) + + +INSTALL(TARGETS ${LIBRARY_NAME} DESTINATION ${LIBDIR}) diff --git a/src/vc_elm.c b/src/vc_elm.c new file mode 100644 index 0000000..594c8d9 --- /dev/null +++ b/src/vc_elm.c @@ -0,0 +1,757 @@ +/* + * Copyright (c) 2011-2014 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 "vc_elm_main.h" +#include + +#include "vc_elm.h" +#include "vc_elm_core.h" +#include "vc_elm_tools.h" +#include "vc_elm_tooltip.h" +#include "vc_elm_widget_wrapper.h" +#include + +/** +* @brief Internal variable. It can check whether voice control elm is initilaized or not. +*/ +static unsigned is_vc_elm_initialized = false; + +/** + * @brief App domain name of the current app. + */ +static char *g_app_domain = NULL; +static Eina_List *g_handlers_list = NULL; + +typedef enum { + VC_ELM_TYPE_EVAS_OBJECT = 0, VC_ELM_TYPE_ITEM = 1 +} vc_elm_type_e; + +struct __vc_elm_s { + vc_elm_type_e type; + intptr_t *data; +}; + +typedef struct __vc_elm_s vc_elm_s; + +struct __vc_elm_widget_cb_data_s{ + vc_elm_widget_cb callback; + void *data; +}; + +typedef struct __vc_elm_widget_cb_data_s vc_elm_widget_cb_data_s; + +/** + * @brief Internal callback that sets the vc_widget's foreground option to true. + */ +static Eina_Bool __vc_elm_x_event_window_focus_in(void *data, int type, void *event) +{ + (void)data; + (void)type; + (void)event; + + vc_widget_set_foreground(EINA_TRUE); + + VC_ELM_LOG_DBG("Focus in"); + return ECORE_CALLBACK_PASS_ON; +} + +/** + * @brief Internal callback that sets the vc_widget's foreground option to false + */ +static Eina_Bool __vc_elm_x_event_window_focus_out(void *data, int type, void *event) +{ + (void)data; + (void)type; + (void)event; + + vc_widget_set_foreground(EINA_FALSE); + + _vc_elm_turn_off_tooltips(); + + VC_ELM_LOG_DBG("Focus out"); + return ECORE_CALLBACK_PASS_ON; +} + +int vc_elm_initialize() +{ + if (true == is_vc_elm_initialized) { + VC_ELM_LOG_DBG("vc elm is already initialized"); + return VC_ELM_ERROR_INVALID_STATE; + } + + eina_log_level_set(EINA_LOG_LEVEL_DBG); + + _vc_elm_core_enable_name_autogen(EINA_FALSE); + _vc_elm_core_init(); + + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, __vc_elm_x_event_window_focus_in, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, __vc_elm_x_event_window_focus_out, NULL); + + g_handlers_list = NULL; + _vc_elm_core_load(); + + is_vc_elm_initialized = true; + VC_ELM_LOG_DBG("vc elm is initialized"); + return VC_ELM_ERROR_NONE; +} + +int vc_elm_deinitialize() +{ + Eina_List *l; + vc_elm_h handler = NULL; + + if (false == is_vc_elm_initialized) { + VC_ELM_LOG_DBG("vc elm is already deinitialized"); + return VC_ELM_ERROR_INVALID_STATE; + } + + if (NULL != g_handlers_list) { + EINA_LIST_FOREACH(g_handlers_list, l, handler) + { + vc_elm_unset_command(handler); + vc_elm_unset_command_hint(handler); + vc_elm_destroy(handler); + } + eina_list_free(g_handlers_list); + } + + _vc_elm_core_fini(); + + if (NULL != g_app_domain) + free(g_app_domain); + + is_vc_elm_initialized = false; + VC_ELM_LOG_DBG("shutting down vc_elm"); + return VC_ELM_ERROR_NONE; +} + +int vc_elm_foreach_supported_languages(vc_elm_supported_language_cb callback, void *user_data) +{ + int ret = vc_widget_foreach_supported_languages(callback, user_data); + switch (ret) { + case VC_ERROR_NONE: + ret = VC_ELM_ERROR_NONE; + break; + case VC_ERROR_INVALID_PARAMETER: + ret = VC_ELM_ERROR_INVALID_PARAMETER; + break; + case VC_ERROR_INVALID_STATE: + ret = VC_ELM_ERROR_INVALID_STATE; + break; + default: + ret = VC_ELM_ERROR_OPERATION_FAILED; + break; + } + return ret; +} + +int vc_elm_get_current_language(char **language) +{ + int ret = vc_widget_get_current_language(language); + switch (ret) { + case VC_ERROR_NONE: + ret = VC_ELM_ERROR_NONE; + break; + case VC_ERROR_INVALID_PARAMETER: + ret = VC_ELM_ERROR_INVALID_PARAMETER; + break; + case VC_ERROR_OUT_OF_MEMORY: + ret = VC_ELM_ERROR_OUT_OF_MEMORY; + break; + case VC_ERROR_INVALID_STATE: + ret = VC_ELM_ERROR_INVALID_STATE; + break; + default: + ret = VC_ELM_ERROR_OPERATION_FAILED; + break; + } + return ret; +} + +static Eina_Bool __hash_fn(const Eina_Hash *hash, const void *key, void *kdata, void *fdata) +{ + vc_elm_widget_cb_data_s *data; + vc_elm_widget_cb callback; + (void)hash; + (void)kdata; + data = (vc_elm_widget_cb_data_s *)fdata; + callback = data->callback; + callback(key, data->data); + return EINA_TRUE; +} + +int vc_elm_foreach_supported_widgets(vc_elm_widget_cb callback, void *user_data) +{ + vc_elm_widget_cb_data_s data; + const Eina_Hash *hash = NULL; + if (NULL == callback) { + VC_ELM_LOG_ERR("Invalid parameters detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + if (false == is_vc_elm_initialized) { + VC_ELM_LOG_ERR("Invalid state detected! Library not initialized!"); + return VC_ELM_ERROR_INVALID_STATE; + } + data.callback = callback; + data.data = user_data; + hash = _vc_elm_core_get_config_widget_map(); + if (NULL == hash) { + VC_ELM_LOG_ERR("Config widget map is NULL!"); + return VC_ELM_ERROR_OPERATION_FAILED; + } + eina_hash_foreach(hash, __hash_fn, &data); + return VC_ELM_ERROR_NONE; +} + +int vc_elm_foreach_supported_actions(const char *widget, vc_elm_action_cb callback, void *user_data) +{ + const Eina_Hash *hash = NULL; + Eina_List *actions_list = NULL; + Eina_List *l = NULL; + const char *action_tag = NULL; + + if ((NULL == widget) || (NULL == callback)) { + VC_ELM_LOG_ERR("Invalid parameters detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + if (false == is_vc_elm_initialized) { + VC_ELM_LOG_ERR("Invalid state detected! Library not initialized!"); + return VC_ELM_ERROR_INVALID_STATE; + } + hash = _vc_elm_core_get_config_widget_map(); + if (NULL == hash) { + VC_ELM_LOG_ERR("Config widget map is NULL!"); + return VC_ELM_ERROR_OPERATION_FAILED; + } + actions_list = (Eina_List *)eina_hash_find(hash, widget); + if (NULL == actions_list) { + VC_ELM_LOG_ERR("Action list is NULL!"); + return VC_ELM_ERROR_OPERATION_FAILED; + } + EINA_LIST_FOREACH(actions_list, l, action_tag) + { + if (NULL != action_tag) { + callback(action_tag, user_data); + } + } + return VC_ELM_ERROR_NONE; +} + +int vc_elm_get_action_command(const char *action, char **command) +{ + const Eina_Hash *hash = NULL; + const char *command_name = NULL; + size_t len = 0; + if ((NULL == action) || (NULL == command)) { + VC_ELM_LOG_ERR("Invalid parameters detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + if (false == is_vc_elm_initialized) { + VC_ELM_LOG_ERR("Invalid state detected! Library not initialized!"); + return VC_ELM_ERROR_INVALID_STATE; + } + hash = _vc_elm_core_get_config_action_map(); + if (NULL == hash) { + VC_ELM_LOG_ERR("Config action map is NULL!"); + return VC_ELM_ERROR_OPERATION_FAILED; + } + command_name = eina_hash_find(_vc_elm_core_get_config_action_map(), action); + if (NULL == command_name) { + VC_ELM_LOG_ERR("No command for given action name!"); + return VC_ELM_ERROR_OPERATION_FAILED; + } + len = strlen(command_name) + 1; + *command = (char *)calloc(len, sizeof(char)); + if (NULL == *command) { + VC_ELM_LOG_ERR("Can not allocate memory!"); + return VC_ELM_ERROR_OPERATION_FAILED; + } + memcpy(*command, command_name, len); + return VC_ELM_ERROR_NONE; +} + +int vc_elm_create_object(Evas_Object *object, vc_elm_h *vc_elm) +{ + vc_elm_s *handler = NULL; + + if (NULL == vc_elm) { + VC_ELM_LOG_ERR("Invalid parameters detected! (vc_elm_h *) poiter is NULL"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + if ((NULL == object) || (!elm_object_widget_check(object))) { + VC_ELM_LOG_ERR("Invalid parameters detected! Incorrect (Evas_Object *)"); + *vc_elm = NULL; + return VC_ELM_ERROR_INVALID_PARAMETER; + } + if (false == is_vc_elm_initialized) { + VC_ELM_LOG_ERR("Invalid state detected! Library not initialized!"); + return VC_ELM_ERROR_INVALID_STATE; + } + if (!_vc_elm_core_register_default_widget(_get_ui_object_name(object), EINA_FALSE, NULL) || (NULL == eina_hash_find(_vc_elm_core_get_config_widget_map(), elm_widget_type_get(object)))) { + VC_ELM_LOG_ERR("Not supported widget"); + *vc_elm = NULL; + return VC_ELM_ERROR_NOT_SUPPORTED; + } + handler = (vc_elm_s *)calloc(1, sizeof(vc_elm_s)); + if (NULL == handler) { + VC_ELM_LOG_ERR("Calloc function returned NULL"); + return VC_ELM_ERROR_OUT_OF_MEMORY; + } + handler->type = VC_ELM_TYPE_EVAS_OBJECT; + handler->data = (void *)object; + g_handlers_list = eina_list_append(g_handlers_list, handler); + *vc_elm = (vc_elm_h)handler; + return VC_ELM_ERROR_NONE; +} + +int vc_elm_create_item(Elm_Object_Item *item, vc_elm_h *vc_elm) +{ + vc_elm_s *handler = NULL; + if (NULL == vc_elm) { + VC_ELM_LOG_ERR("Invalid parameters detected! (vc_elm_h *) poiter is NULL"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + if (NULL == item) { + VC_ELM_LOG_ERR("Invalid parameters detected! (Elm_Object_Item *) poiter is NULL"); + *vc_elm = NULL; + return VC_ELM_ERROR_INVALID_PARAMETER; + } + if (false == is_vc_elm_initialized) { + VC_ELM_LOG_ERR("Invalid state detected! Library not initialized!"); + return VC_ELM_ERROR_INVALID_STATE; + } + handler = (vc_elm_s *)calloc(1, sizeof(vc_elm_s)); + if (NULL == handler) { + VC_ELM_LOG_ERR("Calloc function returned NULL"); + *vc_elm = NULL; + return VC_ELM_ERROR_OUT_OF_MEMORY; + } + handler->type = VC_ELM_TYPE_ITEM; + handler->data = (void *)item; + g_handlers_list = eina_list_append(g_handlers_list, handler); + *vc_elm = (vc_elm_h)handler; + return VC_ELM_ERROR_NONE; +} + +int vc_elm_destroy(vc_elm_h vc_elm) +{ + vc_elm_s *handler = NULL; + Eina_List *list = NULL; + int type = 0; + if (NULL == vc_elm) { + VC_ELM_LOG_ERR("Invalid vc_elm parameter detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + handler = (vc_elm_s *)vc_elm; + type = handler->type; + if (!((VC_ELM_TYPE_EVAS_OBJECT == type) || (VC_ELM_TYPE_ITEM == type))) { + VC_ELM_LOG_ERR("Invalid type detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + + list = eina_list_data_find_list(g_handlers_list, handler); + if (NULL == list) { + VC_ELM_LOG_ERR("Bad handler pointer detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + g_handlers_list = eina_list_remove_list(g_handlers_list, list); + free(handler); + handler = NULL; + return VC_ELM_ERROR_NONE; +} + +int vc_elm_set_command(vc_elm_h vc_elm, const char *command) +{ + vc_elm_s *handler = (vc_elm_s *)vc_elm; + int type = 0; + if (NULL == vc_elm) { + VC_ELM_LOG_ERR("Invalid vc_elm parameter detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + type = handler->type; + if (VC_ELM_TYPE_EVAS_OBJECT == type) { + Evas_Object *obj = (Evas_Object *)handler->data; + return _vc_elm_set_object_command(obj, command); + } else if (VC_ELM_TYPE_ITEM == type) { + Elm_Object_Item *it = (Elm_Object_Item *)handler->data; + return _vc_elm_set_item_object_command(it, command); + } + return VC_ELM_ERROR_INVALID_PARAMETER; +} + +int vc_elm_unset_command(vc_elm_h vc_elm) +{ + vc_elm_s *handler = (vc_elm_s *)vc_elm; + int type = 0; + if (NULL == vc_elm) { + VC_ELM_LOG_ERR("Invalid vc_elm parameter detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + type = handler->type; + if (VC_ELM_TYPE_EVAS_OBJECT == type) { + Evas_Object *obj = (Evas_Object *)handler->data; + return _vc_elm_unset_object_command(obj); + } else if (VC_ELM_TYPE_ITEM == type) { + Elm_Object_Item *it = (Elm_Object_Item *)handler->data; + return _vc_elm_unset_item_object_command(it); + } + return VC_ELM_ERROR_INVALID_PARAMETER; +} + +int vc_elm_set_command_hint(vc_elm_h vc_elm, const char* hint) +{ + vc_elm_s *handler = (vc_elm_s *)vc_elm; + int type = 0; + if (NULL == vc_elm) { + VC_ELM_LOG_ERR("Invalid vc_elm parameter detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + type = handler->type; + if (VC_ELM_TYPE_EVAS_OBJECT == type) { + Evas_Object *obj = (Evas_Object *)handler->data; + return _vc_elm_set_object_hint(obj, hint); + } else if (VC_ELM_TYPE_ITEM == type) { + Elm_Object_Item *it = (Elm_Object_Item *)handler->data; + return _vc_elm_set_item_object_hint(it, hint); + } + return VC_ELM_ERROR_INVALID_PARAMETER; +} + +int vc_elm_unset_command_hint(vc_elm_h vc_elm) +{ + vc_elm_s *handler = (vc_elm_s *)vc_elm; + int type = 0; + if (NULL == vc_elm) { + VC_ELM_LOG_ERR("Invalid vc_elm parameter detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + type = handler->type; + if (VC_ELM_TYPE_EVAS_OBJECT == type) { + Evas_Object *obj = (Evas_Object *)handler->data; + return _vc_elm_unset_object_hint(obj); + } else if (VC_ELM_TYPE_ITEM == type) { + Elm_Object_Item *it = (Elm_Object_Item *)handler->data; + return _vc_elm_unset_item_object_hint(it); + } + return VC_ELM_ERROR_INVALID_PARAMETER; +} + +int vc_elm_set_command_hint_direction(vc_elm_h vc_elm, vc_elm_direction_e direction) +{ + vc_elm_s *handler = (vc_elm_s *)vc_elm; + int type = 0; + if (NULL == vc_elm) { + VC_ELM_LOG_ERR("Invalid vc_elm parameter detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + type = handler->type; + if (VC_ELM_TYPE_EVAS_OBJECT == type) { + Evas_Object *obj = (Evas_Object *)handler->data; + return _vc_elm_set_object_hint_direction(obj, direction); + } else if (VC_ELM_TYPE_ITEM == type) { + Elm_Object_Item *it = (Elm_Object_Item *)handler->data; + Evas_Object *parent = elm_object_item_widget_get(it); + return _vc_elm_set_sub_item_hint_direction(parent, direction); + } + return VC_ELM_ERROR_INVALID_PARAMETER; +} + +int vc_elm_get_command_hint_direction(vc_elm_h vc_elm, vc_elm_direction_e *direction) +{ + vc_elm_s *handler = (vc_elm_s *)vc_elm; + int type = 0; + if (NULL == vc_elm) { + VC_ELM_LOG_ERR("Invalid vc_elm parameter detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + type = handler->type; + if (VC_ELM_TYPE_EVAS_OBJECT == type) { + Evas_Object *obj = (Evas_Object *)handler->data; + return _vc_elm_get_object_hint_direction(obj, direction); + } else if (VC_ELM_TYPE_ITEM == type) { + Elm_Object_Item *it = (Elm_Object_Item *)handler->data; + Evas_Object *parent = elm_object_item_widget_get(it); + return _vc_elm_get_sub_item_hint_direction(parent, direction); + } + return VC_ELM_ERROR_INVALID_PARAMETER; +} + +int vc_elm_set_command_hint_offset(vc_elm_h vc_elm, int pos_x, int pos_y) +{ + vc_elm_s *handler = (vc_elm_s *)vc_elm; + int type = 0; + if (NULL == vc_elm) { + VC_ELM_LOG_ERR("Invalid vc_elm parameter detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + type = handler->type; + if (VC_ELM_TYPE_EVAS_OBJECT == type) { + Evas_Object *obj = (Evas_Object *)handler->data; + return _vc_elm_set_object_custom_hint(obj, NULL, pos_x, pos_y); + } else if (VC_ELM_TYPE_ITEM == type) { + Elm_Object_Item *it = (Elm_Object_Item *)handler->data; + return _vc_elm_set_item_object_custom_hint(it, NULL, pos_x, pos_y); + } + return VC_ELM_ERROR_INVALID_PARAMETER; +} + +int vc_elm_get_command_hint_offset(vc_elm_h vc_elm, int *pos_x, int *pos_y) +{ + vc_elm_s *handler = (vc_elm_s *)vc_elm; + const char *path = NULL; + int type = 0; + if (NULL == vc_elm) { + VC_ELM_LOG_ERR("Invalid vc_elm parameter detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + if ((NULL == pos_x) || (NULL == pos_y)) { + VC_ELM_LOG_ERR("Invalid position poiters detected!"); + return VC_ELM_ERROR_INVALID_PARAMETER; + } + type = handler->type; + if (VC_ELM_TYPE_EVAS_OBJECT == type) { + Evas_Object *obj = (Evas_Object *)handler->data; + return _vc_elm_get_object_custom_hint(obj, &path, pos_x, pos_y); + } else if (VC_ELM_TYPE_ITEM == type) { + Elm_Object_Item *it = (Elm_Object_Item *)handler->data; + return _vc_elm_get_item_object_custom_hint(it, &path, pos_x, pos_y); + } + return VC_ELM_ERROR_INVALID_PARAMETER; +} + +int vc_elm_set_current_language_changed_cb(vc_elm_current_language_changed_cb callback, void *user_data) +{ + int ret = VC_ELM_ERROR_NONE; + + if (false == is_vc_elm_initialized) { + VC_ELM_LOG_ERR("Invalid state detected! Library not initialized!"); + return VC_ELM_ERROR_INVALID_STATE; + } + + ret = vc_elm_widget_wrapper_set_current_language_changed_callback(callback, user_data); + if (0 != ret) { + return VC_ELM_ERROR_OPERATION_FAILED; + } + return VC_ELM_ERROR_NONE; +} + +int vc_elm_unset_current_language_changed_cb() +{ + int ret = VC_ELM_ERROR_NONE; + + if (false == is_vc_elm_initialized) { + VC_ELM_LOG_ERR("Invalid state detected! Library not initialized!"); + return VC_ELM_ERROR_INVALID_STATE; + } + + ret = vc_elm_widget_wrapper_unset_current_language_changed_callback(); + if (0 != ret) { + return VC_ELM_ERROR_OPERATION_FAILED; + } + return VC_ELM_ERROR_NONE; +} + +int _vc_elm_set_object_command(Evas_Object *obj, const char *command) +{ + if (_vc_elm_core_set_object_command(obj, command)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_unset_object_command(Evas_Object *obj) +{ + if (_vc_elm_core_unset_object_command(obj)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_set_object_hint(Evas_Object *obj, const char *hint) +{ + if (_vc_elm_core_set_object_hint(obj, hint)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_unset_object_hint(Evas_Object *obj) +{ + if (_vc_elm_core_unset_object_hint(obj)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_set_object_custom_hint(Evas_Object *obj, const char *image_path, int pos_x, int pos_y) +{ + if (_vc_elm_core_set_object_custom_hint(obj, image_path, pos_x, pos_y)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_get_object_custom_hint(Evas_Object *obj, const char **image_path, int *pos_x, int *pos_y) +{ + if (_vc_elm_core_get_object_custom_hint(obj, image_path, pos_x, pos_y)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_set_item_object_custom_hint(Elm_Object_Item *obj, const char *image_path, int pos_x, int pos_y) +{ + if (_vc_elm_core_set_item_object_custom_hint(obj, image_path, pos_x, pos_y)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_get_item_object_custom_hint(Elm_Object_Item *obj, const char **image_path, int *pos_x, int *pos_y) +{ + if (_vc_elm_core_get_item_object_custom_hint(obj, image_path, pos_x, pos_y)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_set_item_object_command(Elm_Object_Item *obj, const char *command) +{ + if (_vc_elm_core_set_item_object_command(obj, command)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_unset_item_object_command(Elm_Object_Item *obj) +{ + if (_vc_elm_core_unset_item_object_command(obj)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_set_item_object_hint(Elm_Object_Item *obj, const char *hint) +{ + if (_vc_elm_core_set_item_object_hint(obj, hint)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_unset_item_object_hint(Elm_Object_Item *obj) +{ + if (_vc_elm_core_unset_item_object_hint(obj)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_enable_name_autogen_enable(Eina_Bool autogen) +{ + if (_vc_elm_core_enable_name_autogen(autogen)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +vc_elm_widget_info* +_vc_elm_register_widget(const char *widget_name, vc_elm_get_subobjects_cb get_subobjects_func, vc_elm_command_filter_cb is_feltered_func, void *user_data) +{ + return _vc_elm_core_register_widget(widget_name, get_subobjects_func, is_feltered_func, user_data); +} + +void _vc_elm_register_action(vc_elm_widget_info *info, const char *action_name, void *data, vc_elm_action_activator_cb func) +{ + _vc_elm_core_register_action(info, action_name, data, func); +} + +int _vc_elm_set_object_hint_direction(Evas_Object *obj, vc_elm_direction_e direction) +{ + if (_vc_elm_core_set_object_hint_direction(obj, direction)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_get_object_hint_direction(Evas_Object *obj, vc_elm_direction_e *direction) +{ + if (_vc_elm_core_get_object_hint_direction(obj, direction)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_set_sub_item_hint_direction(Evas_Object *obj, vc_elm_direction_e direction) +{ + if (_vc_elm_core_set_sub_item_hint_direction(obj, direction)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_get_sub_item_hint_direction(Evas_Object *obj, vc_elm_direction_e *direction) +{ + if (_vc_elm_core_get_sub_item_hint_direction(obj, direction)) + return VC_ELM_ERROR_NONE; + else + return VC_ELM_ERROR_OPERATION_FAILED; +} + +int _vc_elm_set_text_domain(const char *domain, const char *locale_dir) +{ + + if (NULL == domain) + return VC_ELM_ERROR_OPERATION_FAILED; + + if (NULL != g_app_domain) + free(g_app_domain); + + g_app_domain = strdup(domain); + bindtextdomain(g_app_domain, locale_dir); + + return VC_ELM_ERROR_NONE; +} + +int _vc_elm_get_text_domain(char **domain) +{ + if (NULL == g_app_domain) { + *domain = NULL; + return VC_ELM_ERROR_OPERATION_FAILED; + } + + *domain = strdup(g_app_domain); + return VC_ELM_ERROR_NONE; +} + +#ifdef SRPOL_DEBUG +/** + * @brief Wrapper for making internal function public - for automated test purposes + */ +void show_tooltip() +{ + _show_tooltips(); +} + +/** + * @brief Wrapper for making internal function public - for automated test purposes + */ +void hide_tooltip() +{ + _hide_tooltips(); +} +#endif diff --git a/src/vc_elm.h b/src/vc_elm.h new file mode 100644 index 0000000..586b7f5 --- /dev/null +++ b/src/vc_elm.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011-2014 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 __VC_ELM_H__ +#define __VC_ELM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include +/** + * @file vc_elm.h + * @brief This file contains voice-control-elm functions, that define the behaviour of library + */ + +int _vc_elm_set_object_command(Evas_Object *obj, const char *command); +int _vc_elm_unset_object_command(Evas_Object *obj); +int _vc_elm_set_object_hint(Evas_Object *obj, const char *hint); +int _vc_elm_unset_object_hint(Evas_Object *obj); +int _vc_elm_set_object_custom_hint(Evas_Object *obj, const char *image_path, int pos_x, int pos_y); +int _vc_elm_get_object_custom_hint(Evas_Object *obj, const char **image_path, int *pos_x, int *pos_y); +int _vc_elm_set_item_object_custom_hint(Elm_Object_Item *obj, const char *image_path, int pos_x, int pos_y); +int _vc_elm_get_item_object_custom_hint(Elm_Object_Item *obj, const char **image_path, int *pos_x, int *pos_y); +int _vc_elm_set_item_object_command(Elm_Object_Item *obj, const char *command); +int _vc_elm_unset_item_object_command(Elm_Object_Item *obj); +int _vc_elm_set_item_object_hint(Elm_Object_Item *obj, const char *hint); +int _vc_elm_unset_item_object_hint(Elm_Object_Item *obj); +int _vc_elm_set_object_hint_direction(Evas_Object *obj, vc_elm_direction_e direction); +int _vc_elm_get_object_hint_direction(Evas_Object *obj, vc_elm_direction_e *direction); +int _vc_elm_set_sub_item_hint_direction(Evas_Object *obj, vc_elm_direction_e direction); +int _vc_elm_get_sub_item_hint_direction(Evas_Object *obj, vc_elm_direction_e *direction); + +/** + * set text domain for multi-language support + */ +int _vc_elm_set_text_domain(const char *domain, const char *locale_dir); + +/** + * get text domain for multi-language support + */ +int _vc_elm_get_text_domain(char **domain); + + +#ifdef __cplusplus +} +#endif + +#endif/*__VC_ELM_H__*/ diff --git a/src/vc_elm_core.c b/src/vc_elm_core.c new file mode 100644 index 0000000..adfd5be --- /dev/null +++ b/src/vc_elm_core.c @@ -0,0 +1,1704 @@ +/* + * Copyright (c) 2011-2014 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 "vc_elm_main.h" +#include +#include +#include +#include +#include +#include + +#include "vc_elm.h" +#include "vc_elm_core.h" +#include "vc_elm_tools.h" +#include "vc_elm_widget_wrapper.h" +#include "vc_elm_tooltip.h" +#include "vc_elm_rectangle.h" + +#ifdef _ +#undef _ +#endif +#define _VC_ELM(S) dgettext("voice-control-elm", S) +#define _APP(S) dgettext(g_app_domain, S) + +#define XML_CAST (const xmlChar *) + +static char *g_app_domain = NULL; + +static Evas_Object *g_default_window = NULL; +static Eina_Hash *g_widget_info_hash = NULL; +static Eina_Hash *item_hint_map = NULL; +static Eina_Hash *item_command_map = NULL; +static Eina_Hash *item_custom_map = NULL; +static Eina_Hash *command_item_map = NULL; +static Eina_Hash *registered_item_map = NULL; +static Eina_List *g_wrapped_commands = NULL; +static Eina_List *ui_objects_list = NULL; +static Eina_List *g_current_ui_objects = NULL; +static Eina_Bool g_tooltips_displayed = EINA_FALSE; +static Eina_Bool g_hints_autogenerated = EINA_TRUE; + +static Eina_Hash *g_config_action_map = NULL; +static Eina_Hash *g_config_widget_map = NULL; + +static char *g_tooltips_image_path = NULL; +static char *g_tooltips_default_direction = NULL; +static char *g_tooltips_show = NULL; + +#define HIDE 0xa +#define X_VISIBILITY_TOLERANCE 32.0 +#define Y_VISIBILITY_TOLERANCE 54.0 + +const Eina_Hash *_vc_elm_core_get_config_action_map() { + return g_config_action_map; +} + +const Eina_Hash *_vc_elm_core_get_config_widget_map() { + return g_config_widget_map; +} + +/** + * @brief Structure that wrapps a command with corresponding widget and it's parent + */ +struct Wrapped_Command { + const char *cmd; + void *data; + Evas_Object *obj; + Elm_Object_Item *parent_item; + void (*unwrap_callback)(struct Wrapped_Command *wrapper, const char *action, const char *param); +}; + +/** + * @brief Structure that wrapps a wrapped command with it's command and param + */ +struct Unwrapped_Command { + struct Wrapped_Command *wrap; + char *action; + char *param; +}; + +/** + * @brief Structure defines a custom tooltip + */ +struct Custom_Data { + const char *image_path; + int pos_x; + int pos_y; +}; + +/* functions private to vc_elm_core module */ + +/** + * @brief Function that is called repeatedly to free widget info hashmap elements + * @param[in] element to deallocate + */ +static void __widget_info_free_cb(void *entry); + +/** + * @brief Function that is called repeatedly to free widget info hashmap elements + * @param[in] element to deallocate + */ +static void __hash_entry_dummy_cb(void *entry); + +/** + * @brief Function that is called repeatedly to free object's hashmap elements + * @param[in] element to deallocate + */ +static void __hash_entry_free_cb(void *entry); + +/** + * @brief Function that recursively traverses the widget tree and finds visible + * widgets that can have widgets and commands + * @param[in] current widget to handle + * @param[in] callback to handle traversing the current widget + * @param[in] current list of found widgets + */ +static void __elm_widget_foreach_in_tree(Evas_Object *widget, Eina_Bool (*cb)(Evas_Object *widget, Eina_List **data), Eina_List **data); + +/** + * @brief Function that recursively traverses the widget tree and finds visible + * widgets that can have widgets and commands. This handle special cases + * of some widgets that have subwidgets + * @param[in] current widget to handle + * @param[in] current list of found widgets + */ +static Eina_Bool __elm_widget_foreach_to_list_add(Evas_Object *widget, Eina_List **list); + +/** + * @brief Function that commits the gathered commands + */ +static void __vc_add_commands(); + +/** + * @brief Callback that handles recognition output + * @param[in] recognized command + * @param[in] recognized first param + * @param[in] recognized second param (unused) + * @param[in] extra data to be passed to function + */ +static int __result_cb(const char *cmd, const char *param1, const char *param2, void *user_data); +/** + * @brief Function to handle command activation - also handles special cases + * when visibility checks need to be performed; possibly scrolling or + * bringing in activated invisible widgets + * @param[in] command structure to be activated + * @param[in] recognized action + * @param[in] recognized param + */ +static void __unwrap_universal_item_command(struct Wrapped_Command *wrapper, const char *action, const char *param); + +/** + * @brief Callback that shows or hides tooltips + * @param[in] whether to hide or show the tooltips + */ +static void __show_or_hide_tooltips_callback(bool show_or_hide); + +/** + * @brief Callback that relayouts the tooltips in case of screen rotation + * @param[in] data to pass to callback (unused) + * @param[in] Evas_Object to pass to callback (unused) + * @param[in] callback's data to pass (unused) + */ +static void __rotation(void *data, Evas_Object *obj, void *event_info); + +static int __is_hidden_widget(Evas_Object *obj); + + +/** + * @brief Function that returns the name of the widget + * @param[in] handle to widget's Evas_Object structure + */ +const char *_get_ui_object_name(const Evas_Object *obj) +{ + const char *ret = evas_object_data_get(obj, _vc_elm_get_custom_widget_name()); + if (!ret) + ret = elm_widget_type_get(obj); + if (!ret) + ret = evas_object_name_get(obj); + ret = eina_stringshare_add(ret); + return ret; +} + +/** + * @brief Function that matches recognition result to the registered actions + * and calls for action execution + * @param[in] recognized command + * @param[in] recognized action + * @param[in] recognized param + */ +Eina_Bool _recognize_command(const char *cmd, const char *param1, const char *param2) +{ + const Eina_List *l; + struct Wrapped_Command *wrapped; + struct Wrapped_Command *found = NULL; + VC_ELM_LOG_INFO("Trying to recognize %s %s %s", cmd, param1, param2); + + EINA_LIST_FOREACH(g_wrapped_commands, l, wrapped) { + VC_ELM_LOG_DBG("compare %s %s", wrapped->cmd, cmd); + if (cmd && (0 == strcmp(wrapped->cmd, cmd))) { + VC_ELM_LOG_DBG("found action"); + found = wrapped; + break; + } + } + if (found) { + char *tmp_cmd = strdup(cmd); + char *command = strtok(tmp_cmd, " "); + char *param = strtok(NULL, "'"); + found->cmd = command; + + VC_ELM_LOG_DBG("unwrapping %s %s for %s", param1, param2, _get_ui_object_name(found->obj)); + found->unwrap_callback(found, param, param2); + + if (NULL != tmp_cmd) + free(tmp_cmd); + + return EINA_TRUE; + } + + return EINA_FALSE; +} + +/* implementation */ +static void __hash_entry_dummy_cb(void *entry) +{ + (void)entry; +} + +static void __hash_entry_free_cb(void *entry) +{ + free(entry); +} + +static void __hash_entry_stringshare_free_cb(void *entry) +{ + eina_stringshare_del(entry); +} + +static void __hash_entry_eina_list_free_cb(void *entry) +{ + Eina_List *list = (Eina_List *)entry; + Eina_List *l; + void *data; + + EINA_LIST_FOREACH(list, l, data) { + eina_stringshare_del(data); + list = eina_list_remove_list(list, l); + } +} + +static void __widget_info_free_cb(void *entry) +{ + struct vc_elm_core_widget_info *info = entry; + unsigned int idx; + for (idx = 0; idx < info->actions_count; ++idx) + eina_stringshare_del(info->actions[idx].name); + free(info); +} + +/** + * @brief Function that starts the widgets tree traversal + * @param[in] extra data to be passed + */ +static Eina_Bool __idle_enter(void *data); + +/** + * @brief Function that set's the internal window handlers of current app. + * @param[in] extra data to be passed + */ +/*static Eina_Bool _delayed_window_load(void *data);*/ + +void _vc_elm_core_init() +{ + int ret; + bindtextdomain("voice-control-elm", "/usr/share/locale/"); + + g_widget_info_hash = eina_hash_string_djb2_new(__widget_info_free_cb); + item_hint_map = eina_hash_pointer_new(__hash_entry_free_cb); + item_command_map = eina_hash_pointer_new(__hash_entry_free_cb); + item_custom_map = eina_hash_pointer_new(__hash_entry_free_cb); + command_item_map = eina_hash_string_superfast_new(__hash_entry_free_cb); + registered_item_map = eina_hash_string_superfast_new(__hash_entry_free_cb); + + g_config_action_map = eina_hash_string_superfast_new(__hash_entry_stringshare_free_cb); + g_config_widget_map = eina_hash_string_superfast_new(__hash_entry_eina_list_free_cb); + + ret = _vc_elm_core_read_xml_data(); + VC_ELM_LOG_DBG("XML RETURNED %d", ret); +} + +void _vc_elm_core_fini() +{ + eina_hash_free(g_widget_info_hash); + g_widget_info_hash = NULL; + + eina_hash_free_buckets(registered_item_map); + eina_hash_free(registered_item_map); + registered_item_map = NULL; + + eina_hash_free(g_config_action_map); + g_config_action_map = NULL; + eina_hash_free(g_config_widget_map); + g_config_widget_map = NULL; + _vc_elm_core_destroy_xml_data(); + +#ifndef SRPOL_DEBUG + _vc_elm_widget_wrapper_deinitialize(); +#endif +} + +void _vc_elm_core_load() +{ +#ifndef SRPOL_DEBUG + _vc_elm_widget_wrapper_set_show_tooltips_callback(__show_or_hide_tooltips_callback); + _vc_elm_widget_wrapper_initialize(); +#endif +} + +unsigned int _vc_elm_core_get_window() +{ + return (unsigned int)elm_win_xwindow_get(g_default_window); +} + +Evas_Object *_vc_elm_core_get_evas_object(Elm_Object_Item *item) +{ + Elm_Widget_Item_Data *ret; + ret = eo_data_scope_get(item, ELM_WIDGET_ITEM_CLASS); + if (NULL != ret) + return (Evas_Object *)(ret->view); + else + return NULL; +} + +static Eina_List *__get_objects_of_visible_items(Evas_Object *parent, Elm_Object_Item *(*get_first)(const Evas_Object *obj), Elm_Object_Item *(*get_next)(const Elm_Object_Item *item)) +{ + Eina_List *ret = NULL; + Elm_Object_Item *item = get_first(parent); + int x; + int y; + int w; + int h; + const char *item_hint = NULL; + const char *item_command = NULL; + struct Custom_Data *item_custom_date = NULL; + + if (item == NULL) + return ret; + + evas_object_geometry_get(parent, &x, &y, &w, &h); + do { + int x_1; + int y_1; + int w_1; + int h_1; + Evas_Object *obj; + const char *name; + + obj = _vc_elm_core_get_evas_object(item); + if (!obj) + continue; + + item_hint = eina_hash_find(item_hint_map, &item); + item_command = eina_hash_find(item_command_map, &item); + + if (item_command != NULL) { + if (item_hint != NULL) + evas_object_data_set(obj, VC_ELM_HINT_DATA_KEY, item_hint); + evas_object_data_set(obj, VC_ELM_CMD_DATA_KEY, item_command); + } + + item_custom_date = eina_hash_find(item_custom_map, &item); + + if (item_custom_date != NULL) { + evas_object_data_set(obj, _vc_elm_get_data_key(VC_ELM_HINT_IMAGE_PATH), (const void *)item_custom_date->image_path); + evas_object_data_set(obj, _vc_elm_get_data_key(VC_ELM_POSITION_X), (void *)item_custom_date->pos_x); + evas_object_data_set(obj, _vc_elm_get_data_key(VC_ELM_POSITION_Y), (void *)item_custom_date->pos_y); + } + + evas_object_geometry_get(obj, &x_1, &y_1, &w_1, &h_1); + name = elm_widget_type_get(obj); + if (NULL != name && NULL == eina_hash_find(registered_item_map, name) && NULL != eina_hash_find(g_config_widget_map, name)) { + Eina_List *list2 = eina_hash_find(g_config_widget_map, name); + VC_ELM_LOG_DBG("CORE LIST action size %u", eina_list_count(list2)); + _vc_elm_core_register_default_widget(name, EINA_TRUE, eina_hash_find(g_config_widget_map, name)); + eina_hash_add(registered_item_map, name, strdup("1")); + } + VC_ELM_LOG_DBG("have a visible item %d %d %d %d", x_1, y_1, w_1, h_1); + if (NULL == name) + evas_object_data_set(obj, "special_item", item); + ret = eina_list_append(ret, obj); + } while ((item = get_next(item)) != NULL); + + return ret; +} + +static Eina_Bool __item_item_map_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata) +{ + Evas_Object *eo = NULL; + const char *item_hint = NULL; + struct Custom_Data *item_custom_date = NULL; + R parent_dim; + R item_dim; + R out_dim; + (void)hash; + + eo = _vc_elm_core_get_evas_object(data); + if (NULL == eo) + return EINA_TRUE; + item_hint = eina_hash_find(item_hint_map, &data); + eo = evas_object_smart_parent_get(evas_object_smart_parent_get(eo)); + if (NULL == eo) + return EINA_TRUE; + _R_set_from_efl(&parent_dim, evas_object_smart_parent_get(evas_object_smart_parent_get(evas_object_smart_parent_get(eo)))); + _R_set_from_efl(&item_dim, fdata); + + if (eo == fdata) { + if (_R_intersection(&item_dim, &parent_dim, &out_dim) && (evas_object_visible_get(elm_widget_parent_widget_get(eo)))) { + evas_object_data_set(fdata, VC_ELM_CMD_DATA_KEY, key); + if (item_hint != NULL) + evas_object_data_set(fdata, VC_ELM_HINT_DATA_KEY, item_hint); + item_custom_date = eina_hash_find(item_custom_map, &data); + + if (item_custom_date != NULL) { + evas_object_data_set(fdata, _vc_elm_get_data_key(VC_ELM_HINT_IMAGE_PATH), (const void *)item_custom_date->image_path); + evas_object_data_set(fdata, _vc_elm_get_data_key(VC_ELM_POSITION_X), (void *)item_custom_date->pos_x); + evas_object_data_set(fdata, _vc_elm_get_data_key(VC_ELM_POSITION_Y), (void *)item_custom_date->pos_y); + } + } else { + evas_object_data_del(fdata, VC_ELM_CMD_DATA_KEY); + evas_object_data_del(fdata, VC_ELM_HINT_DATA_KEY); + } + return EINA_FALSE; + } + return EINA_TRUE; +} + +static void __remove_ctxpopup(void *data, Evas *e, Evas_Object *obj, void *event_info) { + Eina_List *constant_list = NULL; + const Eina_List *tmp_list = NULL; + + (void)data; + (void)e; + (void)event_info; + constant_list = elm_widget_can_focus_child_list_get(eina_list_data_get(elm_widget_can_focus_child_list_get(obj))); + tmp_list = constant_list; + do { + Evas_Object *ee = eina_list_data_get(tmp_list); + eina_hash_foreach(command_item_map, __item_item_map_foreach, ee); + evas_object_data_del(ee, VC_ELM_CMD_DATA_KEY); + evas_object_data_del(ee, VC_ELM_HINT_DATA_KEY); + } while ((tmp_list = eina_list_next(tmp_list)) != NULL); +} + +static Eina_List *__get_ctxpopup_objects_of_visible_items(Evas_Object *widget) +{ + Eina_List *constant_list = NULL; + Eina_List *ret = NULL; + const Eina_List *tmp_list = NULL; + constant_list = elm_widget_can_focus_child_list_get(eina_list_data_get(elm_widget_can_focus_child_list_get(widget))); + evas_object_event_callback_add(widget, EVAS_CALLBACK_HIDE, __remove_ctxpopup, widget); + + VC_ELM_LOG_DBG("NUMBERS OF WIDGETS IN CTXPOPUP %d", eina_list_count(constant_list)); + tmp_list = constant_list; + do { + Evas_Object *ee = eina_list_data_get(tmp_list); + eina_hash_foreach(command_item_map, __item_item_map_foreach, ee); + if (evas_object_data_get(ee, VC_ELM_CMD_DATA_KEY) || evas_object_data_get(ee, VC_ELM_HINT_DATA_KEY)) + ret = eina_list_append(ret, (void *)ee); + } while ((tmp_list = eina_list_next(tmp_list)) != NULL); + + return ret; +} + +Elm_Object_Item *_vc_elm_core_get_visible_item(Evas_Object *parent, Elm_Object_Item *(*get_first)(const Evas_Object *obj, void *user_data), Elm_Object_Item *(*get_next)(const Elm_Object_Item *item, void *user_data), void *user_data) +{ + Elm_Object_Item *ret = NULL; + void *usr_d = user_data; + Elm_Object_Item *item = get_first(parent, usr_d); + int x; + int y; + int w; + int h; + + if (item == NULL) + return ret; + + evas_object_geometry_get(parent, &x, &y, &w, &h); + do { + int x_1; + int y_1; + int w_1; + int h_1; + Evas_Object *obj; + + obj = _vc_elm_core_get_evas_object(item); + if (!obj) + continue; + evas_object_geometry_get(obj, &x_1, &y_1, &w_1, &h_1); + if (x_1 >= x && y_1 >= y && (x_1 + w_1) <= (x + w) && (y_1 + h_1) <= (y + h)) { + VC_ELM_LOG_DBG("detected visible item"); + ret = item; + return ret; + } + } while ((item = get_next(item, usr_d)) != NULL); + + return ret; +} + +static void __elm_widget_foreach_in_tree(Evas_Object *widget, Eina_Bool (*cb)(Evas_Object *widget, Eina_List **data), Eina_List **data) +{ + Eina_Bool visible = evas_object_visible_get(widget); + + VC_ELM_LOG_DBG("IS visible %s %d", _get_ui_object_name(widget), visible); + if (visible) { + Eina_List *list = NULL; + const Eina_List *constant_list = NULL; + const Eina_List *l = NULL; + Evas_Object *obj = NULL; + const char *obj_name = NULL; + struct vc_elm_core_widget_info *info = NULL; + + obj_name = _get_ui_object_name(widget); + if (NULL == eina_hash_find(registered_item_map, obj_name) && NULL != eina_hash_find(g_config_widget_map, obj_name)) { + Eina_List *list2 = eina_hash_find(g_config_widget_map, obj_name); + VC_ELM_LOG_DBG("CORE LIST action size %u", eina_list_count(list2)); + _vc_elm_core_register_default_widget(obj_name, EINA_TRUE, eina_hash_find(g_config_widget_map, obj_name)); + if (NULL != obj_name) + eina_hash_add(registered_item_map, obj_name, strdup("1")); + } + VC_ELM_LOG_DBG("cb %s (%p)", obj_name, (void*)widget); + + cb(widget, data); + + if (NULL != (info = eina_hash_find(g_widget_info_hash, obj_name)) && obj_name != NULL && NULL != info->get_subobjects_func) { + constant_list = info->get_subobjects_func(widget, info->user_data); + } else if (obj_name != NULL && (!strcmp("Elm_Button", obj_name) || !strcmp("Elm_Index", obj_name))) { + /* We dont want to have a tooltip for elm_icon on button */ + /* We dont want to have tooltips for elm_index items */ + return; + } else if (obj_name != NULL && !strcmp("Elm_List", obj_name)) { + VC_ELM_LOG_DBG(":: %s", obj_name); + if (NULL == eina_hash_find(registered_item_map, "elm_item") && NULL != eina_hash_find(g_config_widget_map, "Elm_List")) { + _vc_elm_core_register_default_widget("elm_item", EINA_TRUE, NULL); + eina_hash_add(registered_item_map, "elm_item", strdup("1")); + } + constant_list = __get_objects_of_visible_items(widget, &elm_list_first_item_get, &elm_list_item_next); + } else if (obj_name != NULL && !strcmp("Elm_Ctxpopup", obj_name)) { + VC_ELM_LOG_DBG(":: %s", obj_name); + if (NULL == eina_hash_find(registered_item_map, "elm_item") && NULL != eina_hash_find(g_config_widget_map, "Elm_Ctxpopup")) { + _vc_elm_core_register_default_widget("elm_item", EINA_TRUE, NULL); + eina_hash_add(registered_item_map, "elm_item", strdup("1")); + } + constant_list = __get_ctxpopup_objects_of_visible_items(widget); + _vc_elm_core_set_object_hint(widget, _VC_ELM("IDS_CANCEL")); + + } else if (obj_name != NULL && !strcmp("Elm_Genlist", obj_name)) { + VC_ELM_LOG_DBG(":: %s", obj_name); + if (NULL == eina_hash_find(registered_item_map, "elm_item") && NULL != eina_hash_find(g_config_widget_map, "Elm_Genlist")) { + _vc_elm_core_register_default_widget("elm_item", EINA_TRUE, NULL); + eina_hash_add(registered_item_map, "elm_item", strdup("1")); + } + list = __get_objects_of_visible_items(widget, &elm_genlist_first_item_get, &elm_genlist_item_next_get); + constant_list = elm_widget_can_focus_child_list_get(widget); + EINA_LIST_FOREACH (constant_list, l, obj) { + if (NULL == eina_list_data_find(list, obj)) + list = eina_list_append(list, obj); + } + } else if (obj_name != NULL && !strcmp("Elm_Gengrid", obj_name)) { + VC_ELM_LOG_DBG(":: %s", obj_name); + if (NULL == eina_hash_find(registered_item_map, "elm_item") && NULL != eina_hash_find(g_config_widget_map, "Elm_Gengrid")) { + _vc_elm_core_register_default_widget("elm_item", EINA_TRUE, NULL); + eina_hash_add(registered_item_map, "elm_item", strdup("1")); + } + list = __get_objects_of_visible_items(widget, &elm_gengrid_first_item_get, &elm_gengrid_item_next_get); + constant_list = elm_widget_can_focus_child_list_get(widget); + EINA_LIST_FOREACH (constant_list, l, obj) { + if (NULL == eina_list_data_find(list, obj)) + list = eina_list_append(list, obj); + } + } else if (obj_name != NULL && !strcmp("Elm_Toolbar", obj_name)) { + VC_ELM_LOG_DBG(":: %s", obj_name); + if (NULL == eina_hash_find(registered_item_map, "elm_item") && NULL != eina_hash_find(g_config_widget_map, "Elm_Toolbar")) { + _vc_elm_core_register_default_widget("elm_item", EINA_TRUE, NULL); + eina_hash_add(registered_item_map, "elm_item", strdup("1")); + } + list = __get_objects_of_visible_items(widget, &elm_toolbar_first_item_get, &elm_toolbar_item_next_get); + } else if (obj_name != NULL && !strcmp("Elm_Naviframe", obj_name)) { + VC_ELM_LOG_DBG(":: %s", obj_name); + list = eina_list_append(list, _vc_elm_core_get_evas_object(elm_naviframe_top_item_get(widget))); + } else { + constant_list = elm_widget_can_focus_child_list_get(widget); + } + + if (list) + constant_list = list; + + EINA_LIST_FOREACH(constant_list, l, obj) { + const char *current_name = _get_ui_object_name(obj); + + VC_ELM_LOG_DBG("calling %p %s", (void*)obj, current_name); + + if ((current_name != NULL) && ((0 == strcmp(current_name, "Elm_Inwin")) || (0 == strcmp(current_name, "Elm_Popup")) || ((0 == strcmp(current_name, "Elm_Ctxpopup") && (evas_object_visible_get(obj)))))) { + /*overlaying widget found, remove other widgets found, + traverse it's subtree and return*/ + VC_ELM_LOG_INFO("overlaying widget: found"); + + if (data && (*data)) { + eina_list_free(*data); + *data = NULL; + } + + __elm_widget_foreach_in_tree(obj, cb, data); + + VC_ELM_LOG_INFO("overlaying widget: subtree finished"); + return; + } else { + /*continue traversing other subtrees*/ + __elm_widget_foreach_in_tree(obj, cb, data); + } + } + if (list) + eina_list_free(list); + } else { + VC_ELM_LOG_DBG("not visible"); + } +} + +static int __is_hiding_widget(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) +{ + Evas_Object *above_obj; + Evas_Coord my_x; + Evas_Coord my_y; + Evas_Coord my_w; + Evas_Coord my_h; + + above_obj = evas_object_above_get(obj); + if ((above_obj == NULL) || (obj == above_obj)) + return 0; + + evas_object_geometry_get(above_obj, &my_x, &my_y, &my_w, &my_h); + + if (strstr(evas_object_type_get(above_obj), "Elm") && !strstr(evas_object_type_get(above_obj), "Elm_Win") && evas_object_visible_get(above_obj) && ((my_x >= 0) && (my_y >= 0) && (my_w > 0) && (my_h > 0))) { + if ((my_x <= x) && (my_y <= y) && ((my_x + my_w) >= (x + w)) && ((my_y + my_h) >= (y + h))) + return 1; + } + + return __is_hiding_widget(above_obj, x, y, w, h); +} + +static int __is_hidden_widget(Evas_Object *obj) +{ + Evas_Coord x; + Evas_Coord y; + Evas_Coord w; + Evas_Coord h; + + if (obj) { + evas_object_geometry_get(obj, &x, &y, &w, &h); + return __is_hiding_widget(obj, x, y, w, h); + } else { + return 0; + } +} + +static Eina_Bool __elm_widget_foreach_to_list_add(Evas_Object *widget, Eina_List **list) +{ + const char *obj_name = _get_ui_object_name(widget); + Evas_Object *parent_obj = elm_object_parent_widget_get(widget); + const char *parent_obj_name = _get_ui_object_name(parent_obj); + Evas_Object *parents_parent_obj = elm_object_parent_widget_get(parent_obj); + const char *parents_parent_obj_name = _get_ui_object_name(parents_parent_obj); + + assert(list); + + obj_name = eina_stringshare_add(obj_name); + parent_obj_name = eina_stringshare_add(parent_obj_name); + parents_parent_obj_name = eina_stringshare_add(parents_parent_obj_name); + VC_ELM_LOG_DBG("Widget: %s, parent: %s", obj_name, parent_obj_name); + + if (obj_name) { + if ((!strcmp("Elm_Inwin", obj_name)) || (!strcmp("Elm_Popup", obj_name)) || (!strcmp("Elm_Ctxpopup", obj_name))) { + if (list && (*list)) { + eina_list_free(*list); + *list = NULL; + } + } else if ((!strcmp("Elm_Icon", obj_name))) { + if ((NULL != parent_obj_name && !strcmp(parent_obj_name, "Elm_Genlist")) && (NULL != parents_parent_obj_name && !strcmp(parents_parent_obj_name, "Elm_Fileselector"))) + return EINA_FALSE; + } else if ((!strcmp("Elm_Entry", obj_name))) { + if (NULL != parent_obj && NULL != parent_obj_name && !strcmp(parent_obj_name, "Elm_Fileselector")) { + return EINA_FALSE; + } + } + } + + if (__is_hidden_widget(widget)) + return EINA_TRUE; + + *list = eina_list_append(*list, widget); + return EINA_TRUE; +} + +Eina_List *_vc_elm_core_find_all_visible_objects() +{ + Eina_List *ret = NULL; + assert(!!g_default_window); + if (!g_default_window) + return NULL; + __elm_widget_foreach_in_tree(g_default_window, __elm_widget_foreach_to_list_add, &ret); + return ret; +} + +/** + * @brief Internal function that starts page analysis and tooltip showing + */ +#ifndef SRPOL_DEBUG +static +#endif +void _show_tooltips() +{ + Eina_List *_l; + Evas_Object *obj = NULL; + Evas_Object *parent = NULL; + struct vc_elm_core_widget_info *info = NULL; + const char *obj_name = NULL; + const char *parent_obj_name = NULL; + Evas_Coord x; + Evas_Coord y; + Evas_Coord w; + Evas_Coord h; + Evas_Coord x_p; + Evas_Coord y_p; + Evas_Coord w_p; + Evas_Coord h_p; + + __idle_enter(NULL); + + VC_ELM_LOG_DBG("show_tooltips"); + EINA_LIST_FOREACH (g_current_ui_objects, _l, obj) { + parent = elm_object_parent_widget_get(obj); + info = NULL; + obj_name = _get_ui_object_name(obj); + parent_obj_name = _get_ui_object_name(parent); + + if (!obj_name && evas_object_data_get(obj, "special_item")) + obj_name = eina_stringshare_add("evc-item"); + + if (!obj_name) { + VC_ELM_LOG_DBG("[TOOLTIP] Widget name is null"); + continue; + } else if (!strcmp(obj_name, "evc-item")) { + parent = elm_object_parent_widget_get(obj); + parent_obj_name = _get_ui_object_name(parent); + + while ((NULL != parent) && (NULL != parent_obj_name) && (0 != strcmp(parent_obj_name, "Elm_Genlist") && 0 != strcmp(parent_obj_name, "Elm_List") && 0 != strcmp(parent_obj_name, "Elm_Gengrid") && 0 != strcmp(parent_obj_name, "Elm_Ctxpopup") && 0 != strcmp(parent_obj_name, "Elm_Toolbar"))) { + parent = elm_object_parent_widget_get(parent); + + if (NULL != parent) + parent_obj_name = _get_ui_object_name(parent); + } + + if (NULL == parent) + continue; + + parent_obj_name = _get_ui_object_name(parent); + + if ((NULL != parent_obj_name) && (0 == strcmp(parent_obj_name, "Elm_Genlist") || 0 == strcmp(parent_obj_name, "Elm_List") || 0 == strcmp(parent_obj_name, "Elm_Gengrid") || 0 == strcmp(parent_obj_name, "Elm_Toolbar"))) { + evas_object_geometry_get(obj, &x, &y, &w, &h); + evas_object_geometry_get(parent, &x_p, &y_p, &w_p, &h_p); + + if ((y < y_p - Y_VISIBILITY_TOLERANCE) || (y + h > y_p + h_p + Y_VISIBILITY_TOLERANCE) || (x < x_p - X_VISIBILITY_TOLERANCE) || (x + w > y_p + w_p + X_VISIBILITY_TOLERANCE)) + continue; + } + } else if (NULL == (info = eina_hash_find(g_widget_info_hash, obj_name))) { + VC_ELM_LOG_DBG("[TOOLTIP] Widget type '%s' not supported", obj_name); + continue; + } else if (!strcmp(obj_name, "Elm_Naviframe")) { + VC_ELM_LOG_DBG("[TOOLTIP] No tooltip for %s", obj_name); + continue; + } else if ((NULL != parent_obj_name) && (0 == strcmp(parent_obj_name, "Elm_Genlist") || 0 == strcmp(parent_obj_name, "Elm_List") || 0 == strcmp(parent_obj_name, "Elm_Gengrid") || 0 == strcmp(parent_obj_name, "Elm_Toolbar"))) { + evas_object_geometry_get(obj, &x, &y, &w, &h); + evas_object_geometry_get(parent, &x_p, &y_p, &w_p, &h_p); + + if ((y < y_p - Y_VISIBILITY_TOLERANCE) || (y + h > y_p + h_p + Y_VISIBILITY_TOLERANCE) || (x < x_p - X_VISIBILITY_TOLERANCE) || (x + w > y_p + w_p + X_VISIBILITY_TOLERANCE)) + continue; + } else { + parent = elm_object_parent_widget_get(obj); + + if (NULL == parent) + continue; + + parent_obj_name = _get_ui_object_name(parent); + + evas_object_geometry_get(obj, &x, &y, &w, &h); + evas_object_geometry_get(parent, &x_p, &y_p, &w_p, &h_p); + + VC_ELM_LOG_DBG("item %d %d %d %d %s %d %d %d %d", x, y, w, h, parent_obj_name, x_p, y_p, w_p, h_p); + + if (!((y + Y_VISIBILITY_TOLERANCE > y_p) || (y_p + h_p + Y_VISIBILITY_TOLERANCE > y + h) || (x + X_VISIBILITY_TOLERANCE > x_p) || (y_p + w_p + X_VISIBILITY_TOLERANCE > x + w))) + continue; + } + + VC_ELM_LOG_DBG("[TOOLTIP] the tooltip for %s", obj_name); + _vc_elm_tooltips_show_tooltip(obj, evas_object_data_get(obj, VC_ELM_HINT_DATA_KEY)); + } + + _vc_elm_relayout_and_show_tooltips(); +} + +struct vc_elm_core_widget_info *_vc_elm_core_register_widget(const char *widget_name, vc_elm_get_subobjects_cb get_subobjects_func, vc_elm_command_filter_cb is_filtered_func, void *user_data) +{ + struct vc_elm_core_widget_info *info = NULL; + void *found = eina_hash_find(g_widget_info_hash, widget_name); + if (found) { + VC_ELM_LOG_ERR("Widget already registered: %s", widget_name); + } else { + info = malloc(sizeof(struct vc_elm_core_widget_info)); + if (info != NULL) { + memset(info, 0, sizeof(*info)); + info->name = eina_stringshare_add(widget_name); + info->get_subobjects_func = get_subobjects_func; + info->is_filtered_func = is_filtered_func; + info->actions = NULL; + info->actions_count = 0; + info->user_data = user_data; + if (eina_hash_add(g_widget_info_hash, info->name, info)) + VC_ELM_LOG_INFO("Registered widget: %s", widget_name); + else + VC_ELM_LOG_ERR("Failed to register widget: %s", widget_name); + } + } + return info; +} + +void _vc_elm_core_register_action(struct vc_elm_core_widget_info *info, const char *action_name, void *data, vc_elm_action_activator_cb action_activator_func) +{ + unsigned int idx = 0; + if (!info) { + VC_ELM_LOG_ERR("widget handle required"); + return; + } + + idx = info->actions_count; + info->actions_count++; + + info->actions = realloc(info->actions, sizeof(struct vc_elm_core_action_info) * info->actions_count); + if (info->actions != NULL) { + info->actions[idx].name = eina_stringshare_add(action_name); + info->actions[idx].data = data; + info->actions[idx].action_activator_func = action_activator_func; + + VC_ELM_LOG_DBG("Registered widget in VC_ELM (%s, %s)", info->name, action_name); + } +} + +static void __vc_add_commands() +{ + Eina_List *_l; + Evas_Object *obj; + size_t idx; + unsigned int registered; + Elm_Object_Item *item = NULL; + Evas_Object *parent; + Evas_Coord x; + Evas_Coord y; + Evas_Coord w; + Evas_Coord h; + Evas_Coord x_p; + Evas_Coord y_p; + Evas_Coord w_p; + Evas_Coord h_p; + + _vc_elm_get_text_domain(&g_app_domain); + VC_ELM_LOG_DBG("app domain - %s", g_app_domain); + { + const Eina_List *l; + struct Wrapped_Command *wrapped; + EINA_LIST_FOREACH(g_wrapped_commands, l, wrapped) { + free(wrapped); + } + eina_list_free(g_wrapped_commands); + g_wrapped_commands = NULL; + } + + EINA_LIST_FOREACH (g_current_ui_objects, _l, obj) { + struct vc_elm_core_widget_info *info = NULL; + const char *obj_name = _get_ui_object_name(obj); + char *command = NULL; + char *comm = NULL; + int ret; + obj_name = eina_stringshare_add(obj_name); + registered = 0; + if (obj_name) + VC_ELM_LOG_DBG("Adding command for %s", obj_name); + if (!obj_name && evas_object_data_get(obj, "special_item")) + obj_name = eina_stringshare_add("evc-item"); + if (!obj_name) { + VC_ELM_LOG_DBG("Widget '%p' has no type specified", obj_name); + continue; + } + if (NULL == (info = eina_hash_find(g_widget_info_hash, obj_name))) { + VC_ELM_LOG_DBG("Widget type '%s' not supported", obj_name); + continue; + } + + command = evas_object_data_get(obj, VC_ELM_CMD_DATA_KEY); + if (!command) + continue; + + for (idx = 0; idx < info->actions_count; ++idx) { + struct vc_elm_core_action_info *action = info->actions + idx; + if ((info->is_filtered_func) && (info->is_filtered_func(obj, _VC_ELM(action->name), info->user_data))) { + VC_ELM_LOG_DBG("Filtered command [%s, %s, %s]", obj_name, command, action->name); + continue; + } + VC_ELM_LOG_DBG("Creating command [%s, %s, %s]", obj_name, command, action->name); + + parent = elm_object_parent_widget_get(obj); + + if (parent != NULL) { + if (0 == strcmp(_get_ui_object_name(parent), "Elm_Genlist")) { + item = elm_genlist_first_item_get(parent); + + do { + evas_object_geometry_get(obj, &x, &y, &w, &h); + evas_object_geometry_get(_vc_elm_core_get_evas_object(item), &x_p, &y_p, &w_p, &h_p); + + if ((x_p + w_p >= x + w) && (y_p + h_p >= y + h) && (y_p <= y)) + break; + } while ((item = elm_genlist_item_next_get(item)) != NULL); + } + } + + comm = NULL; + if (_VC_ELM(action->name) == NULL || !strcmp(_VC_ELM(action->name), "")) + ret = asprintf(&comm, "%s", _APP(command)); + else + ret = asprintf(&comm, "%s %s", _APP(command), _VC_ELM(action->name)); + + if (-1 == ret) { + VC_ELM_LOG_ERR("Error translating command: %s", command); + continue; + } + + _vc_elm_widget_wrapper_add_command(comm, NULL); + + { + struct Wrapped_Command *cmd = NULL; + cmd = malloc(sizeof(struct Wrapped_Command)); + if (cmd != NULL) { + memset(cmd, 0, sizeof(*cmd)); + cmd->cmd = eina_stringshare_add(comm); + cmd->obj = obj; + cmd->data = info; + cmd->unwrap_callback = &__unwrap_universal_item_command; + cmd->parent_item = item; + g_wrapped_commands = eina_list_append(g_wrapped_commands, cmd); + } + } + + if (NULL != comm) + free(comm); + ++registered; + } + + if (registered == 0) + evas_object_data_del(obj, VC_ELM_HINT_DATA_KEY); + eina_stringshare_del(obj_name); + } + + _vc_elm_widget_wrapper_commit_commands(&__result_cb, NULL); +} + +#ifndef SRPOL_DEBUG +static +#endif +void _hide_tooltips() +{ + VC_ELM_LOG_DBG("hide_tooltips"); + _vc_elm_turn_off_tooltips(); +} + +static int __result_cb(const char *cmd, const char *param1, const char *param2, void *user_data) +{ + (void)user_data; + _hide_tooltips(); + + VC_ELM_LOG_DBG("Got result from VC %s %s %s", cmd, param1, param2); + + if (!_recognize_command(cmd, param1, NULL)) + VC_ELM_LOG_DBG("Command not found"); + return 0; +} + +Eina_Bool _vc_elm_core_equal_actions(const char *action1, const char *action2) +{ + if (!action1 || !action2) + return action1 == action2; + else + return !strcmp(action1, action2); +} + +static void __activate_cb(void *data, Evas_Object *obj, void *event_info) +{ + struct Unwrapped_Command *unwr = (struct Unwrapped_Command *)data; + Evas_Object *object; + const struct vc_elm_core_widget_info *info; + unsigned int idx = 0; + + (void)event_info; + (void)obj; + + if (NULL != unwr) { + object = unwr->wrap->obj; + info = (const struct vc_elm_core_widget_info*)unwr->wrap->data; + + LOGI("activate_cb activated"); + VC_ELM_LOG_DBG("_unwrap_widget_command with params: %s %s %s", unwr->action, unwr->action, unwr->wrap->cmd); + + for (idx = 0; idx < info->actions_count; ++idx) { + if ((!unwr->action && (_vc_elm_core_equal_actions("", _VC_ELM(info->actions[idx].name)))) || _vc_elm_core_equal_actions(unwr->action, _VC_ELM(info->actions[idx].name))) { + VC_ELM_LOG_DBG("activating action %s %s", unwr->action, unwr->param); + info->actions[idx].action_activator_func(object, info->actions[idx].data, unwr->action); + break; + } + } + + if (unwr->action) + free(unwr->action); + if (unwr->param) + free(unwr->param); + free(unwr); + return; + } + return; +} + +static void __activate_invisible_item_cb(void *data, Evas_Object *obj, void *event_info) +{ + if (NULL != obj) + evas_object_smart_callback_del(obj, "scroll,anim,stop", __activate_invisible_item_cb); + + LOGI("_activate_universal_item_cb activated"); + __activate_cb(data, obj, event_info); + + return; +} + +static void __dismissed_cb(void *data, Evas_Object *obj, void *event_info) +{ + (void)data; + (void)event_info; + + if (NULL != obj) + evas_object_smart_callback_del(obj, "dismissed", __dismissed_cb); + + elm_ctxpopup_dismiss(obj); + elm_ctxpopup_clear(obj); + evas_object_del(obj); + +} + +static void __unwrap_universal_item_command(struct Wrapped_Command *wrapper, const char *action, const char *param) +{ + struct Unwrapped_Command *unwr = (struct Unwrapped_Command *)calloc(1, sizeof(struct Unwrapped_Command)); + Elm_Object_Item *item = (Elm_Object_Item *)eina_hash_find(command_item_map, wrapper->cmd); + Evas_Object *parent = NULL; + Elm_Object_Item *parent_item = NULL; + Evas_Coord x; + Evas_Coord y; + Evas_Coord w; + Evas_Coord h; + Evas_Coord x_p; + Evas_Coord y_p; + Evas_Coord w_p; + Evas_Coord h_p; + + if (NULL == unwr) { + VC_ELM_LOG_ERR("Fail to allocate memory"); + return; + } + + unwr->wrap = wrapper; + unwr->action = (action) ? strdup(action) : NULL; + unwr->param = (param) ? strdup(param) : NULL; + VC_ELM_LOG_DBG("__unwrap_universal_item_command with params: %p %p %s %s", (void *)wrapper->obj, (void *)item, action, param); + + if (NULL != item) { + parent = elm_object_parent_widget_get(_vc_elm_core_get_evas_object(item)); + + while (NULL != parent) { + if (0 == strcmp(_get_ui_object_name(parent), "Elm_Genlist")) { + evas_object_geometry_get(_vc_elm_core_get_evas_object(item), &x, &y, &w, &h); + evas_object_geometry_get(parent, &x_p, &y_p, &w_p, &h_p); + if (y > h_p || y < y_p) { + evas_object_smart_callback_add(parent, "scroll,anim,stop", __activate_invisible_item_cb, (void*)unwr); + elm_genlist_item_bring_in(item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE); + } else { + __activate_cb((void*)unwr, NULL, NULL); + } + return; + } else if (0 == strcmp(_get_ui_object_name(parent), "Elm_List")) { + elm_list_item_show(item); + break; + } else if (0 == strcmp(_get_ui_object_name(parent), "Elm_Gengrid")) { + elm_gengrid_item_show(item, ELM_GENGRID_ITEM_SCROLLTO_MIDDLE); + break; + } else if (0 == strcmp(_get_ui_object_name(parent), "Elm_Toolbar")) { + elm_toolbar_item_show(item, ELM_TOOLBAR_ITEM_SCROLLTO_IN); + break; + } else if (0 == strcmp(_get_ui_object_name(parent), "Elm_Ctxpopup")) { + /*no way to bring item in, try clicking it*/ + evas_object_smart_callback_add(parent, "dismissed", __dismissed_cb, NULL); + __activate_cb((void*)unwr, NULL, NULL); + return; + } else { + parent = elm_object_parent_widget_get(parent); + } + } + } + + parent_item = unwr->wrap->parent_item; + if (parent_item != NULL) { + + evas_object_geometry_get(_vc_elm_core_get_evas_object(parent_item), &x, &y, &w, &h); + evas_object_geometry_get(elm_object_parent_widget_get(_vc_elm_core_get_evas_object(parent_item)), &x_p, &y_p, &w_p, &h_p); + + if (y > h_p || y < y_p) { + evas_object_smart_callback_add(elm_object_parent_widget_get(_vc_elm_core_get_evas_object(parent_item)), "scroll,anim,stop", __activate_invisible_item_cb, (void*)unwr); + elm_genlist_item_bring_in(parent_item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE); + return; + } + } + + __activate_cb((void *)unwr, NULL, NULL); +} + +static void __object_del_callback(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + (void)e; + (void)event_info; + eina_stringshare_del((char *)data); + evas_object_data_del(obj, VC_ELM_CMD_DATA_KEY); + ui_objects_list = eina_list_remove(ui_objects_list, obj); +} + +static void __item__object_del_callback(void *data, Evas_Object *obj, void *event_info) +{ + struct Custom_Data *cdata; + Elm_Object_Item *obj_item = (Elm_Object_Item *)event_info; + + (void)data; + (void)obj; + + eina_hash_free_cb_set(item_hint_map, __hash_entry_dummy_cb); + eina_hash_free_cb_set(item_command_map, __hash_entry_dummy_cb); + eina_hash_free_cb_set(item_custom_map, __hash_entry_dummy_cb); + + eina_stringshare_del((char *)eina_hash_find(item_hint_map, &obj_item)); + eina_stringshare_del((char *)eina_hash_find(item_command_map, &obj_item)); + + cdata = (struct Custom_Data *)eina_hash_find(item_custom_map, &obj_item); + free(cdata); + + eina_hash_del(item_hint_map, &obj_item, NULL); + eina_hash_del(item_command_map, &obj_item, NULL); + eina_hash_del(item_custom_map, &obj_item, NULL); + + eina_hash_free_cb_set(item_hint_map, __hash_entry_free_cb); + eina_hash_free_cb_set(item_command_map, __hash_entry_free_cb); + eina_hash_free_cb_set(item_custom_map, __hash_entry_free_cb); +} + +Eina_Bool _vc_elm_core_set_object_command(Evas_Object *obj, const char *_command) +{ + const char *command = eina_stringshare_add(_command); + evas_object_data_set(obj, VC_ELM_CMD_DATA_KEY, command); + if (NULL == eina_list_data_find(ui_objects_list, obj)) + ui_objects_list = eina_list_append(ui_objects_list, obj); + VC_ELM_LOG_DBG("added new item %d %p", eina_list_count(ui_objects_list), (void*)obj); + evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, __object_del_callback, command); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_unset_object_command(Evas_Object *obj) +{ + evas_object_data_del(obj, VC_ELM_CMD_DATA_KEY); + ui_objects_list = eina_list_remove(ui_objects_list, obj); + evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, __object_del_callback); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_set_object_hint(Evas_Object *obj, const char *_hint) +{ + if (evas_object_data_get(obj, VC_ELM_CMD_DATA_KEY) != NULL) { + const char *hint = eina_stringshare_add(_hint); + evas_object_data_set(obj, VC_ELM_HINT_DATA_KEY, hint); + return EINA_TRUE; + } + return EINA_FALSE; +} + +Eina_Bool _vc_elm_core_unset_object_hint(Evas_Object *obj) +{ + evas_object_data_del(obj, VC_ELM_HINT_DATA_KEY); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_set_item_object_command(Elm_Object_Item *obj, const char *_command) +{ + const char *command = eina_stringshare_add(_command); + if (NULL == command) + return EINA_FALSE; + eina_hash_add(item_command_map, &obj, command); + eina_hash_add(command_item_map, command, obj); + elm_object_item_del_cb_set(obj, __item__object_del_callback); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_unset_item_object_command(Elm_Object_Item *obj) +{ + eina_hash_free_cb_set(item_command_map, __hash_entry_dummy_cb); + + eina_stringshare_del((char *)eina_hash_find(item_command_map, &obj)); + eina_hash_del(item_command_map, &obj, NULL); + + eina_hash_free_cb_set(item_command_map, __hash_entry_free_cb); + + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_set_item_object_hint(Elm_Object_Item *obj, const char *_hint) +{ + if (eina_hash_find(item_command_map, &obj) != NULL) { + const char *hint = eina_stringshare_add(_hint); + eina_hash_add(item_hint_map, &obj, hint); + return EINA_TRUE; + } + return EINA_FALSE; +} + +Eina_Bool _vc_elm_core_unset_item_object_hint(Elm_Object_Item *obj) +{ + eina_hash_free_cb_set(item_hint_map, __hash_entry_dummy_cb); + + eina_stringshare_del((char *)eina_hash_find(item_hint_map, &obj)); + eina_hash_del(item_hint_map, &obj, NULL); + + eina_hash_free_cb_set(item_hint_map, __hash_entry_free_cb); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_set_object_custom_hint(Evas_Object *obj, const char *image_path, int pos_x, int pos_y) +{ + if (NULL == obj) { + VC_ELM_LOG_ERR("Invalid Evas_Object parameter detected!"); + return EINA_FALSE; + } + evas_object_data_set(obj, _vc_elm_get_data_key(VC_ELM_HINT_IMAGE_PATH), (const void *)image_path); + evas_object_data_set(obj, _vc_elm_get_data_key(VC_ELM_POSITION_X), (void *)pos_x); + evas_object_data_set(obj, _vc_elm_get_data_key(VC_ELM_POSITION_Y), (void *)pos_y); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_get_object_custom_hint(Evas_Object *obj, const char **image_path, int *pos_x, int *pos_y) +{ + if (NULL == obj) { + VC_ELM_LOG_ERR("Invalid Evas_Object parameter detected!"); + return EINA_FALSE; + } + *image_path = (const char *)evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_HINT_IMAGE_PATH)); + *pos_x = (int)(evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_POSITION_X))); + *pos_y = (int)evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_POSITION_Y)); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_set_item_object_custom_hint(Elm_Object_Item *obj, const char *image_path, int pos_x, int pos_y) +{ + struct Custom_Data *cdata; + if (NULL == obj) { + VC_ELM_LOG_ERR("Invalid Elm_Object_Item parameter detected!"); + return EINA_FALSE; + } + cdata = eina_hash_find(item_custom_map, &obj); + if (NULL == cdata) { + cdata = (struct Custom_Data *)calloc(1, sizeof(struct Custom_Data)); + if (NULL == cdata) { + VC_ELM_LOG_ERR("Fail to allocate memory"); + return EINA_FALSE; + } + cdata->image_path = image_path; + cdata->pos_x = pos_x; + cdata->pos_y = pos_y; + eina_hash_add(item_custom_map, &obj, cdata); + } else { + cdata->image_path = image_path; + cdata->pos_x = pos_x; + cdata->pos_y = pos_y; + } + + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_get_item_object_custom_hint(Elm_Object_Item *obj, const char **image_path, int *pos_x, int *pos_y) +{ + struct Custom_Data *cdata; + if (NULL == obj) { + VC_ELM_LOG_ERR("Invalid Elm_Object_Item parameter detected!"); + return EINA_FALSE; + } + cdata = eina_hash_find(item_custom_map, &obj); + if (NULL != cdata) { + *image_path = (const char *)cdata->image_path; + *pos_x = (int)cdata->pos_x; + *pos_y = (int)cdata->pos_y; + } + + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_unset_item_object_custom_hint(Elm_Object_Item *obj) +{ + struct Custom_Data *cdata; + if (NULL == obj) { + VC_ELM_LOG_ERR("Invalid Elm_Object_Item parameter detected!"); + return EINA_FALSE; + } + cdata = eina_hash_find(item_custom_map, &obj); + if (NULL == cdata) { + eina_hash_del(item_custom_map, &obj, cdata); + free(cdata); + } + + return EINA_TRUE; +} + +const char *_vc_elm_core_get_object_hint(const Evas_Object *obj) +{ + const char *hint = evas_object_data_get(obj, VC_ELM_HINT_DATA_KEY); + return hint; +} + +Eina_Bool _vc_elm_core_set_object_hint_fixed_possition(Evas_Object *obj, int x, int y) +{ + evas_object_data_set(obj, _vc_elm_get_data_key(VC_ELM_FIXED_X), (void *)x); + evas_object_data_set(obj, _vc_elm_get_data_key(VC_ELM_FIXED_Y), (void *)y); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_get_object_hint_fixed_possition(Evas_Object *obj, int *x, int *y) +{ + *x = (int)evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_FIXED_X)); + *y = (int)evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_FIXED_Y)); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_del_object_hint_fixed_possition(Evas_Object *obj) +{ + evas_object_data_del(obj, _vc_elm_get_data_key(VC_ELM_FIXED_X)); + evas_object_data_del(obj, _vc_elm_get_data_key(VC_ELM_FIXED_Y)); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_set_object_hint_direction(Evas_Object *obj, vc_elm_direction_e direction) +{ + evas_object_data_set(obj, VC_ELM_DIRECTION, (void *)(direction + 1)); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_get_object_hint_direction(Evas_Object *obj, vc_elm_direction_e *direction) +{ + *direction = ((vc_elm_direction_e)evas_object_data_get(obj, VC_ELM_DIRECTION)) - 1; + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_del_object_hint_direction(Evas_Object *obj) +{ + evas_object_data_del(obj, VC_ELM_DIRECTION); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_set_sub_item_hint_direction(Evas_Object *obj, vc_elm_direction_e direction) +{ + evas_object_data_set(obj, VC_ELM_SUB_ITEM_DIRECTION, (void *)direction); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_get_sub_item_hint_direction(Evas_Object *obj, vc_elm_direction_e *direction) +{ + *direction = (vc_elm_direction_e)evas_object_data_get(obj, VC_ELM_SUB_ITEM_DIRECTION); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_del_sub_item_hint_direction(Evas_Object *obj) +{ + evas_object_data_del(obj, VC_ELM_SUB_ITEM_DIRECTION); + return EINA_TRUE; +} + +Eina_Bool _vc_elm_core_enable_name_autogen(Eina_Bool ag) +{ + g_hints_autogenerated = ag; + return EINA_TRUE; +} + +static void __show_or_hide_tooltips_callback(bool show_or_hide) +{ + VC_ELM_LOG_DBG("tooltips %d", show_or_hide); + g_tooltips_displayed = show_or_hide; + if (show_or_hide) + _show_tooltips(); + else + _hide_tooltips(); +} + +/*static void __idle_changed(Ecore_Evas *ee) { + (void)ee; + VC_ELM_LOG_DBG("Evas has changed"); +}*/ + +static Eina_Bool __idle_enter(void *data) +{ + Eina_List *l; + Evas_Object *obj; + Eina_Bool is_focused = elm_win_focus_get(g_default_window); + Ecore_X_Window focused = ecore_x_window_focus_get(); + (void)data; + + VC_ELM_LOG_DBG("Focused %ud", focused); + VC_ELM_LOG_DBG("Focused g_default %ud", elm_win_xwindow_get(g_default_window)); + if (!is_focused || focused != elm_win_xwindow_get(g_default_window)) { + /* window changed, we need to get new one */ + VC_ELM_LOG_DBG("list count %d", eina_list_count(ui_objects_list)); + EINA_LIST_FOREACH(ui_objects_list, l, obj) { + Evas_Object *window = NULL; + VC_ELM_LOG_DBG("foreach obj %p", (void*)obj); + window = elm_object_top_widget_get(obj); + if (window && elm_win_focus_get(window) == EINA_TRUE) { + /*Ecore_Evas *ecevas = NULL;*/ + VC_ELM_LOG_DBG("NEW Focused g_default %ud", elm_win_xwindow_get(window)); + g_default_window = window; + /*ecevas = ecore_evas_ecore_evas_get(evas_object_evas_get(g_default_window)); + ecore_evas_callback_post_render_set(ecevas, __idle_changed);*/ + break; + } + } + } + + /* OK, window set properly now */ + + _vc_elm_set_tooltips_window(g_default_window); + VC_ELM_LOG_DBG("elm_win_xwindow_get = %p", (void*)elm_win_xwindow_get(g_default_window)); + + if (elm_win_wm_rotation_supported_get(g_default_window)) { + int rots[4] = {0, 90, 180, 270}; + elm_win_wm_rotation_available_rotations_set(g_default_window, (const int*)&rots, 4); + evas_object_smart_callback_add(g_default_window, "wm,rotation,changed", __rotation, g_default_window); + VC_ELM_LOG_DBG("Added support for rotation"); + } else { + VC_ELM_LOG_DBG("wm rotation supported get error"); + } + + g_current_ui_objects = _vc_elm_core_find_all_visible_objects(); + + VC_ELM_LOG_DBG("adding commands"); + __vc_add_commands(); + VC_ELM_LOG_DBG("idle enter finish"); + return ECORE_CALLBACK_CANCEL; +} + +static void __rotation(void *data, Evas_Object *obj, void *event_info) +{ + (void)data; + (void)obj; + (void)event_info; + if (!g_tooltips_displayed) + return; + __show_or_hide_tooltips_callback(false); + ecore_main_loop_iterate(); + __show_or_hide_tooltips_callback(true); + ecore_main_loop_iterate(); +} + +const char *_vc_elm_get_custom_widget_name() +{ + return VC_ELM_CUSTOM_WIDGET_NAME; +} + +int _vc_elm_core_read_xml_data() +{ + xmlDocPtr doc = NULL; + xmlNodePtr root = NULL; + xmlNodePtr main_node = NULL; + xmlNodePtr cur = NULL; + xmlNodePtr child = NULL; + xmlNodePtr tmp = NULL; + xmlChar *key = NULL; + + VC_ELM_LOG_DBG("reading XML start"); + doc = xmlParseFile(VC_ELM_CONFIG_XML); + if (doc == NULL) { + VC_ELM_LOG_ERR("Failed to parse XML file"); + return VC_ELM_ERROR_OPERATION_FAILED; + } + + main_node = xmlDocGetRootElement(doc); + if (main_node == NULL) { + VC_ELM_LOG_ERR("Empty XML document"); + xmlFreeDoc(doc); + return VC_ELM_ERROR_OPERATION_FAILED; + } + + root = main_node->xmlChildrenNode; + do { + VC_ELM_LOG_DBG("Root nodes mames %s", root->name); + if (0 == xmlStrcmp(root->name, XML_CAST VC_ELM_TAG_BASE_NAME)) { + cur = root->xmlChildrenNode; + do { + if (cur == NULL) { + VC_ELM_LOG_ERR("Empty XML document"); + xmlFreeDoc(doc); + return VC_ELM_ERROR_OPERATION_FAILED; + } + VC_ELM_LOG_DBG("cur->name %s", cur->name); + if (0 == xmlStrcmp(cur->name, XML_CAST VC_ELM_TAG_ACTION_LIST)) { + child = cur->xmlChildrenNode; + VC_ELM_LOG_DBG("xml pointer last %s %p", cur->last->name, (void *)cur->last); + do { + if (0 == xmlStrcmp(child->name, XML_CAST VC_ELM_TAG_ACTION_GROUP)) { + const char *action_name = NULL; + tmp = child->xmlChildrenNode; + do { + if (0 == xmlStrcmp(tmp->name, XML_CAST VC_ELM_TAG_ACTION_NAME)) { + key = xmlNodeGetContent(tmp); + VC_ELM_LOG_DBG("action name %s", (char *)key); + action_name = eina_stringshare_add((char *)key); + xmlFree(key); + } else if (0 == xmlStrcmp(tmp->name, XML_CAST VC_ELM_TAG_ACTION_COMMAND)) { + const char *action_command = NULL; + key = xmlNodeGetContent(tmp); + VC_ELM_LOG_DBG("action command %s", (char *)key); + if (action_name != NULL) { + action_command = eina_stringshare_add((char *)key); + eina_hash_add(g_config_action_map, action_name, action_command); + } + xmlFree(key); + } + tmp = tmp->next; + } while (tmp != NULL); + } + child = child->next; + } while (child != NULL); + } else if (0 == xmlStrcmp(cur->name, XML_CAST VC_ELM_TAG_WIDGET_LIST)) { + child = cur->xmlChildrenNode; + do { + if (0 == xmlStrcmp(child->name, XML_CAST VC_ELM_TAG_WIDGET_GROUP)) { + const char *widget_name = NULL; + tmp = child->xmlChildrenNode; + do { + if (0 == xmlStrcmp(tmp->name, XML_CAST VC_ELM_TAG_WIDGET_NAME)) { + key = xmlNodeGetContent(tmp); + VC_ELM_LOG_DBG("widget name %s", (char *)key); + widget_name = eina_stringshare_add((char *)key); + xmlFree(key); + } else if (0 == xmlStrcmp(tmp->name, XML_CAST VC_ELM_TAG_WIDGET_ACTIONS)) { + xmlNodePtr actions = tmp->xmlChildrenNode; + Eina_List *actions_list = NULL; + do { + if (0 == xmlStrcmp(actions->name, XML_CAST VC_ELM_TAG_ACTION_NAME)) { + const char *action_tag = NULL; + key = xmlNodeGetContent(actions); + VC_ELM_LOG_DBG("widget action name %s", (char*)key); + action_tag = eina_stringshare_add((char*)key); + actions_list = eina_list_append(actions_list, action_tag); + xmlFree(key); + } + actions = actions->next; + } while (actions != NULL); + if (widget_name != NULL && actions_list != NULL) + eina_hash_add(g_config_widget_map, widget_name, actions_list); + } + tmp = tmp->next; + } while (tmp != NULL); + } + child = child->next; + } while (child != NULL); + } else if (0 == xmlStrcmp(cur->name, XML_CAST VC_ELM_TAG_HINT_GROUP)) { + child = cur->xmlChildrenNode; + do { + if (0 == xmlStrcmp(child->name, XML_CAST VC_ELM_TAG_HINT_SHOW)) { + key = xmlNodeGetContent(child); + VC_ELM_LOG_DBG("hint show %s", (char*)key); + g_tooltips_show = strdup((char*)key); + xmlFree(key); + } else if (0 == xmlStrcmp(child->name, XML_CAST VC_ELM_TAG_HINT_DIRECTION)) { + key = xmlNodeGetContent(child); + VC_ELM_LOG_DBG("hint direction %s", (char*)key); + g_tooltips_default_direction = strdup((char*)key); + xmlFree(key); + } else if (0 == xmlStrcmp(child->name, XML_CAST VC_ELM_TAG_HINT_IMAGE)) { + key = xmlNodeGetContent(child); + VC_ELM_LOG_DBG("hint image %s", (char*)key); + g_tooltips_image_path = strdup((char*)key); + xmlFree(key); + } + child = child->next; + } while (child != NULL); + } + cur = cur->next; + } while (cur != NULL); + } else if (0 == xmlStrcmp(root->name, XML_CAST VC_ELM_TAG_BASE_INFO)) { + cur = root->xmlChildrenNode; + do { + if (0 == xmlStrcmp(cur->name, XML_CAST VC_ELM_TAG_TIZEN_VERSION)) { + key = xmlNodeGetContent(cur); + VC_ELM_LOG_DBG("hint direction %s", (char*)key); + xmlFree(key); + } else if (0 == xmlStrcmp(cur->name, XML_CAST VC_ELM_TAG_PROFILE)) { + key = xmlNodeGetContent(cur); + VC_ELM_LOG_DBG("hint direction %s", (char*)key); + xmlFree(key); + } else if (0 == xmlStrcmp(cur->name, XML_CAST VC_ELM_TAG_EFL_VERSION)) { + key = xmlNodeGetContent(cur); + VC_ELM_LOG_DBG("hint direction %s", (char*)key); + xmlFree(key); + } + cur = cur->next; + } while (cur != NULL); + } + root = root->next; + } while (root != NULL); + + xmlFreeDoc(doc); + + return VC_ELM_ERROR_NONE; +} + +int _vc_elm_core_destroy_xml_data() +{ + + if (g_tooltips_show) + free(g_tooltips_show); + if (g_tooltips_default_direction) + free(g_tooltips_default_direction); + if (g_tooltips_image_path) + free(g_tooltips_image_path); + return VC_ELM_ERROR_NONE; +} + +int _vc_elm_core_get_tooltip_default_direction() +{ + if (NULL == g_tooltips_default_direction) + return VC_ELM_DIRECTION_CENTER; + + if (!strcmp(g_tooltips_default_direction, "center")) + return VC_ELM_DIRECTION_CENTER; + else if (!strcmp(g_tooltips_default_direction, "left")) + return VC_ELM_DIRECTION_LEFT; + else if (!strcmp(g_tooltips_default_direction, "right")) + return VC_ELM_DIRECTION_RIGHT; + else if (!strcmp(g_tooltips_default_direction, "top")) + return VC_ELM_DIRECTION_TOP; + else if (!strcmp(g_tooltips_default_direction, "bottom")) + return VC_ELM_DIRECTION_BOTTOM; + else if (!strcmp(g_tooltips_default_direction, "left top")) + return VC_ELM_DIRECTION_LEFT_TOP; + else if (!strcmp(g_tooltips_default_direction, "left bottom")) + return VC_ELM_DIRECTION_LEFT_BOTTOM; + else if (!strcmp(g_tooltips_default_direction, "right top")) + return VC_ELM_DIRECTION_RIGHT_TOP; + else if (!strcmp(g_tooltips_default_direction, "right bottom")) + return VC_ELM_DIRECTION_RIGHT_BOTTOM; + else + return VC_ELM_DIRECTION_CENTER; +} + +const char *_vc_elm_core_get_tooltip_image_path() +{ + return (const char *)g_tooltips_image_path; +} + +int _vc_elm_core_get_tooltip_show() +{ + if (NULL == g_tooltips_show) + return EINA_FALSE; + else if (0 == strcmp(g_tooltips_show, "on")) + return EINA_TRUE; + + return EINA_FALSE; +} diff --git a/src/vc_elm_core.h b/src/vc_elm_core.h new file mode 100644 index 0000000..7577d16 --- /dev/null +++ b/src/vc_elm_core.h @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2011-2014 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 __VC_ELM_CORE_H__ +#define __VC_ELM_CORE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include +/** + * @file vc_elm_core.h + * @brief This file contains core functions, that define the behaviour of library + */ + +#define VC_ELM_CONFIG_XML "/usr/lib/voice/vc-elm/1.0/voice-control-elm-config.xml" +#define VC_ELM_TAG_BASE_NAME "voice-control-elm-config" + +#define VC_ELM_TAG_ACTION_LIST "action-list" +#define VC_ELM_TAG_ACTION_GROUP "action" +#define VC_ELM_TAG_ACTION_NAME "action-name" +#define VC_ELM_TAG_ACTION_COMMAND "action-command" + +#define VC_ELM_TAG_WIDGET_LIST "widget-list" +#define VC_ELM_TAG_WIDGET_GROUP "widget" +#define VC_ELM_TAG_WIDGET_NAME "widget-name" +#define VC_ELM_TAG_WIDGET_ACTIONS "actions" + +#define VC_ELM_TAG_HINT_GROUP "hint" +#define VC_ELM_TAG_HINT_SHOW "hint-show" +#define VC_ELM_TAG_HINT_DIRECTION "default-hint-direction" +#define VC_ELM_TAG_HINT_IMAGE "default-hint-image" + +#define VC_ELM_TAG_BASE_INFO "voice-control-elm-info" +#define VC_ELM_TAG_TIZEN_VERSION "tizen-version" +#define VC_ELM_TAG_PROFILE "profile" +#define VC_ELM_TAG_EFL_VERSION "efl-version" + +#define VC_ELM_HINT_DATA_KEY "vc_elm_hint_data_key" +#define VC_ELM_CMD_DATA_KEY "vc_elm_cmd_data_key" +#define VC_ELM_CUSTOM_WIDGET_NAME "VC_ELM_CUSTOM_WIDGET_NAME" +#define VC_ELM_DIRECTION "vc_elm_direction" +#define VC_ELM_SUB_ITEM_DIRECTION "vc_elm_sub_item_direction" + +/** + * @brief This array holds names for autogenerated tooltips + */ +static const char *const autogen_names[] = + {"IDS_ALPHA", "IDS_BRAVO", "IDS_CHARLIE", "IDS_DELTA", "IDS_ECHO", + "IDS_FOXTROT", "IDS_GOLF", "IDS_HOTEL", "IDS_INDIA", "IDS_JULIET", + "IDS_KILO", "IDS_LIMA", "IDS_MIKE", /*"IDS_NOVEMBER",*/"IDS_OSCAR", + "IDS_PAPA", "IDS_QUEBEC", "IDS_ROMEO", "IDS_SIERRA", "IDS_TANGO", + "IDS_UNIFORM", "IDS_VICTOR", "IDS_WHISKEY", "IDS_X_RAY", "IDS_YANKEE", + "IDS_ZULU", "IDS_ZORRO", "IDS_CASTLE", "IDS_ONE", "IDS_TWO", + "IDS_THREE", "IDS_FOUR", "IDS_FIVE", "IDS_SIX", "IDS_SEVEN", + "IDS_EIGHT", "IDS_NINE", "IDS_TEN", "IDS_ELEVEN", "IDS_TWELVE"}; + +/** + * @brief A handle to the dynamic action info structure + */ +typedef struct vc_elm_core_dynamic_action_info vc_elm_dynamic_action_info; + +/** + * @brief A handle to the widget action info structure + */ +typedef struct vc_elm_core_action_info vc_elm_action_info; + +/** + * @brief A handle to the widget info structure + */ +typedef struct vc_elm_core_widget_info vc_elm_widget_info; + +/** + * @brief A callback function type to be called to get wigdet subobjects list + */ +typedef Eina_List *(*vc_elm_get_subobjects_cb)(const Evas_Object *obj, void *user_data); + +/** + * @brief A callback function type to be called to filter allowed commands to be used for a widget. + */ +typedef Eina_Bool (*vc_elm_command_filter_cb)(Evas_Object *obj, const char *text, void *user_data); + +/** + * @brief A callback function type to be called to process action when an allowed command recognized. + */ +typedef void (*vc_elm_action_activator_cb)(Evas_Object *object, void *data, const char *action_name); + +const char *_vc_elm_get_custom_widget_name(); + +const char *_get_ui_object_name(const Evas_Object *obj); + +/** + * @brief The vc_elm_core_dynamic_action_info struct is responsible for holding dynamic action info + */ +struct vc_elm_core_dynamic_action_info { + void *data; + void **items; + unsigned int items_count; + void (*activate_item_tooltip_func)(void *item, void *data); + void (*show_item_tooltip_func)(const char *hint, void *item, void *data); + void (*hide_item_tooltip_func)(void *item, void *data); + void (*free_dynamic_action_info)(struct vc_elm_core_dynamic_action_info *dinfo, void *data); +}; + +/** + * @brief The vc_elm_core_action_info struct is responsible for holding action info + */ +struct vc_elm_core_action_info { + const char *name; + void *data; + vc_elm_action_activator_cb action_activator_func; +}; + +/** + * @brief The vc_elm_core_widget_info struct is responsible for holding widget info + */ +struct vc_elm_core_widget_info { + const char *name; + struct vc_elm_core_action_info *actions; + unsigned int actions_count; + vc_elm_get_subobjects_cb get_subobjects_func; + vc_elm_command_filter_cb is_filtered_func; + void *user_data; +}; + +/** + * @brief vc_elm_core_init function is responsible for initializing voice-control-elm module + * + * @see vc-elm-initialize + * @see vc-elm-shutdown + * @see vc_elm_core_fini + */ +void _vc_elm_core_init(); +/** + * @brief vc_elm_core_fini function is responsible for deinitializing voice-control-elm module + * + * @see vc-elm-initialize + * @see vc-elm-shutdown + * @see vc_elm_core_init + */ +void _vc_elm_core_fini(); +void _vc_elm_core_load(); +unsigned int _vc_elm_core_get_window(); +Evas_Object *_vc_elm_core_get_evas_object(Elm_Object_Item *item); + +#ifdef SRPOL_DEBUG +/** + * @brief _show_tooltips function runs steps necessary to show tooltips on screen + * @details This function may be invoked from outside only for test purposes + * + * @see _hide_tooltips + */ +void _show_tooltips(); +/** + * @brief _hide_tooltips function runs steps necessary to hide tooltips from screen + * @details This function may be invoked from outside only for test purposes + */ +void _hide_tooltips(); +#endif + +/** + * @brief vc_elm_core_find_all_visible_objects function searches for visible objects on screen + * @return Eina_List *list of visible objects or NULL if no default window + */ +Eina_List *_vc_elm_core_find_all_visible_objects(); + +/** + * @brief vc_elm_core_register_widget function registers widget in voice-control-elm module, to enable voice + * commands on it + * @param widget_name the name of the widget + * @param widget_hint_name the hint do be displayed over the widget + * @param focus_enabled_func pointer to function invoked when widget gets focused + * @param get_subobjects_func pointer to function for a widget with subwidgets + * @param is_filtered_func pointer to function enabling filtering widget + * @return vc_elm_core_widget_info struct pointer or null if already registered + */ +struct vc_elm_core_widget_info *_vc_elm_core_register_widget(const char *widget_name, vc_elm_get_subobjects_cb get_subobjects_func, vc_elm_command_filter_cb is_filtered_func, void *user_data); + +/** + * @brief vc_elm_core_register_action function registers action to be performed on widget in voice-control-elm + * module + * @param widget Pointer to vc_elm_core_action_info object + * @param action_name Name of action + * @param data Additional data to be passed to action_activator_func + * @param action_activator_func function to be invoked when action is activated + */ +void _vc_elm_core_register_action(struct vc_elm_core_widget_info *widget, const char *action_name, void *data, vc_elm_action_activator_cb action_activator_func); + +/** + * @brief vc_elm_core_default_widgets_register function, registers all supported default widgets in + * voice-control-elm module + */ +void _vc_elm_core_register_default_widgets(); + +/** + * @brief vc_elm_core_default_widgets_register function, registers selected widget in + * voice-control-elm module + */ +Eina_Bool _vc_elm_core_register_default_widget(const char *widget_name, Eina_Bool register_widget, Eina_List *actions); + +/** + * @brief vc_elm_actions_equal function checks is two given actions are the same + * @param action1 name of first action + * @param action2 name of second action + * @return EINA_TRUE if equal or EINA_FALSE if not equal + */ +Eina_Bool _vc_elm_core_equal_actions(const char *action1, const char *action2); + +/** + * @brief vc_elm_core_object_hint_set function sets custom hint for object + * @param obj pointer to desired widget + * @param hint hint to be displayed + * @return EINA_TRUE if successful or EINA_FALSE otherwise + * + * @see vc_elm_core_unset_object_hint + */ +Eina_Bool _vc_elm_core_set_object_hint(Evas_Object *obj, const char *hint); + +/** + * @brief vc_elm_core_object_hint_unset function unsets custom hint from object + * @param obj pointer to desired widget + * @return EINA_TRUE if successful or EINA_FALSE otherwise + * + * @see vc_elm_core_set_object_hint + */ +Eina_Bool _vc_elm_core_unset_object_hint(Evas_Object *obj); + +/** + * @brief vc_elm_core_object_command_set function sets command for object + * @param obj pointer to desired widget + * @param command command to activate widget + * @return EINA_TRUE if successful of EINA_FALSE otherwise + * + * @see vc_elm_core_unset_object_command + */ +Eina_Bool _vc_elm_core_set_object_command(Evas_Object *obj, const char *command); + +/** + * @brief vc_elm_core_object_command_unset function unsets command from object + * @param obj pointer to desired widget + * @return EINA_TRUE if successful of EINA_FALSE otherwise + * + * @see vc_elm_core_set_object_command + */ +Eina_Bool _vc_elm_core_unset_object_command(Evas_Object *obj); + +/** + * @brief vc_elm_core_item_object_hint_set function sets hint for subitem + * @param obj pointer to subitem + * @param hint hint to be set + * @param list pointer to subitem's parent + * @return EINA_TRUE if successful or EINA_FALSE otherwise + * + * @see vc_elm_core_unset_item_object_hint + */ +Eina_Bool _vc_elm_core_set_item_object_hint(Elm_Object_Item *obj, const char *hint); + +/** + * @brief vc_elm_core_object_custom_hint_set function sets tooltip's image and position of tooltip + * @param obj pointer to widget + * @param image_path image path + * @param pos_x x coordinate + * @param pos_y y coordinate + * @return EINA_TRUE if successful or EINA_FALSE otherwise + * + * @see vc_elm_core_get_object_custom_hint + */ +Eina_Bool _vc_elm_core_set_object_custom_hint(Evas_Object *obj, const char *image_path, int pos_x, int pos_y); + +/** + * @brief vc_elm_core_get_object_custom_hint function gets tooltip's image and position of tooltip + * @param obj pointer to widget + * @param image_path image path + * @param pos_x x coordinate + * @param pos_y y coordinate + * @return EINA_TRUE if successful or EINA_FALSE otherwise + * + * @see vc_elm_core_set_item_object_custom_hint + */ +Eina_Bool _vc_elm_core_get_object_custom_hint(Evas_Object *obj, const char **image_path, int *pos_x, int *pos_y); + +/** + * @brief vc_elm_core_item_object_custom_hint_set function sets tooltip's image and position of tooltip + * @param obj pointer to subitem + * @param image_path image path + * @param pos_x x coordinate + * @param pos_y y coordinate + * @return EINA_TRUE if successful or EINA_FALSE otherwise + * + * @see vc_elm_core_get_item_object_custom_hint + */ +Eina_Bool _vc_elm_core_set_item_object_custom_hint(Elm_Object_Item *obj, const char *image_path, int pos_x, int pos_y); + +/** + * @brief vc_elm_core_get_item_object_custom_hint function gets tooltip's image and position of tooltip + * @param obj pointer to subitem + * @param image_path image path + * @param pos_x x coordinate + * @param pos_y y coordinate + * @return EINA_TRUE if successful or EINA_FALSE otherwise + * + * @see vc_elm_core_set_item_object_custom_hint + */ +Eina_Bool _vc_elm_core_get_item_object_custom_hint(Elm_Object_Item *obj, const char **image_path, int *pos_x, int *pos_y); + +/** + * @brief vc_elm_core_object_hint_get function gets object's hint + * @param obj pointer to object + * @return hint for object + */ +const char *_vc_elm_core_get_object_hint(const Evas_Object *obj); + +/** + * @brief vc_elm_core_object_skip_set function marks a widget that hint is not to be set + * @param obj pointer to widget + * @return EINA_TRUE if succesful or EINA_FALSE otherwise + */ +Eina_Bool _vc_elm_core_set_skip_object(Evas_Object *obj); + +/** + * @brief vc_elm_core_object_skip_get function checking if widget's hint is to be set + * @param obj pointer to widget + * @return EINA_TRUE if true, EINA_FALSE if not + */ +Eina_Bool _vc_elm_core_get_skip_object(const Evas_Object *obj); + +/** + * @brief vc_elm_core_item_object_hint_unset function unsets hint from subitem + * @param obj pointer to subitem + * @param list pointer to subitem's parent + * @return EINA_TRUE if successful or EINA_FALSE otherwise + * + * @see vc_elm_core_set_item_object_hint + */ +Eina_Bool _vc_elm_core_unset_item_object_hint(Elm_Object_Item *obj); + +/** + * @brief vc_elm_core_item_object_command_set function sets command for subitem + * @param obj pointer to subitem + * @param command command to activate subitem + * @param list pointer to subitem's parent + * @return EINA_TRUE if successful or EINA_FALSE otherwise + * + * @see vc_elm_core_unset_item_object_command + */ +Eina_Bool _vc_elm_core_set_item_object_command(Elm_Object_Item *obj, const char *command); + +/** + * @brief vc_elm_core_item_object_command_unset function unsets command from subitem + * @param obj pointer to subitem + * @param list pointer to subitem's parent + * @return EINA_TRUE if successful or EINA_FALSE otherwise + * + * @see vc_elm_core_set_item_object_command + */ +Eina_Bool _vc_elm_core_unset_item_object_command(Elm_Object_Item *obj); + +/** + * @brief vc_elm_core_object_hint_fixed_possition_set function sets fixed position of tooltip + * @param obj pointer to widget + * @param x x coordinate + * @param y y coordinate + * @return EINA_TRUE if successful, EINA_FALSE otherwise + */ +Eina_Bool _vc_elm_core_set_object_hint_fixed_possition(Evas_Object *obj, int x, int y); + +/** + * @brief vc_elm_core_object_hint_fixed_possition_get function gets fixed position of tooltip + * @param obj pointer to widget + * @param x x coordinate + * @param y y coordinate + * @return EINA_TRUE if successful, EINA_FALSE otherwise + */ +Eina_Bool _vc_elm_core_get_object_hint_fixed_possition(Evas_Object *obj, int *x, int *y); + +/** + * @brief vc_elm_core_object_hint_fixed_possition_del function removes tooltip's fixed position + * @param obj pointer to widget + * @return EINA_TRUE if successful, EINA_FALSE otherwise + */ +Eina_Bool _vc_elm_core_del_object_hint_fixed_possition(Evas_Object *obj); + +/** + * @brief vc_elm_core_object_hint_direction_set function sets direction of widget's tooltip + * @param obj pointer to widget + * @param direction direction as defined by vc_elm_direction_e + * @return EINA_TRUE if successful, EINA_FALSE otherwise + */ +Eina_Bool _vc_elm_core_set_object_hint_direction(Evas_Object *obj, vc_elm_direction_e direction); + +/** + * @brief vc_elm_core_object_hint_direction_get function gets tooltip's direction + * @param obj pointer to widget + * @param direction direction of the tooltip + * @return EINA_TRUE if successfull, EINA_FALSE otherwise + */ +Eina_Bool _vc_elm_core_get_object_hint_direction(Evas_Object *obj, vc_elm_direction_e *direction); + +/** + * @brief vc_elm_core_object_hint_direction_del function unsets tooltip's direction + * @param obj pointer to widget + * @return EINA_TRUE if successfull, EINA_FALSE otherwise + */ +Eina_Bool _vc_elm_core_del_object_hint_direction(Evas_Object *obj); + +/** + * @brief vc_elm_core_name_autogen_enable function enables or disables tooltips autogeneration + * @param ag EINA_TRUE if enable autogenerate, EINA_FALSE if not + * @return EINA_TRUE + */ +Eina_Bool _vc_elm_core_enable_name_autogen(Eina_Bool ag); + +/** + * @brief vc_elm_core_get_visible_item function returns first visible subitem of widget + * @param parent pointer to parent widget + * @return first visible item + */ +Elm_Object_Item *_vc_elm_core_get_visible_item(Evas_Object *parent, Elm_Object_Item *(*get_first)(const Evas_Object *obj, void *user_data), Elm_Object_Item *(*get_next)(const Elm_Object_Item *item, void *user_data), void *user_data); + +/** + * @brief vc_elm_core_sub_item_hint_direction_set function sets direction of subwidget's tooltips + * @param obj pointer to parent object + * @param direction direction of tooltips as defined in vc_elm_sub_item_direction_e + * @return + */ +Eina_Bool _vc_elm_core_set_sub_item_hint_direction(Evas_Object *obj, vc_elm_direction_e direction); +/** + * @brief vc_elm_core_sub_item_hint_direction_get function gets direction of subwidget's tooltips + * @param obj pointer to parent object + * @param direction pointer to direction object as defined in vc_elm_sub_item_direction_e + * @return + */ +Eina_Bool _vc_elm_core_get_sub_item_hint_direction(Evas_Object *obj, vc_elm_direction_e *direction); + +/** + * @brief vc_elm_core_read_xml_data function reads and parses configurable xml file + * @return + */ +int _vc_elm_core_read_xml_data(); + +/** + * @brief vc_elm_core_destroy_xml_data function removes configurable xml variables + * @return + */ +int _vc_elm_core_destroy_xml_data(); + +/** + * @brief vc_elm_core_get_tooltip_default_direction function returns tooltip + * default direction specified in configuration file + * @return default direction enum vc_elm_direction_e value + */ +int _vc_elm_core_get_tooltip_default_direction(); + +/** + * @brief vc_elm_core_get_tooltip_image_path function returns if tooltip should + * be displayed or not according to configuration file + * @return EINA_TRUE if tooltips should be displayed, otherwise EINA_FALSE + */ +const char *_vc_elm_core_get_tooltip_image_path(); + +/** + * @brief vc_elm_core_get_tooltip_show function returns tooltip + * char table + * @return path to the image file + */ +int _vc_elm_core_get_tooltip_show(); + +/** + * @brief _vc_elm_core_get_config_action_map function returns hash map + * of actions registered in library + * @return path to the image file + */ +const Eina_Hash *_vc_elm_core_get_config_action_map(); + +/** + * @brief _vc_elm_core_get_config_widget_map function returns hash map + * of widgets registered in library + * @return path to the image file + */ +const Eina_Hash *_vc_elm_core_get_config_widget_map(); + + +#ifdef __cplusplus +} +#endif + +#endif/*__VC_ELM_CORE_H__*/ diff --git a/src/vc_elm_core_default_widgets.c b/src/vc_elm_core_default_widgets.c new file mode 100644 index 0000000..e2cf50b --- /dev/null +++ b/src/vc_elm_core_default_widgets.c @@ -0,0 +1,1751 @@ +/* + * Copyright (c) 2011-2014 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 "vc_elm_main.h" +#include +#include +#include + +#include "vc_elm.h" +#include "vc_elm_core.h" +#include "vc_elm_tools.h" +#include "vc_elm_tooltip.h" + +#ifdef _ +#undef _ +#endif +#define _VC_ELM(S) dgettext("voice-control-elm", S) + +#define DEGRESS_15 15.0 +#define DEGRESS_90 90.0 +#define DEGRESS_180 180.0 + +static const char SCROLL_UP[] = "IDS_SCROLL_UP"; +static const char SCROLL_DOWN[] = "IDS_SCROLL_DOWN"; +static const char CENTER[] = "IDS_CENTER"; +static const char SCROLL_LEFT[] = "IDS_SCROLL_LEFT"; +static const char SCROLL_RIGHT[] = "IDS_SCROLL_RIGHT"; +static const char UP[] = "IDS_UP"; +static const char DOWN[] = "IDS_DOWN"; +static const char LEFT[] = "IDS_LEFT"; +static const char RIGHT[] = "IDS_RIGHT"; +static const char HOME[] = "IDS_HOME"; +static const char END[] = "IDS_END"; +static const char CLICK[] = ""; + +enum SCROLL_AMOUNT { + LESS, + LITTLE, + MORE, + MAXIMAL +}; +enum SCROLL_TURN { + HORIZONTAL, + VERTICAL +}; +enum SCROLL_DIRECTION { + TO_BEGINNING, + TO_END +}; + +static void __set_toooltips_position_on_visible_items(Evas_Object *parent, Elm_Object_Item *(*get_first)(const Evas_Object *obj, void *user_data), Elm_Object_Item *(*get_next)(const Elm_Object_Item *item, void *user_data), void *user_data); + +/** + * @brief Function for scrolling elementary object + * @param Scrolable Evas_Object + * @param enumeration value of amount of scroll + * @param enumeration value of turn + * @param enumeration value of direction + */ +static void __scroll_object(Evas_Object *scrollable, enum SCROLL_AMOUNT amount, enum SCROLL_TURN turn, enum SCROLL_DIRECTION direction) +{ + int x; + int y; + int w; + int h; + int mw; + int mh; + int pw; + int ph; + int *pos; + int count; + int sign; + int maximal; + + elm_scroller_child_size_get(scrollable, &mw, &mh); + elm_scroller_region_get(scrollable, &x, &y, &w, &h); + evas_object_geometry_get(scrollable, NULL, NULL, &pw, &ph); + VC_ELM_LOG_DBG("cur region %d %d %d %d", x, y, w, h); + VC_ELM_LOG_DBG("max region %d %d", mw, mh); + VC_ELM_LOG_DBG("page size %d %d", pw, ph); + if (mw < 0) + mw = 65535; + if (mh < 0) + mh = 65535; + + if (HORIZONTAL == turn) { + pos = &x; + count = w; + maximal = mw - w; + } else { + pos = &y; + count = h; + maximal = mh - h; + } + + if (TO_BEGINNING == direction) { + sign = -1; + maximal = 0; + } else { + sign = 1; + } + + switch (amount) { + case LESS: + *pos += sign * ph / 2; + break; + case LITTLE: + *pos += sign * count / 2; + break; + case MORE: + *pos += sign * count * 2; + break; + case MAXIMAL: + *pos = maximal; + break; + default: + VC_ELM_LOG_ERR("assert failed"); + exit(-1); + } + + VC_ELM_LOG_DBG("next region %d %d %d %d", x, y, w, h); + elm_scroller_region_bring_in(scrollable, x, y, w, h); +} + +/** + * @brief Emulate mouse click function on point defined by coordinates. + * @param Elementary object + * @param x coordinates + * @param y coordinates + */ +static void __emulate_mouse_click_full(const Evas_Object *object, char xpercent, char ypercent) +{ + int x; + int y; + int w; + int h; + int new_x; + int new_y; + Evas_Object *obj = __safe_efl_cast(object); + evas_object_geometry_get(obj, &x, &y, &w, &h); + new_x = (w * xpercent); + new_x = div(new_x, 100).quot; + new_x += x; + + new_y = (h * ypercent); + new_y = div(new_y, 100).quot; + new_y += y; + evas_event_feed_mouse_move(evas_object_evas_get(obj), new_x, new_y, 0, NULL); + evas_event_feed_mouse_down(evas_object_evas_get(obj), 1, EVAS_BUTTON_NONE, 1, NULL); + evas_event_feed_mouse_up(evas_object_evas_get(obj), 1, EVAS_BUTTON_NONE, 2, NULL); +} + +/** + * @brief Emulate mouse click function + */ +static void __emulate_mouse_click(const Evas_Object *obj) +{ + __emulate_mouse_click_full(obj, 10, 75); + /* because items with two line style are clickable on: + - text only in first line + - the whole second line */ +} + +/* Button widget ----------------------------------------------------------- */ + +/** + * @brief Function that is activated on button action. + * @param[in] button object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __button_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + (void)data; + VC_ELM_LOG_DBG("button activator func"); + + if (!action_name || (0 == strcmp(action_name, _VC_ELM(CLICK)))) { + VC_ELM_LOG_INFO("clicking down %s (%p)", elm_widget_type_get(obj), (void*)obj); + __emulate_mouse_click(obj); + } else { + VC_ELM_LOG_INFO("bad action (%s) for %s", action_name, elm_widget_type_get(obj)); + } +} + +/** + * @brief Function that registers Evas_Object button from Elementary. + */ +static void __register_elm_button(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *button; + VC_ELM_LOG_INFO("Registering elm_button in vc_elm"); + button = _vc_elm_core_register_widget("Elm_Button", NULL, NULL, NULL); + if (NULL == button) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(button, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __button_activator_func); + } +} + +/** + * @brief Function that filter subwidgets voice command of vc_elm_item object. + * @param[in] vc_elm_item object + * @param[in] action string that was activated + */ +static Eina_Bool __item_filter_func(Evas_Object *obj, const char *text, void *user_data) +{ + (void)text; + (void)user_data; + + if (NULL == obj) + return EINA_TRUE; + return EINA_FALSE; +} + +/** + * @brief Function that registers Evas_Object vc_elm_item from Elementary. + */ +static void __register_vc_elm_item() +{ + struct vc_elm_core_widget_info *item; + VC_ELM_LOG_INFO("Registering vc_elm_supported_item in vc_elm"); + item = _vc_elm_core_register_widget("evc-item", NULL, __item_filter_func, NULL); + if (NULL == item) + return; + + _vc_elm_core_register_action(item, CLICK, NULL, __button_activator_func); +} + +/* Hoversel widget --------------------------------------------------------- */ +/** + * @brief Function that registers Evas_Object hoversel from Elementary. + */ +static void __register_elm_hoversel(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *hoversel; + VC_ELM_LOG_INFO("Registering elm_hoversel - in VC_ELM"); + hoversel = _vc_elm_core_register_widget("Elm_Hoversel", NULL, NULL, NULL); + if (NULL == hoversel) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(hoversel, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __button_activator_func); + } +} + +/* Gengrid widget ---------------------------------------------------------- */ +/** + * @brief Function that is activated on gengrid action. + * @param[in] gengrid object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __gengrid_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + (void)data; + + VC_ELM_LOG_INFO("activated gengrid with action %s", action_name); + if (!action_name) { + VC_ELM_LOG_WARN("no default action set for gengrid"); + } else if (elm_gengrid_horizontal_get(obj)) { + if (!strcmp(_VC_ELM(LEFT), action_name)) + __scroll_object(obj, LITTLE, HORIZONTAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(RIGHT), action_name)) + __scroll_object(obj, LITTLE, HORIZONTAL, TO_END); + else if (!strcmp(_VC_ELM(SCROLL_LEFT), action_name)) + __scroll_object(obj, MORE, HORIZONTAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(SCROLL_RIGHT), action_name)) + __scroll_object(obj, MORE, HORIZONTAL, TO_END); + else if (!strcmp(_VC_ELM(HOME), action_name)) + __scroll_object(obj, MAXIMAL, HORIZONTAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(END), action_name)) + __scroll_object(obj, MAXIMAL, HORIZONTAL, TO_END); + else + VC_ELM_LOG_WARN("unknown action"); + } else { + if (!strcmp(_VC_ELM(UP), action_name)) + __scroll_object(obj, LITTLE, VERTICAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(DOWN), action_name)) + __scroll_object(obj, LITTLE, VERTICAL, TO_END); + else if (!strcmp(_VC_ELM(SCROLL_UP), action_name)) + __scroll_object(obj, MORE, VERTICAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(SCROLL_DOWN), action_name)) + __scroll_object(obj, MORE, VERTICAL, TO_END); + else if (!strcmp(_VC_ELM(HOME), action_name)) + __scroll_object(obj, MAXIMAL, VERTICAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(END), action_name)) + __scroll_object(obj, MAXIMAL, VERTICAL, TO_END); + else + VC_ELM_LOG_WARN("unknown action"); + } +} + +Elm_Object_Item *__gengrid_filter_first_item_get(const Evas_Object *obj, void *user_data) +{ + (void)user_data; + return elm_gengrid_first_item_get(obj); +} + +Elm_Object_Item *__gengrid_filter_item_next_get(const Elm_Object_Item *it, void *user_data) +{ + (void)user_data; + return elm_gengrid_item_next_get(it); +} + +Elm_Object_Item *__gengrid_filter_last_item_get(const Evas_Object *obj, void *user_data) +{ + (void)user_data; + return elm_gengrid_last_item_get(obj); +} + +Elm_Object_Item *__gengrid_filter_item_prev_get(const Elm_Object_Item *it, void *user_data) +{ + (void)user_data; + return elm_gengrid_item_prev_get(it); +} + +/** + * @brief Function that filter subwidgets voice command of gengrid object. + * @param[in] gengrid object + * @param[in] action string that was activated + */ +static Eina_Bool __gengrid_filter_func(Evas_Object *obj, const char *action, void *user_data) +{ + int horizontal = elm_gengrid_horizontal_get(obj); + (void)user_data; + VC_ELM_LOG_DBG("filtering gengrid"); + if (NULL == action) /* NULL means whole object */ + { + Elm_Object_Item *first = __gengrid_filter_first_item_get(obj, NULL); + Elm_Object_Item *last = __gengrid_filter_last_item_get(obj, NULL); + Elm_Object_Item *first_visible = _vc_elm_core_get_visible_item(obj, __gengrid_filter_first_item_get, __gengrid_filter_item_next_get, NULL); + Elm_Object_Item *last_visible = _vc_elm_core_get_visible_item(obj, __gengrid_filter_last_item_get, __gengrid_filter_item_prev_get, NULL); + + if (first == first_visible && last == last_visible) { + VC_ELM_LOG_DBG("filtered out gengrid"); + return EINA_TRUE; + } + } else if (!strcmp(action, _VC_ELM(UP)) || !strcmp(action, _VC_ELM(DOWN)) || !strcmp(action, _VC_ELM(SCROLL_UP)) || !strcmp(action, _VC_ELM(SCROLL_DOWN))) { + if (horizontal) + return EINA_TRUE; + else + return EINA_FALSE; + } else if (!strcmp(action, _VC_ELM(LEFT)) || !strcmp(action, _VC_ELM(RIGHT)) || !strcmp(action, _VC_ELM(SCROLL_LEFT)) || !strcmp(action, _VC_ELM(SCROLL_RIGHT))) { + if (horizontal) + return EINA_FALSE; + else + return EINA_TRUE; + } + + return EINA_FALSE; +} + +/** + * @brief Function that registers Evas_Object gengrid from Elementary. + */ +static void __register_elm_gengrid(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *gengrid; + VC_ELM_LOG_INFO("Registering elm_gengrid in vc_elm"); + gengrid = _vc_elm_core_register_widget("Elm_Gengrid", NULL, __gengrid_filter_func, NULL); + + if (NULL == gengrid) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(gengrid, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __gengrid_activator_func); + } +} + +/* Genlist widget ---------------------------------------------------------- */ +/** + * @brief Function that is activated on genlist action. + * @param[in] genlist object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __genlist_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + (void)data; + VC_ELM_LOG_INFO("activated genlist with action %s", action_name); + + if (!action_name) + VC_ELM_LOG_WARN("no default action set for genlist"); + else if (!strcmp(_VC_ELM(UP), action_name)) + __scroll_object(obj, LITTLE, VERTICAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(DOWN), action_name)) + __scroll_object(obj, LITTLE, VERTICAL, TO_END); + else if (!strcmp(_VC_ELM(SCROLL_UP), action_name)) + __scroll_object(obj, MORE, VERTICAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(SCROLL_DOWN), action_name)) + __scroll_object(obj, MORE, VERTICAL, TO_END); + else if (!strcmp(_VC_ELM(HOME), action_name)) + __scroll_object(obj, MAXIMAL, VERTICAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(END), action_name)) + __scroll_object(obj, MAXIMAL, VERTICAL, TO_END); + else + VC_ELM_LOG_WARN("unknown action"); +} + +static Elm_Object_Item *__genlist_filter_first_item_get(const Evas_Object *obj, void *user_data) +{ + (void)user_data; + return elm_genlist_first_item_get(obj); +} + +static Elm_Object_Item *__genlist_filter_item_next_get(const Elm_Object_Item *it, void *user_data) +{ + (void)user_data; + return elm_genlist_item_next_get(it); +} + +static Elm_Object_Item *__genlist_filter_last_item_get(const Evas_Object *obj, void *user_data) +{ + (void)user_data; + return elm_genlist_last_item_get(obj); +} + +static Elm_Object_Item *__genlist_filter_item_prev_get(const Elm_Object_Item *it, void *user_data) +{ + (void)user_data; + return elm_genlist_item_prev_get(it); +} + +/** + * @brief Function that filter subwidgets voice command of genlist object. + * @param[in] genlist object + * @param[in] action string that was activated + */ +static Eina_Bool __genlist_filter_func(Evas_Object *obj, const char *action, void *user_data) +{ + Elm_Object_Item *first; + Elm_Object_Item *last; + Elm_Object_Item *first_visible; + Elm_Object_Item *last_visible; + (void)action; + (void)user_data; + + __set_toooltips_position_on_visible_items(obj, __genlist_filter_first_item_get, __genlist_filter_item_next_get, NULL); + + first = __genlist_filter_first_item_get(obj, NULL); + last = __genlist_filter_last_item_get(obj, NULL); + first_visible = _vc_elm_core_get_visible_item(obj, __genlist_filter_first_item_get, __genlist_filter_item_next_get, NULL); + + last_visible = _vc_elm_core_get_visible_item(obj, __genlist_filter_last_item_get, __genlist_filter_item_prev_get, NULL); + + VC_ELM_LOG_WARN("--%p %p--------%p %p--------", (void*)first, (void*)first_visible, (void*)last, (void*)last_visible); +#define MyDBG(name) \ + { \ + int x; \ + int y; \ + int w; \ + int h; \ + if (name) \ + { \ + evas_object_geometry_get(_vc_elm_core_get_evas_object(name), &x, &y, &w, &h); \ + VC_ELM_LOG_WARN("%s -> %d %d / %d %d", #name, x, y, w, h); \ + } \ + } + + MyDBG(first); + MyDBG(first_visible); + MyDBG(last); + MyDBG(last_visible); +#undef MyDBG + + if (first == first_visible && last == last_visible) { + VC_ELM_LOG_DBG("hiding genlist tooltip"); + return EINA_TRUE; + } + return EINA_FALSE; +} + +/** + * @brief Function that registers Evas_Object genlist from Elementary. + */ +static void __register_elm_genlist(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *genlist; + VC_ELM_LOG_INFO("Registering elm_genlist in vc_elm"); + genlist = _vc_elm_core_register_widget("Elm_Genlist", NULL, __genlist_filter_func, NULL); + + if (NULL == genlist) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(genlist, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __genlist_activator_func); + } +} + +/* radiobutton widget------------------------------------------------------- */ +/** + * @brief Function that registers Evas_Object radiobutton from Elementary. + */ +static void __register_elm_radiobutton(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *radiobutton; + VC_ELM_LOG_INFO("Registering elm_radiobutton in vc_elm"); + radiobutton = _vc_elm_core_register_widget("Elm_Radio", NULL, NULL, NULL); + + if (NULL == radiobutton) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(radiobutton, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __button_activator_func); + } +} + +/* bubble widget ----------------------------------------------------------- */ +/** + * @brief Function that is activated on bubble action. + * @param[in] bubble object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __bubble_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + (void)data; + if (!action_name || (0 == strcmp(action_name, _VC_ELM(CLICK)))) { + VC_ELM_LOG_INFO("Activated bubble with action %s", action_name); + evas_object_smart_callback_call(obj, "clicked", NULL); + } +} + +/** + * @brief Function that registers Evas_Object bubble from Elementary. + */ +static void __register_elm_bubble(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *bubble; + VC_ELM_LOG_INFO("Registering bubble in VC_ELM"); + bubble = _vc_elm_core_register_widget("Elm_Bubble", NULL, NULL, NULL); + if (NULL == bubble) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(bubble, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __bubble_activator_func); + } +} + +/* list widget ------------------------------------------------------------- */ +/** + * @brief Function that is activated on list action. + * @param[in] list object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __list_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + (void)data; + VC_ELM_LOG_INFO("Activated list with action %s", action_name); + + if (!action_name) + VC_ELM_LOG_WARN("No default action set for list"); + else if (!strcmp(_VC_ELM(UP), action_name)) + __scroll_object(obj, LITTLE, VERTICAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(DOWN), action_name)) + __scroll_object(obj, LITTLE, VERTICAL, TO_END); + else if (!strcmp(_VC_ELM(SCROLL_UP), action_name)) + __scroll_object(obj, MORE, VERTICAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(SCROLL_DOWN), action_name)) + __scroll_object(obj, MORE, VERTICAL, TO_END); + else if (!strcmp(_VC_ELM(HOME), action_name)) + __scroll_object(obj, MAXIMAL, VERTICAL, TO_BEGINNING); + else if (!strcmp(_VC_ELM(END), action_name)) + __scroll_object(obj, MAXIMAL, VERTICAL, TO_END); + else + VC_ELM_LOG_WARN("unknown action"); +} + +/** + * @brief Function found and set voice tooltips on list + */ +static void __set_toooltips_position_on_visible_items(Evas_Object *parent, Elm_Object_Item *(*get_first)(const Evas_Object *obj, void *user_data), Elm_Object_Item *(*get_next)(const Elm_Object_Item *item, void *user_data), void *user_data) +{ + Elm_Object_Item *item = get_first(parent, user_data); + vc_elm_direction_e direction = VC_ELM_DIRECTION_CENTER; + int x; + int y; + int w; + int h; + if (item == NULL) + return; + + _vc_elm_core_get_sub_item_hint_direction(parent, &direction); + + evas_object_geometry_get(parent, &x, &y, &w, &h); + do { + int x_1; + int y_1; + int w_1; + int h_1; + Evas_Object *obj = _vc_elm_core_get_evas_object(item); + if (!obj) + continue; + _vc_elm_core_set_sub_item_hint_direction(obj, direction); + evas_object_geometry_get(obj, &x_1, &y_1, &w_1, &h_1); + + if (x_1 + (w_1 / 2) >= x && y_1 + (h_1 / 2) >= y && (x_1 + (w_1 / 2)) <= (x + w) && (y_1 + (h_1 / 2)) <= (y + h)) { + const char *name = elm_widget_type_get(obj); + if (name == NULL) { + char *item_string = NULL; + if (NULL != (item_string = evas_object_data_get(obj, VC_ELM_HINT_DATA_KEY))) + _vc_elm_core_set_object_hint(obj, item_string); + else + continue; + } + } + } while ((item = get_next(item, user_data)) != NULL); + + return; +} + +Elm_Object_Item *__list_filter_first_item_get(const Evas_Object *obj, void *user_data) +{ + (void)user_data; + return elm_list_first_item_get(obj); +} + +Elm_Object_Item *list_filter_item_next_get(const Elm_Object_Item *it, void *user_data) +{ + (void)user_data; + return elm_list_item_next(it); +} + +Elm_Object_Item *list_filter_last_item_get(const Evas_Object *obj, void *user_data) +{ + (void)user_data; + return elm_list_last_item_get(obj); +} + +Elm_Object_Item *list_filter_item_prev_get(const Elm_Object_Item *it, void *user_data) +{ + (void)user_data; + return elm_list_item_prev(it); +} + +/** + * @brief Function that filter subwidgets voice command of filter object. + * @param[in] filter object + * @param[in] action string that was activated + */ +static Eina_Bool __list_filter_func(Evas_Object *obj, const char *action, void *user_data) +{ + Elm_Object_Item *first; + Elm_Object_Item *last; + Elm_Object_Item *first_visible; + Elm_Object_Item *last_visible; + (void)action; + (void)user_data; + + __set_toooltips_position_on_visible_items(obj, __list_filter_first_item_get, list_filter_item_next_get, NULL); + first = __list_filter_first_item_get(obj, NULL); + last = list_filter_last_item_get(obj, NULL); + first_visible = _vc_elm_core_get_visible_item(obj, __list_filter_first_item_get, list_filter_item_next_get, NULL); + last_visible = _vc_elm_core_get_visible_item(obj, list_filter_last_item_get, list_filter_item_prev_get, NULL); + if (first == first_visible && last == last_visible) { + VC_ELM_LOG_DBG("hiding list tooltip"); + return EINA_TRUE; + } + return EINA_FALSE; +} + +/** + * @brief Function that registers Evas_Object list from Elementary. + */ +static void __register_elm_list(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *list; + VC_ELM_LOG_DBG("Registering list in vc_elm"); + list = _vc_elm_core_register_widget("Elm_List", NULL, __list_filter_func, NULL); + + if (NULL == list) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(list, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __list_activator_func); + } +} + +/* slider ------------------------------------------------------------------ */ +/** + * @brief Function that is activated on slider action. + * @param[in] slider object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __slider_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + /* separated horizontal and vertical slider */ + + double new_value; + double min; + double max; + double value = elm_slider_value_get(obj); + Eina_Bool horizontal = elm_slider_horizontal_get(obj); + (void)data; + + elm_slider_min_max_get(obj, &min, &max); + + VC_ELM_LOG_INFO("Activated slider with action %s", action_name); + + if (action_name == NULL) { + VC_ELM_LOG_WARN("Action is null. Doing nothing."); + } else if (horizontal == EINA_TRUE && !strcmp(action_name, _VC_ELM(LEFT))) { + new_value = value - 0.1 * (max - min); + if (new_value <= min) + elm_slider_value_set(obj, min); + else + elm_slider_value_set(obj, new_value); + + VC_ELM_LOG_INFO("Slider: left"); + } else if (horizontal == EINA_TRUE && !strcmp(action_name, _VC_ELM(RIGHT))) { + new_value = value + 0.1 * (max - min); + if (new_value >= max) + elm_slider_value_set(obj, max); + else + elm_slider_value_set(obj, new_value); + + VC_ELM_LOG_INFO("Slider: right"); + } else if (horizontal == EINA_TRUE && !strcmp(action_name, _VC_ELM(SCROLL_LEFT))) { + new_value = value - 0.2 * (max - min); + if (new_value <= min) + elm_slider_value_set(obj, min); + else + elm_slider_value_set(obj, new_value); + + VC_ELM_LOG_INFO("Slider: scroll left"); + } else if (horizontal == EINA_TRUE && !strcmp(action_name, _VC_ELM(SCROLL_RIGHT))) { + new_value = value + 0.2 * (max - min); + if (new_value >= max) + elm_slider_value_set(obj, max); + else + elm_slider_value_set(obj, new_value); + + VC_ELM_LOG_INFO("Slider: scroll right"); + } else if (horizontal == EINA_FALSE && !strcmp(action_name, _VC_ELM(UP))) { + new_value = value - 0.1 * (max - min); + if (new_value <= min) + elm_slider_value_set(obj, min); + else + elm_slider_value_set(obj, new_value); + + VC_ELM_LOG_INFO("Slider: up"); + } else if (horizontal == EINA_FALSE && !strcmp(action_name, _VC_ELM(DOWN))) { + new_value = value + 0.1 * (max - min); + if (new_value >= max) + elm_slider_value_set(obj, max); + else + elm_slider_value_set(obj, new_value); + + VC_ELM_LOG_INFO("Slider: down"); + } else if (horizontal == EINA_FALSE && !strcmp(action_name, _VC_ELM(SCROLL_UP))) { + new_value = value - 0.2 * (max - min); + if (new_value <= min) + elm_slider_value_set(obj, min); + else + elm_slider_value_set(obj, new_value); + + VC_ELM_LOG_INFO("Slider: scroll up"); + } else if (horizontal == EINA_FALSE && !strcmp(action_name, _VC_ELM(SCROLL_DOWN))) { + new_value = value + 0.2 * (max - min); + if (new_value >= max) + elm_slider_value_set(obj, max); + else + elm_slider_value_set(obj, new_value); + + VC_ELM_LOG_INFO("Slider: scroll down"); + } else if (!strcmp(action_name, _VC_ELM(HOME))) { + elm_slider_value_set(obj, min); + + VC_ELM_LOG_INFO("Slider: home"); + } else if (!strcmp(action_name, _VC_ELM(END))) { + elm_slider_value_set(obj, max); + + VC_ELM_LOG_INFO("Slider: end"); + } else if (!strcmp(action_name, _VC_ELM(CENTER))) { + elm_slider_value_set(obj, 0.5 * (max - min)); + + VC_ELM_LOG_INFO("Slider: center"); + } else { + VC_ELM_LOG_WARN("unknown action"); + } +} + +/** + * @brief Function that filter subwidgets voice command of slider object. + * @param[in] slider object + * @param[in] action string that was activated + */ +static Eina_Bool __slider_cmd_filter_func(Evas_Object *obj, const char *text, void *user_data) +{ + Eina_Bool horizontal = elm_slider_horizontal_get(obj); + (void)user_data; + + if (text == NULL) + return EINA_FALSE; + + if (!strcmp(text, _VC_ELM(LEFT)) || !strcmp(text, _VC_ELM(RIGHT)) || !strcmp(text, _VC_ELM(SCROLL_LEFT)) || !strcmp(text, _VC_ELM(SCROLL_RIGHT)) || !strcmp(text, _VC_ELM(HOME)) || !strcmp(text, _VC_ELM(END)) || !strcmp(text, _VC_ELM(CENTER))) { + if (horizontal) + return EINA_FALSE; + } + if (!strcmp(text, _VC_ELM(UP)) || !strcmp(text, _VC_ELM(DOWN)) || !strcmp(text, _VC_ELM(SCROLL_UP)) || !strcmp(text, _VC_ELM(SCROLL_DOWN)) || !strcmp(text, _VC_ELM(HOME)) || !strcmp(text, _VC_ELM(END)) || !strcmp(text, _VC_ELM(CENTER))) { + if (!horizontal) + return EINA_FALSE; + } + + return EINA_TRUE; +} + +/** + * @brief Function that registers Evas_Object spinner from Elementary. + */ +static void __register_elm_slider(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *slider; + VC_ELM_LOG_INFO("Registering slider in VC_ELM"); + slider = _vc_elm_core_register_widget("Elm_Slider", NULL, __slider_cmd_filter_func, NULL); + + if (NULL == slider) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(slider, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __slider_activator_func); + } +} + +/* colorselector widget -----------------------------------------------------*/ + +static const char VC_ELM_COLORSELECTOR_PARENT[] = "vc_elm_colorselector_parent"; + +static Evas_Object *swallowedH; +static Evas_Object *swallowedS; +static Evas_Object *swallowedV; + +/** + * @brief Function that registers voice command for colorselector object. + * @param[in] colorselector object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __colorselector_hue_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + (void)obj; + (void)data; + + if (!action_name || !strcmp(action_name, _VC_ELM(LEFT))) { + edje_object_part_drag_step(swallowedH, "elm.arrow", -0.01, 0); + edje_object_signal_emit(swallowedH, "drag", "*"); + } else if (!strcmp(action_name, _VC_ELM(RIGHT))) { + edje_object_part_drag_step(swallowedH, "elm.arrow", 0.01, 0); + edje_object_signal_emit(swallowedH, "drag", "*"); + } else if (!strcmp(action_name, _VC_ELM(SCROLL_LEFT))) { + edje_object_part_drag_step(swallowedH, "elm.arrow", -0.05, 0); + edje_object_signal_emit(swallowedH, "drag", "*"); + } else if (!strcmp(action_name, _VC_ELM(SCROLL_RIGHT))) { + edje_object_part_drag_step(swallowedH, "elm.arrow", 0.05, 0); + edje_object_signal_emit(swallowedH, "drag", "*"); + } else { + VC_ELM_LOG_WARN("unknown action"); + return; + } +} + +/** + * @brief Function that registers voice command for sat. colorselector object. + * @param[in] colorselector object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __colorselector_saturation_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + (void)obj; + (void)data; + + if (!action_name || !strcmp(action_name, _VC_ELM(RIGHT))) { + edje_object_part_drag_step(swallowedS, "elm.arrow", 0.01, 0); + edje_object_signal_emit(swallowedS, "drag", "*"); + } else if (!strcmp(action_name, _VC_ELM(LEFT))) { + edje_object_part_drag_step(swallowedS, "elm.arrow", -0.01, 0); + edje_object_signal_emit(swallowedS, "drag", "*"); + } else if (!strcmp(action_name, _VC_ELM(SCROLL_RIGHT))) { + edje_object_part_drag_step(swallowedS, "elm.arrow", 0.05, 0); + edje_object_signal_emit(swallowedS, "drag", "*"); + } else if (!strcmp(action_name, _VC_ELM(SCROLL_LEFT))) { + edje_object_part_drag_step(swallowedS, "elm.arrow", -0.05, 0); + edje_object_signal_emit(swallowedS, "drag", "*"); + } else { + VC_ELM_LOG_WARN("unknown action"); + return; + } +} + +/** + * @brief Function that registers voice command for value colorselector object. + * @param[in] colorselector object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __colorselector_value_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + (void)obj; + (void)data; + + if (!action_name || !strcmp(action_name, _VC_ELM(LEFT))) { + edje_object_part_drag_step(swallowedV, "elm.arrow", -0.01, 0); + edje_object_signal_emit(swallowedV, "drag", "*"); + } else if (!strcmp(action_name, _VC_ELM(RIGHT))) { + edje_object_part_drag_step(swallowedV, "elm.arrow", 0.01, 0); + edje_object_signal_emit(swallowedV, "drag", "*"); + } else if (!strcmp(action_name, _VC_ELM(SCROLL_LEFT))) { + edje_object_part_drag_step(swallowedV, "elm.arrow", -0.05, 0); + edje_object_signal_emit(swallowedV, "drag", "*"); + } else if (!strcmp(action_name, _VC_ELM(SCROLL_RIGHT))) { + edje_object_part_drag_step(swallowedV, "elm.arrow", 0.05, 0); + edje_object_signal_emit(swallowedV, "drag", "*"); + } else { + VC_ELM_LOG_WARN("unknown action"); + return; + } +} + +/** + * @brief Function that analyse layout for color objects. + */ +static void __sub_layout_inspect(Eina_List *ret, Evas_Object *widget) +{ + /*Temporary fix for pallete without tooltips*/ + const char *colors[] = + {"pink", "violet", "purple", "navy", "blue", "cyan", "green", "lime", "yellow", "red"}; + const Eina_List *l = NULL; + Evas_Object *obj = NULL; + const Eina_List *list = elm_widget_can_focus_child_list_get(widget); + int i = 0; + + (void)ret; + (void)widget; + + EINA_LIST_FOREACH(list, l, obj) { + const char *type = elm_widget_type_get(obj); + if (type && !strcmp(type, "Elm_Layout")) { + evas_object_data_set(obj, VC_ELM_COLORSELECTOR_PARENT, widget); + evas_object_data_set(obj, _vc_elm_get_custom_widget_name(), "Elm_Button"); + ret = eina_list_append(ret, obj); + if (i < 10) + _vc_elm_set_object_hint(obj, colors[i++]); + } + } +} + +const char HUE[] = "IDS_HUE"; +const char SATURATION[] = "IDS_SATURATION"; +const char LIGHTNESS[] = "IDS_LIGHTNESS"; +/** + * @brief Function that registers voice command for colorselector object. + * @param[in] colorselector object + */ +static Eina_List *__colorselector_get_subwidgets(const Evas_Object *colorselector, void *user_data) +{ + Eina_List *ret = NULL; + Evas_Object *edje = elm_layout_content_get(colorselector, "selector"); + (void)user_data; + + swallowedH = edje_object_part_swallow_get(edje, "elm.colorbar_0"); + evas_object_data_set(swallowedH, _vc_elm_get_custom_widget_name(), "simple_hue_colorbar_activator"); + evas_object_data_set(swallowedH, VC_ELM_COLORSELECTOR_PARENT, colorselector); + + _vc_elm_core_set_object_command(swallowedH, _VC_ELM(HUE)); + _vc_elm_core_set_object_hint(swallowedH, _VC_ELM(HUE)); + ret = eina_list_append(ret, swallowedH); + + swallowedS = edje_object_part_swallow_get(edje, "elm.colorbar_1"); + evas_object_data_set(swallowedS, _vc_elm_get_custom_widget_name(), "simple_saturation_colorbar_activator"); + evas_object_data_set(swallowedS, VC_ELM_COLORSELECTOR_PARENT, colorselector); + _vc_elm_core_set_object_command(swallowedS, _VC_ELM(SATURATION)); + _vc_elm_core_set_object_hint(swallowedS, _VC_ELM(SATURATION)); + ret = eina_list_append(ret, swallowedS); + + swallowedV = edje_object_part_swallow_get(edje, "elm.colorbar_2"); + evas_object_data_set(swallowedV, _vc_elm_get_custom_widget_name(), "simple_value_colorbar_activator"); + evas_object_data_set(swallowedV, VC_ELM_COLORSELECTOR_PARENT, colorselector); + _vc_elm_core_set_object_command(swallowedV, _VC_ELM(LIGHTNESS)); + _vc_elm_core_set_object_hint(swallowedV, _VC_ELM(LIGHTNESS)); + ret = eina_list_append(ret, swallowedV); + + /*Palette*/ + edje = elm_layout_content_get(colorselector, "palette"); + __sub_layout_inspect(ret, edje); + return ret; +} + +/** + * @brief Function that registers Evas_Object hue_colorselector from Elementary. + */ +static void __register_elm_simple_hue_colorselector_activator(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *colorbar; + VC_ELM_LOG_INFO("Registering simple_hue_colorselector_activator in VC_ELM"); + colorbar = _vc_elm_core_register_widget("simple_hue_colorbar_activator", NULL, NULL, NULL); + + if (NULL == colorbar) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(colorbar, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __colorselector_hue_activator_func); + } +} + +/** + * @brief Function that registers Evas_Object saturation colorselector + * from Elementary. + */ +static void __register_elm_simple_saturation_colorselector_activator(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *colorbar; + VC_ELM_LOG_INFO("Registering simple_saturation_colorselector_activator in VC_ELM"); + colorbar = _vc_elm_core_register_widget("simple_saturation_colorbar_activator", NULL, NULL, NULL); + + if (NULL == colorbar) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(colorbar, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __colorselector_saturation_activator_func); + } +} + +/** + * @brief Function that registers Evas_Object value colorselector + * from Elementary. + */ +static void __register_elm_simple_value_colorselector_activator(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *colorbar; + VC_ELM_LOG_INFO("Registering simple_value_colorselector_activator in VC_ELM"); + colorbar = _vc_elm_core_register_widget("simple_value_colorbar_activator", NULL, NULL, NULL); + + if (NULL == colorbar) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(colorbar, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __colorselector_value_activator_func); + } +} + +/** + * @brief Function that registers Evas_Object colorselector from Elementary. + */ +static void __register_elm_colorselector(Eina_List *actions) +{ + (void)actions; + VC_ELM_LOG_INFO("Registering colorselector in VC_ELM"); + _vc_elm_core_register_widget("elm_colorselector", &__colorselector_get_subwidgets, NULL, NULL); +} + +/* Spinner ----------------------------------------------------------------- */ +/** + * @brief Function that is activated on spinner action. + * @param[in] spinner object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __spinner_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + Eina_Bool vertical = EINA_FALSE; + double min; + double max; + double step; + double value; + const char *style = elm_object_style_get(obj); + (void)data; + + if (style && (0 == strcmp(style, "vertical") || 0 == strcmp(style, "default"))) + vertical = EINA_TRUE; + + elm_spinner_min_max_get(obj, &min, &max); + value = elm_spinner_value_get(obj); + step = elm_spinner_step_get(obj); + + VC_ELM_LOG_INFO("activated spinner with action %s", action_name); + if (!action_name) { + VC_ELM_LOG_WARN("no default action set for spinner"); + return; + } else if ((!vertical && !strcmp(action_name, _VC_ELM(LEFT))) || (vertical && !strcmp(action_name, _VC_ELM(DOWN)))) { + value = value - step; + /* we don't need to handle min/max and wrap cases, + * spinner will do it automatically */ + elm_spinner_value_set(obj, value); + } else if ((!vertical && !strcmp(action_name, _VC_ELM(RIGHT))) || (vertical && !strcmp(action_name, _VC_ELM(UP)))) { + value = value + step; + elm_spinner_value_set(obj, value); + /* we don't need to handle min/max and wrap cases, + * spinner will do it automatically */ + } else if (!strcmp(action_name, _VC_ELM(HOME))) { + elm_spinner_value_set(obj, min); + + VC_ELM_LOG_INFO("Spinner: home"); + } else if (!strcmp(action_name, _VC_ELM(END))) { + elm_spinner_value_set(obj, max); + + VC_ELM_LOG_INFO("Spinner: end"); + } else { + VC_ELM_LOG_WARN("unknown action"); + return; + } +} + +/** + * @brief Function that filter subwidgets voice command of spinner object. + * @param[in] spinner object + * @param[in] action string that was activated + */ +static Eina_Bool __spinner_cmd_filter_func(Evas_Object *obj, const char *action_name, void *user_data) +{ + Eina_Bool vertical = EINA_FALSE; + const char *style = elm_object_style_get(obj); + (void)user_data; + + if (style && (0 == strcmp(style, "vertical") || 0 == strcmp(style, "default"))) + vertical = EINA_TRUE; + + if ((!action_name) || (!strcmp(action_name, _VC_ELM(HOME))) || (!strcmp(action_name, _VC_ELM(END)))) + return EINA_FALSE; + else if ((!vertical && !strcmp(action_name, _VC_ELM(LEFT))) || (vertical && !strcmp(action_name, _VC_ELM(DOWN)))) + return EINA_FALSE; + else if ((!vertical && !strcmp(action_name, _VC_ELM(RIGHT))) || (vertical && !strcmp(action_name, _VC_ELM(UP)))) + return EINA_FALSE; + return EINA_TRUE; +} + +/** + * @brief Function that registers Evas_Object spinner from Elementary. + */ +static void __register_elm_spinner(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *spinner; + VC_ELM_LOG_INFO("Registering photocam in VC_ELM"); + spinner = _vc_elm_core_register_widget("Elm_Spinner", NULL, __spinner_cmd_filter_func, NULL); + + if (NULL == spinner) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(spinner, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __spinner_activator_func); + } +} + +/* entry widget ------------------------------------------------------------ */ +/** + * @brief Function that filter subwidgets voice command of entry object. + * @param[in] entry object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __entry_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + (void)data; + + if (!action_name || 0 == strcmp(_VC_ELM(CLICK), action_name)) { + __emulate_mouse_click(obj); + elm_entry_select_all(obj); + elm_entry_select_none(obj); + elm_entry_input_panel_show(obj); + } else if (elm_entry_scrollable_get(obj)) { + if (!strcmp(_VC_ELM(UP), action_name)) + __scroll_object(obj, LESS, VERTICAL, TO_BEGINNING); + if (!strcmp(_VC_ELM(DOWN), action_name)) + __scroll_object(obj, LESS, VERTICAL, TO_END); + if (!strcmp(_VC_ELM(SCROLL_UP), action_name)) + __scroll_object(obj, LITTLE, VERTICAL, TO_BEGINNING); + if (!strcmp(_VC_ELM(SCROLL_DOWN), action_name)) + __scroll_object(obj, LITTLE, VERTICAL, TO_END); + } else { + VC_ELM_LOG_ERR("not supported"); + } +} + +static Eina_Bool __entry_cmd_filter_func(Evas_Object *obj, const char *action_name, void *user_data) +{ + Eina_Bool scrollable = EINA_FALSE; + Eina_Bool single_line = EINA_FALSE; + const char *text; + + (void)user_data; + + scrollable = elm_entry_scrollable_get(obj); + text = elm_entry_entry_get(obj); + single_line = elm_entry_single_line_get(obj); + + if (text && scrollable == EINA_TRUE && single_line == EINA_FALSE) { + if (!strcmp(action_name, _VC_ELM(UP)) || !strcmp(action_name, _VC_ELM(DOWN)) || !strcmp(action_name, _VC_ELM(SCROLL_UP)) || !strcmp(action_name, _VC_ELM(SCROLL_UP))) + return EINA_FALSE; + } + + if (!strcmp(action_name, _VC_ELM(CLICK))) + return EINA_FALSE; + + return EINA_TRUE; +} + +/** + * @brief Function that registers Evas_Object entry from Elementary. + */ +static void __register_elm_entry(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *entry; + VC_ELM_LOG_INFO("Registering entry in VC_ELM"); + + entry = _vc_elm_core_register_widget("Elm_Entry", NULL, __entry_cmd_filter_func, NULL); + + if (NULL == entry) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(entry, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __entry_activator_func); + } +} + +/* multibuttonentry widget ------------------------------------------------- */ +/** + * @brief Function that registers subwidgets voice command of multibuttonentry object. + * @param[in] multibuttonentry object + */ +static Eina_List *__entry_get_subwidgets(const Evas_Object *entry, void *user_data) +{ + Eina_List *ret = NULL; + const Eina_List *l = NULL; + Evas_Object *obj = NULL; + const Eina_List *list = NULL; + (void)user_data; + entry = elm_layout_content_get(entry, "box.swallow"); + list = elm_widget_can_focus_child_list_get(entry); + + EINA_LIST_FOREACH(list, l, obj) { + const char *type = elm_widget_type_get(obj); + const char *part = elm_object_part_text_get(obj, "mbe.label"); + if (part) + continue; + if (type && !strcmp(type, "Elm_Layout")) { + evas_object_data_set(obj, VC_ELM_COLORSELECTOR_PARENT, entry); + evas_object_data_set(obj, _vc_elm_get_custom_widget_name(), "Elm_Button"); + ret = eina_list_append(ret, obj); + } else if (type && !strcmp(type, "Elm_Entry")) { + ret = eina_list_append(ret, obj); + } + } + return ret; +} + +/** + * @brief Function that registers Evas_Object multibuttonentry from Elementary. + */ +static void __register_elm_multibuttonentry(Eina_List *actions) +{ + (void)actions; + VC_ELM_LOG_INFO("Registering entry in VC_ELM"); + + _vc_elm_core_register_widget("Elm_Multibuttonentry", __entry_get_subwidgets, NULL, NULL); +} + +/* toolbar widget ----------------------------------------------------------*/ + +static Elm_Object_Item *__toolbar_filter_first_item_get(const Evas_Object *obj, void *user_data) +{ + (void)user_data; + return elm_toolbar_first_item_get(obj); +} + +static Elm_Object_Item *__toolbar_filter_item_next_get(const Elm_Object_Item *it, void *user_data) +{ + (void)user_data; + return elm_toolbar_item_next_get(it); +} + +static Elm_Object_Item *__toolbar_filter_last_item_get(const Evas_Object *obj, void *user_data) +{ + (void)user_data; + return elm_toolbar_last_item_get(obj); +} + +static Elm_Object_Item *__toolbar_filter_item_prev_get(const Elm_Object_Item *it, void *user_data) +{ + (void)user_data; + return elm_toolbar_item_prev_get(it); +} + +/** + * @brief Function that is activated on toolbar action. + * @param[in] toolbar object + * @param[in] user data + * @param[in] action string that was activated + */ +static void __toolbar_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + Elm_Object_Item *item_first; + Elm_Object_Item *item_last; + Elm_Object_Item *first_visible_item; + Elm_Object_Item *last_visible_item; + (void)data; + + item_first = __toolbar_filter_first_item_get(obj, NULL); + item_last = __toolbar_filter_last_item_get(obj, NULL); + + first_visible_item = _vc_elm_core_get_visible_item(obj, __toolbar_filter_first_item_get, __toolbar_filter_item_next_get, NULL); + last_visible_item = _vc_elm_core_get_visible_item(obj, __toolbar_filter_last_item_get, __toolbar_filter_item_prev_get, NULL); + + if (!action_name) { + VC_ELM_LOG_WARN("No default action set for toolbar"); + return; + } else if (!strcmp(_VC_ELM(HOME), action_name)) { + elm_toolbar_item_bring_in(item_first, ELM_TOOLBAR_ITEM_SCROLLTO_IN); + } else if (!strcmp(_VC_ELM(END), action_name)) { + elm_toolbar_item_bring_in(item_last, ELM_TOOLBAR_ITEM_SCROLLTO_IN); + } else if (elm_toolbar_horizontal_get(obj) == EINA_TRUE) { + if (!strcmp(_VC_ELM(RIGHT), action_name)) + elm_toolbar_item_bring_in(elm_toolbar_item_next_get(last_visible_item), ELM_TOOLBAR_ITEM_SCROLLTO_IN); + else if (!strcmp(_VC_ELM(SCROLL_RIGHT), action_name)) + elm_toolbar_item_bring_in(elm_toolbar_item_next_get(last_visible_item), ELM_TOOLBAR_ITEM_SCROLLTO_FIRST); + else if (!strcmp(_VC_ELM(LEFT), action_name)) + elm_toolbar_item_bring_in(elm_toolbar_item_prev_get(first_visible_item), ELM_TOOLBAR_ITEM_SCROLLTO_IN); + else if (!strcmp(_VC_ELM(SCROLL_LEFT), action_name)) + elm_toolbar_item_bring_in(elm_toolbar_item_prev_get(first_visible_item), ELM_TOOLBAR_ITEM_SCROLLTO_LAST); + } else if (elm_toolbar_horizontal_get(obj) == EINA_FALSE) { + if (!strcmp(_VC_ELM(DOWN), action_name)) + elm_toolbar_item_bring_in(elm_toolbar_item_next_get(last_visible_item), ELM_TOOLBAR_ITEM_SCROLLTO_IN); + else if (!strcmp(_VC_ELM(SCROLL_DOWN), action_name)) + elm_toolbar_item_bring_in(elm_toolbar_item_next_get(last_visible_item), ELM_TOOLBAR_ITEM_SCROLLTO_MIDDLE); + else if (!strcmp(_VC_ELM(UP), action_name)) + elm_toolbar_item_bring_in(elm_toolbar_item_prev_get(first_visible_item), ELM_TOOLBAR_ITEM_SCROLLTO_IN); + else if (!strcmp(_VC_ELM(SCROLL_UP), action_name)) + elm_toolbar_item_bring_in(elm_toolbar_item_prev_get(first_visible_item), ELM_TOOLBAR_ITEM_SCROLLTO_MIDDLE); + } else { + VC_ELM_LOG_ERR("not supported"); + } +} + +/** + * @brief Function that filter subwidgets voice command of toolbar object. + * @param[in] toolbar object + * @param[in] action string that was activated + */ +static Eina_Bool __toolbar_cmd_filter_func(Evas_Object *obj, const char *action_name, void *user_data) +{ + Eina_Bool horizontal = elm_toolbar_horizontal_get(obj); + (void)user_data; + + { + Elm_Object_Item *first = __toolbar_filter_first_item_get(obj, NULL); + Elm_Object_Item *last = __toolbar_filter_last_item_get(obj, NULL); + Elm_Object_Item *first_visible = _vc_elm_core_get_visible_item(obj, __toolbar_filter_first_item_get, __toolbar_filter_item_next_get, NULL); + Elm_Object_Item *last_visible = _vc_elm_core_get_visible_item(obj, __toolbar_filter_last_item_get, __toolbar_filter_item_prev_get, NULL); + if (first == first_visible && last == last_visible) { + VC_ELM_LOG_DBG("filtered out toolbar"); + return EINA_TRUE; + } + } + + if (!action_name) + return EINA_TRUE; + else if (!strcmp(_VC_ELM(HOME), action_name) || !strcmp(_VC_ELM(END), action_name)) + return EINA_FALSE; + else if ((horizontal) && (!strcmp(_VC_ELM(RIGHT), action_name) || !strcmp(_VC_ELM(LEFT), action_name) || !strcmp(_VC_ELM(SCROLL_RIGHT), action_name) || !strcmp(_VC_ELM(SCROLL_LEFT), action_name))) + return EINA_FALSE; + else if ((!horizontal) && (!strcmp(_VC_ELM(UP), action_name) || !strcmp(_VC_ELM(DOWN), action_name) || !strcmp(_VC_ELM(SCROLL_UP), action_name) || !strcmp(_VC_ELM(SCROLL_DOWN), action_name))) + return EINA_FALSE; + VC_ELM_LOG_DBG("filtered out %s action", action_name); + return EINA_TRUE; +} + +/** + * @brief Function that registers Evas_Object toolbar from Elementary. + */ +static void __register_elm_toolbar(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *toolbar; + VC_ELM_LOG_INFO("Registering toolbar in VC_ELM"); + toolbar = _vc_elm_core_register_widget("Elm_Toolbar", NULL, __toolbar_cmd_filter_func, NULL); + + if (NULL == toolbar) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(toolbar, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __toolbar_activator_func); + } +} + +/* checkbox widget ----------------------------------------------------------*/ +/** + * @brief Function that registers Evas_Object checkbox from Elementary. + */ +static void __register_elm_checkbox(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *checkbox; + VC_ELM_LOG_INFO("Registering elm_checkbox in VC_ELM"); + checkbox = _vc_elm_core_register_widget("Elm_Check", NULL, NULL, NULL); + + if (NULL == checkbox) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(checkbox, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, __button_activator_func); + } +} + +/* panes widget -------------------------------------------------------------- */ +/** + * @brief Function that filter subwidgets voice command of panes object. + * @param[in] panes object + * @param[in] action string that was activated + */ +static Eina_Bool panes_cmd_filter_func(Evas_Object *obj, const char *action_name, void *user_data) +{ + Eina_Bool horizontal = elm_panes_horizontal_get(obj); + double percentage = elm_panes_content_left_size_get(obj); + int x; + int y; + int w; + int h; + char *image_path = evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_HINT_IMAGE_PATH)); + (void)user_data; + + if (!action_name) { + VC_ELM_LOG_WARN("No default function for panes"); + return EINA_TRUE; + } + evas_object_geometry_get(obj, &x, &y, &w, &h); + + if (EINA_TRUE == horizontal) + _vc_elm_set_object_custom_hint(obj, image_path, (int)((1.0 * w * 0.5)), (int)((1.0 * h * percentage))); + else + _vc_elm_set_object_custom_hint(obj, image_path, (int)((1.0 * w * percentage)), (int)((1.0 * h * 0.5))); + + if (elm_panes_fixed_get(obj)) + return EINA_FALSE; + if ((horizontal) && (!strcmp(_VC_ELM(UP), action_name) || !strcmp(_VC_ELM(DOWN), action_name))) + return EINA_FALSE; + if ((!horizontal) && (!strcmp(_VC_ELM(LEFT), action_name) || !strcmp(_VC_ELM(RIGHT), action_name))) + return EINA_FALSE; + VC_ELM_LOG_INFO("Panes actions filtered"); + return EINA_TRUE; +} + +/** + * @brief Function that is activated on panes action. + * @param[in] panes object + * @param[in] user data + * @param[in] action string that was activated + */ +static void panes_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + double left_size; + double right_size; + (void)data; + + left_size = elm_panes_content_left_size_get(obj); + right_size = elm_panes_content_right_size_get(obj); + + if (!strcmp(_VC_ELM(UP), action_name)) + elm_panes_content_left_size_set(obj, left_size - 0.1); + else if (!strcmp(_VC_ELM(DOWN), action_name)) + elm_panes_content_right_size_set(obj, right_size - 0.1); + else if (!strcmp(_VC_ELM(LEFT), action_name)) + elm_panes_content_left_size_set(obj, left_size - 0.1); + else if (!strcmp(_VC_ELM(RIGHT), action_name)) + elm_panes_content_right_size_set(obj, right_size - 0.1); +} + +/** + * @brief Function that registers Evas_Object panes from Elementary. + */ +static void __register_elm_panes(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *panes; + VC_ELM_LOG_INFO("Registering panes in VC_ELM"); + panes = _vc_elm_core_register_widget("Elm_Panes", NULL, panes_cmd_filter_func, NULL); + + if (NULL == panes) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(panes, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, panes_activator_func); + } +} + +/* Scroller widget ---------------------------------------------------------*/ + +static void scroller_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + int h_pagelast; + int v_pagelast; + int h_currentpage; + int v_currentpage; + int max_w; + int max_h; + Evas_Coord pagewidth; + Evas_Coord pageheight; + Evas_Coord current_x; + Evas_Coord current_y; + Evas_Coord current_w; + Evas_Coord current_h; + double h_pagerel; + double v_pagerel; + (void)data; + + elm_scroller_last_page_get(obj, &h_pagelast, &v_pagelast); + elm_scroller_page_size_get(obj, &pagewidth, &pageheight); + elm_scroller_region_get(obj, ¤t_x, ¤t_y, ¤t_w, ¤t_h); + elm_scroller_page_relative_get(obj, &h_pagerel, &v_pagerel); + elm_scroller_current_page_get(obj, &h_currentpage, &v_currentpage); + elm_scroller_child_size_get(obj, &max_w, &max_h); + + if (!strcmp(_VC_ELM(HOME), action_name)) { + elm_scroller_region_show(obj, 0, 0, current_w, current_h); + } else if (!strcmp(_VC_ELM(END), action_name)) { + elm_scroller_region_show(obj, max_w, max_h, current_w, current_h); + } else if (!strcmp(_VC_ELM(UP), action_name)) { + if (v_pagerel > 0) + elm_scroller_page_show(obj, h_currentpage, v_currentpage - 1); + else + elm_scroller_region_show(obj, current_x, current_y - current_h, current_w, current_h); + } else if (!strcmp(_VC_ELM(DOWN), action_name)) { + if (v_pagerel > 0) + elm_scroller_page_show(obj, h_currentpage, v_currentpage + 1); + else + elm_scroller_region_show(obj, current_x, current_y + current_h, current_w, current_h); + } else if (!strcmp(_VC_ELM(LEFT), action_name)) { + if (h_pagerel > 0) + elm_scroller_page_show(obj, h_currentpage - 1, v_currentpage); + else + elm_scroller_region_show(obj, current_x - current_w, current_y, current_w, current_h); + } else if (!strcmp(_VC_ELM(RIGHT), action_name)) { + if (h_pagerel > 0) + elm_scroller_page_show(obj, h_currentpage + 1, v_currentpage); + else + elm_scroller_region_show(obj, current_x + current_w, current_y, current_w, current_h); + } +} + +static Eina_Bool scroller_filter_func(Evas_Object *obj, const char *text, void *user_data) +{ + Eina_Bool lock_x; + Eina_Bool lock_y; + + (void)user_data; + + lock_x = elm_object_scroll_lock_x_get(obj); + lock_y = elm_object_scroll_lock_y_get(obj); + + if (lock_x) { + if (!strcmp(_VC_ELM(RIGHT), text) || !strcmp(_VC_ELM(LEFT), text)) + return EINA_TRUE; + } + + if (lock_y) { + if (!strcmp(_VC_ELM(UP), text) || !strcmp(_VC_ELM(DOWN), text)) + return EINA_TRUE; + } + + return EINA_FALSE; +} + +static void __register_elm_scroller(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *scroller; + VC_ELM_LOG_INFO("Registering scroller in VC_ELM"); + scroller = _vc_elm_core_register_widget("Elm_Scroller", NULL, scroller_filter_func, NULL); + + if (NULL == scroller) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(scroller, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, scroller_activator_func); + } +} + +static void label_activator_func(Evas_Object *obj, void *data, const char *action_name) +{ + (void)data; + (void)obj; + (void)action_name; + +} + +static void __register_elm_label(Eina_List *actions) +{ + Eina_List *l; + const char *action_name; + struct vc_elm_core_widget_info *label; + VC_ELM_LOG_INFO("Registering label in VC_ELM"); + label = _vc_elm_core_register_widget("Elm_Label", NULL, NULL, NULL); + + if (NULL == label) + return; + + EINA_LIST_FOREACH(actions, l, action_name) { + _vc_elm_core_register_action(label, eina_hash_find(_vc_elm_core_get_config_action_map(), action_name), NULL, label_activator_func); + } +} + +/* ------------------------------------------------------------------------- */ +/** + * @brief Function that registers supported widgets. + */ +void _vc_elm_core_register_default_widgets() +{ + __register_elm_genlist(NULL); + __register_elm_radiobutton(NULL); + __register_elm_bubble(NULL); + __register_elm_checkbox(NULL); + __register_elm_list(NULL); + __register_elm_slider(NULL); + __register_elm_colorselector(NULL); + __register_elm_simple_hue_colorselector_activator(NULL); + __register_elm_simple_saturation_colorselector_activator(NULL); + __register_elm_simple_value_colorselector_activator(NULL); + __register_elm_spinner(NULL); + __register_elm_toolbar(NULL); + __register_elm_entry(NULL); + __register_elm_multibuttonentry(NULL); + __register_vc_elm_item(); + __register_elm_gengrid(NULL); + __register_elm_button(NULL); + __register_elm_panes(NULL); + __register_elm_scroller(NULL); + __register_elm_label(NULL); +} + +Eina_Bool _vc_elm_core_register_default_widget(const char *widget_name, Eina_Bool register_widget, Eina_List *actions) +{ + VC_ELM_LOG_DBG("REGISTERING A WIDGET %s", widget_name); + VC_ELM_LOG_DBG("Actions list %u", eina_list_count(actions)); + VC_ELM_LOG_DBG("Actions list pointer %p", (void*)actions); + (void)actions; + if (NULL == widget_name) + return EINA_FALSE; + + if (0 == strcmp(widget_name, "Elm_Genlist")) { + if (register_widget) + __register_elm_genlist(actions); + } else if (0 == strcmp(widget_name, "Elm_Radio")) { + if (register_widget) + __register_elm_radiobutton(actions); + } else if (0 == strcmp(widget_name, "Elm_Bubble")) { + if (register_widget) + __register_elm_bubble(actions); + } else if (0 == strcmp(widget_name, "Elm_Check")) { + if (register_widget) + __register_elm_checkbox(actions); + } else if (0 == strcmp(widget_name, "Elm_List")) { + if (register_widget) + __register_elm_list(actions); + } else if (0 == strcmp(widget_name, "Elm_Slider")) { + if (register_widget) + __register_elm_slider(actions); + } else if (0 == strcmp(widget_name, "Elm_Colorselector")) { + if (register_widget) + __register_elm_colorselector(actions); + } else if (0 == strcmp(widget_name, "simple_hue_colorbar_activator")) { + if (register_widget) + __register_elm_simple_hue_colorselector_activator(actions); + } else if (0 == strcmp(widget_name, "simple_saturation_colorbar_activator")) { + if (register_widget) + __register_elm_simple_saturation_colorselector_activator(actions); + } else if (0 == strcmp(widget_name, "simple_value_colorbar_activator")) { + if (register_widget) + __register_elm_simple_value_colorselector_activator(actions); + } else if (0 == strcmp(widget_name, "Elm_Spinner")) { + if (register_widget) + __register_elm_spinner(actions); + } else if (0 == strcmp(widget_name, "Elm_Panes")) { + if (register_widget) + __register_elm_panes(actions); + } else if (0 == strcmp(widget_name, "Elm_Toolbar")) { + if (register_widget) + __register_elm_toolbar(actions); + } else if (0 == strcmp(widget_name, "Elm_Entry")) { + if (register_widget) + __register_elm_entry(actions); + } else if (0 == strcmp(widget_name, "Elm_Multibuttonentry")) { + if (register_widget) + __register_elm_multibuttonentry(actions); + } else if (0 == strcmp(widget_name, "elm_item")) { + if (register_widget) + __register_vc_elm_item(); + } else if (0 == strcmp(widget_name, "Elm_Gengrid")) { + if (register_widget) + __register_elm_gengrid(actions); + } else if (0 == strcmp(widget_name, "Elm_Button")) { + if (register_widget) + __register_elm_button(actions); + } else if (0 == strcmp(widget_name, "Elm_Scroller")) { + if (register_widget) + __register_elm_scroller(actions); + } else if (0 == strcmp(widget_name, "Elm_Hoversel")) { + if (register_widget) + __register_elm_hoversel(actions); + } else if (0 == strcmp(widget_name, "Elm_Label")) { + if (register_widget) + __register_elm_label(actions); + } else { + return EINA_FALSE; + } + return EINA_TRUE; +} diff --git a/src/vc_elm_main.h b/src/vc_elm_main.h new file mode 100644 index 0000000..91a2c8a --- /dev/null +++ b/src/vc_elm_main.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011-2014 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 __VC_ELM_MAIN_H__ +#define __VC_ELM_MAIN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#pragma GCC system_header +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +#define ELM_INTERNAL_API_ARGESFSDFEFC +#include +#undef ELM_INTERNAL_API_ARGESFSDFEFC + +static inline Evas_Object *__safe_efl_cast(const Evas_Object *cobj) +{ + union { + Evas_Object *obj; + const Evas_Object *cobj; + } helper; + + helper.cobj = cobj; + return helper.obj; +} + +void *eo_data_scope_get(const Eo *obj, const Eo_Class *klass); + + +#ifdef __cplusplus +} +#endif + +#endif/*__VC_ELM_MAIN_H__*/ diff --git a/src/vc_elm_rectangle.c b/src/vc_elm_rectangle.c new file mode 100644 index 0000000..11c669f --- /dev/null +++ b/src/vc_elm_rectangle.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011-2014 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 "vc_elm_main.h" +#include "vc_elm_rectangle.h" + +static const char VC_ELM_FIXED_X[] = "vc_elm_fixed_x"; +static const char VC_ELM_FIXED_Y[] = "vc_elm_fixed_y"; + +/** + * @brief Function that set structure R dimensions from Evas_Object settings + * @param[in] pointer to structure R that will be filled with dimensions info + * @param[in] pointer to Evas_Object + */ +void _R_set_from_efl(R *p, Evas_Object *obj) +{ + int x; + int y; + int w; + int h; + int *tx; + int *ty; + evas_object_geometry_get(obj, &x, &y, &w, &h); + tx = (int *)evas_object_data_get(obj, VC_ELM_FIXED_X); + ty = (int *)evas_object_data_get(obj, VC_ELM_FIXED_Y); + if (tx != 0 && ty != 0) { + x = (int)tx; + y = (int)ty; + } + p->x = x; + p->y = y; + p->w = w; + p->h = h; +} + +#if !defined max +#define max(a, b) (a > b ? a : b) +#endif + +#if!defined min +#define min(a, b) (a < b ? a : b) +#endif + +/** + * @brief Function that check intersection of two R structures. + * @param[in] pointer to first structure R1 + * @param[in] pointer to second structure R2 + * @param[out] pointer to structure R that is intersection of provided R1 and R2 + */ +int _R_intersection(R *r1, R *r2, R *out) +{ + int leftX = max(r1->x, r2->x); + int rightX = min(r1->x + r1->w, r2->x + r2->w); + int topY = max(r1->y, r2->y); + int bottomY = min(r1->y + r1->h, r2->y + r2->h); + + int W = rightX - leftX; + int H = bottomY - topY; + out->x = leftX; + out->y = topY; + out->w = rightX - leftX; + out->h = bottomY - topY; + + if (W < 0 || H < 0) + return 0; + + return 1; +} diff --git a/src/vc_elm_rectangle.h b/src/vc_elm_rectangle.h new file mode 100644 index 0000000..1648578 --- /dev/null +++ b/src/vc_elm_rectangle.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011-2014 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 __VC_ELM_RECTANGLE_H__ +#define __VC_ELM_RECTANGLE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "vc_elm_main.h" + +/** + * @brief Structure that contains Evas_Object dimensions + */ + struct _R { + int x; + int y; + int w; + int h; +}; + +typedef struct _R R; + +/** + * @brief Function that set structure R dimensions from Evas_Object settings + * @param[in] pointer to structure R that will be filled with dimensions info + * @param[in] pointer to Evas_Object + */ +void _R_set_from_efl(R *p, Evas_Object *obj); + +/** + * @brief Function that check intersection of two R structures. + * @param[in] pointer to first structure R1 + * @param[in] pointer to second structure R2 + * @param[out] pointer to structure R that is intersection of provided R1 and R2 + */ +int _R_intersection(R *r1, R *r2, R *out); + + +#ifdef __cplusplus +} +#endif + +#endif /* __VC_ELM_RECTANGLE_H__ */ diff --git a/src/vc_elm_tools.h b/src/vc_elm_tools.h new file mode 100644 index 0000000..65cd58e --- /dev/null +++ b/src/vc_elm_tools.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011-2014 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 __VC_ELM_TOOLS_H__ +#define __VC_ELM_TOOLS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#pragma GCC system_header +#include "vc_elm_main.h" + +#define LOG_TAG "VC_ELM" + +#define VC_ELM_LOG_DBG(fmt, ...) do{ EINA_LOG_ERR("\033[0;32m" fmt "\033[m", ## __VA_ARGS__); SLOGI("\033[0;32m" fmt "\033[m", ## __VA_ARGS__); }while(0) +#define VC_ELM_LOG_INFO(fmt, ...) do{ EINA_LOG_ERR("\033[0;35m" fmt "\033[m", ## __VA_ARGS__); SLOGI("\033[0;32m" fmt "\033[m", ## __VA_ARGS__); }while(0) +#define VC_ELM_LOG_ERR(fmt, ...) do{ EINA_LOG_ERR("\033[0;31m" fmt "\033[m", ## __VA_ARGS__); SLOGE("\033[0;32m" fmt "\033[m", ## __VA_ARGS__); }while(0) +#define VC_ELM_LOG_WARN(fmt, ...) do{ EINA_LOG_ERR("\033[0;36m" fmt "\033[m", ## __VA_ARGS__); SLOGW("\033[0;32m" fmt "\033[m", ## __VA_ARGS__); }while(0) + + +#ifdef __cplusplus +} +#endif + +#endif/*__VC_ELM_TOOLS_H__*/ diff --git a/src/vc_elm_tooltip.c b/src/vc_elm_tooltip.c new file mode 100644 index 0000000..a8b3586 --- /dev/null +++ b/src/vc_elm_tooltip.c @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2011-2014 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 "vc_elm_main.h" +#include "vc_elm.h" +#include "vc_elm_core.h" +#include "vc_elm_tooltip.h" +#include "vc_elm_tools.h" +#include "vc_elm_rectangle.h" +#include "Eina.h" +#include +#include +#include + +#define _APP(S) dgettext(g_app_domain, S) + +#define SCALE 1000 + +static const char __VC_ELM_SAVED_X[] = "vc_elm_saved_x"; +static const char __VC_ELM_SAVED_Y[] = "vc_elm_saved_y"; + +static const char *__key_table[] = { + "vc_elm_fixed_x", + "vc_elm_fixed_y", + "vc_elm_once_fixed_x", + "vc_elm_once_fixed_y", + "vc_elm_hint_image_path", + "vc_elm_position_x", + "vc_elm_position_y" +}; + +static char *g_app_domain = NULL; +static int domain_initialized = 0; + +static Evas_Object *g_win = NULL; +static Evas_Object *g_grid = NULL; +static int win_width = -1; +static int win_heigh = -1; + +static Eina_List *obj_list = NULL; + +const char *_vc_elm_get_data_key(vc_elm_data_key key) { + if (key < sizeof(__key_table)/sizeof(__key_table[0])) { + return __key_table[key]; + } + return NULL; +} + +void _vc_elm_set_tooltips_window(Evas_Object *win) +{ + g_win = win; + evas_object_geometry_get(win, NULL, NULL, &win_width, &win_heigh); + VC_ELM_LOG_ERR("init %p %p", (void*)win, (void*)g_grid); +} + +static void __turn_on_tooltips() +{ + int x; + int y; + int w; + int h; + + VC_ELM_LOG_DBG("my tool"); + + g_grid = elm_grid_add(g_win); + evas_object_layer_set(g_grid, 10000); + + elm_grid_size_set(g_grid, SCALE, SCALE); + evas_object_geometry_get(g_win, &x, &y, &w, &h); + VC_ELM_LOG_DBG("win size: %d %d, %d %d", x, y, w, h); + evas_object_move(g_grid, x, y); + evas_object_resize(g_grid, w, h); + evas_object_show(g_grid); + evas_object_smart_calculate(g_grid); +} + +static int __evas_object_position_comparator_func(const void *a_, const void *b_) +{ + int ax; + int ay; + int aw; + int ah; + int tax; + int tay; + int bx; + int by; + int bw; + int bh; + int tbx; + int tby; + int dx; + int dy; + const Evas_Object *a = (const Evas_Object *)a_; + const Evas_Object *b = (const Evas_Object *)b_; + evas_object_geometry_get(a, &ax, &ay, &aw, &ah); + tax = (int)evas_object_data_get(a, __VC_ELM_SAVED_X); + tay = (int)evas_object_data_get(a, __VC_ELM_SAVED_Y); + tbx = (int)evas_object_data_get(b, __VC_ELM_SAVED_X); + tby = (int)evas_object_data_get(b, __VC_ELM_SAVED_Y); + if (tax > 0 && tay > 0) { + ax = tax; + ay = tay; + } + evas_object_geometry_get(b, &bx, &by, &bw, &bh); + + if (tbx > 0 && tby > 0) { + bx = tbx; + by = tby; + } + dx = ax - bx; + dy = ay - by; + + return dy == 0 ? dx : dy; +} + +void _vc_elm_add_tooltip(Evas_Object *obj, const char *tip) +{ + int x = 0; + int y = 0; + Evas_Object *tipobj; + int aw; + int ah; + int mw; + int mh; + int mx; + int my; /* geometry of tooltips overlay */ + Evas_Object *rec; + Evas_Object *rec_bg; + const char *image_path; + + { + int x_; + int y_; + int w_; + int h_; + evas_object_geometry_get(obj, &x_, &y_, &w_, &h_); + x = x_ + w_ / 2; + y = y_ + h_ / 2; + + x_ = (int)evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_FIXED_X)); + y_ = (int)evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_FIXED_Y)); + + if (x_ > 0 && y_ > 0) { + x = x_; + y = y_; + } + + x_ = (int)evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_ONCE_FIXED_X)); + if (x_ > 0) + evas_object_data_del(obj, _vc_elm_get_data_key(VC_ELM_ONCE_FIXED_X)); + y_ = (int)evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_ONCE_FIXED_Y)); + if (y_ > 0) + evas_object_data_del(obj, _vc_elm_get_data_key(VC_ELM_ONCE_FIXED_Y)); + + if (x_ > 0 && y_ > 0) { + x = x_; + y = y_; + } + evas_object_data_set(obj, __VC_ELM_SAVED_X, (void *)x); + evas_object_data_set(obj, __VC_ELM_SAVED_Y, (void *)y); + } + + if (!g_grid) + __turn_on_tooltips(); + + rec = elm_label_add(g_grid); + elm_object_text_set(rec, tip); + evas_object_color_set(rec, 0, 0, 0, 255); + evas_object_show(rec); + + evas_object_geometry_get(g_grid, &mx, &my, &mw, &mh); + evas_object_size_hint_min_get(rec, &aw, &ah); + + rec_bg = elm_image_add(g_grid); + + image_path = evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_HINT_IMAGE_PATH)); + if (image_path == NULL) + image_path = _vc_elm_core_get_tooltip_image_path(); + + elm_image_file_set(rec_bg, image_path, NULL); + elm_image_resizable_set(rec_bg, EINA_TRUE, EINA_TRUE); + elm_image_aspect_fixed_set(rec_bg, EINA_FALSE); + evas_object_size_hint_align_set(rec_bg, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_min_set(rec_bg, (aw + 60), ah); + + evas_object_show(rec_bg); + + tipobj = elm_layout_add(g_grid); + elm_layout_file_set(tipobj, "/usr/share/edje/voice-control-elm.edj", "tip_group"); + elm_object_part_content_set(tipobj, "content", rec); + elm_object_part_content_set(tipobj, "bg", rec_bg); + evas_object_show(tipobj); + + { + int _x = ((x - mx) * SCALE) / mw; + int _y = ((y - my) * SCALE) / mh; + + int _w = ((aw + 32) * SCALE) / mw; + int _h = ((ah + 10) * SCALE) / mh; + elm_grid_pack(g_grid, tipobj, _x + 32, _y - _h / 2, _w, _h); + } + + evas_object_data_set(obj, "MyTooltipHandle", tipobj); + obj_list = eina_list_sorted_insert(obj_list, &__evas_object_position_comparator_func, obj); +} + +void _vc_elm_turn_off_tooltips() +{ + Eina_List *chlds = elm_grid_children_get(g_grid); + Eina_List *l; + Evas_Object *obj; + + if (!g_grid) + return; + + EINA_LIST_FOREACH(chlds, l, obj) { + elm_grid_unpack(g_grid, obj); + evas_object_del(obj); + } + + evas_object_del(g_grid); + g_grid = NULL; + + obj_list = eina_list_free(obj_list); +} + +void _vc_elm_relayout_and_show_tooltips() +{ + Eina_List *l; + Evas_Object *obj; + int inserted = 0; + int mw; + int mh; + int mx; + int my; + size_t length = eina_list_count(obj_list); + R *recs = (R *)malloc(sizeof(R) * length); + int nx; + int ny; + int nw; + int nh; + + evas_object_geometry_get(g_grid, &mx, &my, &mw, &mh); + + EINA_LIST_FOREACH(obj_list, l, obj) { + int p; + int direction; + R o; + R t; + R i; + Evas_Object *tip = evas_object_data_get(obj, "MyTooltipHandle"); + _R_set_from_efl(&o, obj); + + { + int x; + int y; + int w; + int h; + elm_grid_pack_get(tip, &x, &y, &w, &h); + t.x = ((x * mw) / SCALE) - mx; + t.y = ((y * mh) / SCALE) - my; + t.w = ((w * mw) / SCALE); + t.h = ((h * mh) / SCALE); + } + + t.x = o.x - t.w + o.w / 2; + t.x = t.x < 0 ? 0 : t.x; + t.y = o.y - t.h + o.h / 2; + t.y = t.y < 0 ? 0 : t.y; + + for (p = 0; p < inserted; ++p) { + if (1 == _R_intersection(&t, &recs[p], &i)) { + t.y += i.h + 1; + if (1 == _R_intersection(&t, &recs[p], &i)) { + t.y -= i.h + 1; + t.x += i.w + 1; + if (1 == _R_intersection(&t, &recs[p], &i)) + t.y += i.h + 1; + } + + } + } + + if (evas_object_data_get(obj, VC_ELM_DIRECTION) != NULL) { + direction = (int)evas_object_data_get(obj, VC_ELM_DIRECTION); + direction--; + } else if (evas_object_data_get(obj, VC_ELM_SUB_ITEM_DIRECTION) != NULL) { + direction = (int)evas_object_data_get(obj, VC_ELM_SUB_ITEM_DIRECTION); + direction--; + } else { + direction = _vc_elm_core_get_tooltip_default_direction(); + } + if (direction == VC_ELM_DIRECTION_CENTER) { + t.x = o.x + o.w / 2 - t.w / 2; + t.y = o.y + o.h / 2 - t.h / 2; + } else if (direction == VC_ELM_DIRECTION_LEFT) { + t.x = o.x + o.w / 5 - t.w; + t.y = o.y + o.h / 2 - t.h / 2; + } else if (direction == VC_ELM_DIRECTION_RIGHT) { + t.x = o.x + o.w - o.w / 5; + t.y = o.y + o.h / 2 - t.h / 2; + } else if (direction == VC_ELM_DIRECTION_TOP) { + t.x = o.x + o.w / 2 - t.w / 2; + t.y = o.y + o.h / 5 - t.h; + } else if (direction == VC_ELM_DIRECTION_BOTTOM) { + t.x = o.x + o.w / 2 - t.w / 2; + t.y = o.y + o.h - o.h / 5; + } else if (direction == VC_ELM_DIRECTION_LEFT_TOP) { + t.x = o.x + o.w / 5 - t.w; + t.y = o.y + o.h / 5 - t.h; + } else if (direction == VC_ELM_DIRECTION_LEFT_BOTTOM) { + t.x = o.x + o.w / 5 - t.w; + t.y = o.y + o.h - o.h / 5; + } else if (direction == VC_ELM_DIRECTION_RIGHT_TOP) { + t.x = o.x + o.w - o.w / 5; + t.y = o.y + o.h / 5 - t.h; + } else if (direction == VC_ELM_DIRECTION_RIGHT_BOTTOM) { + t.x = o.x + o.w - o.w / 5; + t.y = o.y + o.h - o.h / 5; + } + + if (recs != NULL) { + recs[inserted].x = t.x; + recs[inserted].y = t.y; + recs[inserted].w = t.w; + recs[inserted].h = t.h; + ++inserted; + } + + if (evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_POSITION_X)) != NULL && evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_POSITION_Y)) != NULL) { + int position_x = (int)(evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_POSITION_X))); + int position_y = (int)(evas_object_data_get(obj, _vc_elm_get_data_key(VC_ELM_POSITION_Y))); + + t.x = position_x + o.x; + t.y = position_y + o.y; + } + + nx = ((t.x - mx) * SCALE) / mw; + ny = ((t.y - my) * SCALE) / mh; + nw = (t.w * SCALE) / mw; + nh = (t.h * SCALE) / mh; + + elm_grid_pack_set(tip, nx, ny, nw, nh); + } + free(recs); +} + +void _vc_elm_tooltips_show_tooltip(Evas_Object *obj, const char *text) +{ + if (domain_initialized == 0) { + _vc_elm_get_text_domain(&g_app_domain); + if (NULL != g_app_domain) + domain_initialized = 1; + } + + if (text) { + const char font_pre[] = ""; + const char font_post[] = ""; + + size_t tooltip_content_len = strlen(font_pre) + strlen(font_post) + strlen(_APP(text)); + char *tooltip_content = (char *)calloc(tooltip_content_len + 1, sizeof(char)); + if (tooltip_content != NULL) + tooltip_content[0] = '\0'; + else { + VC_ELM_LOG_ERR("Fail to allocate memory"); + return; + } + + eina_strlcat(tooltip_content, font_pre, tooltip_content_len + 1); + eina_strlcat(tooltip_content, _APP(text), tooltip_content_len + 1); + eina_strlcat(tooltip_content, font_post, tooltip_content_len + 1); + + _vc_elm_add_tooltip(obj, tooltip_content); + free(tooltip_content); + } +} diff --git a/src/vc_elm_tooltip.h b/src/vc_elm_tooltip.h new file mode 100644 index 0000000..0941121 --- /dev/null +++ b/src/vc_elm_tooltip.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011-2014 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 __VC_ELM_TOOLTIP_H__ +#define __VC_ELM_TOOLTIP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vc_elm_main.h" + +typedef enum { + VC_ELM_FIXED_X = 0, VC_ELM_FIXED_Y = 1, + VC_ELM_ONCE_FIXED_X = 2, VC_ELM_ONCE_FIXED_Y = 3, + VC_ELM_HINT_IMAGE_PATH = 4, VC_ELM_POSITION_X = 5, + VC_ELM_POSITION_Y = 6 +} vc_elm_data_key; + +/** + * @brief Function shows a tooltip over an Evas_Object + * @param[in] pointer to Evas_Object structure that the tooltip belongs to + * @param[in] text of the tooltip + */ +void _vc_elm_tooltips_show_tooltip(Evas_Object *obj, const char *text); + +/** + * @brief Function that sets the window that the tooltips will be shown on + * @param[in] pointer to the current window + */ +void _vc_elm_set_tooltips_window(Evas_Object *win); + +/** + * @brief Function that shows all the tooltips that should be visible + */ +void _vc_elm_turn_off_tooltips(); + +/** + * @brief Function that adds a tooltip to an Evas_Object + * @param[in] pointer to Evas_Object structure that the tooltip belongs to + * @param[in] text of the tooltip + */ +void _vc_elm_add_tooltip(Evas_Object *obj, const char *text); + +/** + * @brief Function that recalculates postitons of all the visible tooltips + * and shows them + */ +void _vc_elm_relayout_and_show_tooltips(); + +const char *_vc_elm_get_data_key(vc_elm_data_key key); + +#ifdef __cplusplus +} +#endif + +#endif/*__VC_ELM_TOOLTIP_H__*/ diff --git a/src/vc_elm_widget_wrapper.c b/src/vc_elm_widget_wrapper.c new file mode 100644 index 0000000..da5b7cb --- /dev/null +++ b/src/vc_elm_widget_wrapper.c @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2011-2014 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 "vc_elm_main.h" +#include "vc_elm_widget_wrapper.h" +#include "vc_elm_tools.h" +#include "vc_elm_core.h" + +#include + +struct __voice_control_wrapper_s { + bool initialized; + vc_cmd_list_h group; + char *lang; + int (*result_cb)(const char *cmd, const char *param1, const char *param2, void *data); + void (*tooltips_cb)(bool); + vc_current_language_changed_cb language_changed_cb; + void *lang_user_data; + void *data; +}; + +static struct __voice_control_wrapper_s vcw = {0, 0, 0, 0, 0, 0, 0, 0}; + +static void __vc_state_changed_cb(vc_state_e previous, vc_state_e current, void *user_data); +static void __vc_service_state_changed_cb(vc_service_state_e previous, vc_service_state_e current, void *user_data); +static void __vc_error_cb(vc_error_e reason, void *user_data); +static void __vc_result_cb(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char *result, void *user_data); +static void __vc_show_tooltip_callback(bool show, void *data); +static void __vc_language_changed_cb(const char *previous, const char *current, void *data); + +#define VC_CMD_ERROR_CHECK_CASE(VALUE) \ + case VALUE: \ + VC_ELM_LOG_ERR("vc error in (%s) -> %s", msg, #VALUE); \ + break; + +#define VC_ERROR_CHECK(args) do { \ + int err = args; \ + const char *msg = # args; \ + switch (err) { \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_OUT_OF_MEMORY); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_IO_ERROR); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_INVALID_PARAMETER); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_TIMED_OUT); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_RECORDER_BUSY); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_PERMISSION_DENIED); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_NOT_SUPPORTED); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_INVALID_STATE); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_INVALID_LANGUAGE); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_ENGINE_NOT_FOUND); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_OPERATION_FAILED); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_OPERATION_REJECTED); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_ITERATION_END); \ + VC_CMD_ERROR_CHECK_CASE(VC_ERROR_EMPTY); \ + case VC_ERROR_NONE: \ + VC_ELM_LOG_DBG("NO error in (%s)", msg); \ + break; \ + default: \ + VC_ELM_LOG_ERR("Unkown error in (%s)", msg); \ + } \ + } while(0) + +static void __vc_widget_send_current_command_group_cb(vc_cmd_list_h *vc_group, void *user_data) +{ + (void)user_data; + *vc_group = vcw.group; + + VC_ELM_LOG_DBG("SEND CURRENT COMMAND GROUP cb CALLED"); +} + +int _vc_elm_widget_wrapper_initialize() +{ + char *lang = NULL; + if (vcw.initialized) { + VC_ELM_LOG_ERR("already initialized"); + return 0; + } + vcw.initialized = 1; + + VC_ERROR_CHECK(vc_widget_initialize()); + VC_ERROR_CHECK(vc_widget_set_error_cb(&__vc_error_cb, NULL)); + VC_ERROR_CHECK(vc_widget_set_show_tooltip_cb(&__vc_show_tooltip_callback, NULL)); + VC_ERROR_CHECK(vc_widget_set_result_cb(&__vc_result_cb, NULL)); + VC_ERROR_CHECK(vc_widget_set_state_changed_cb(&__vc_state_changed_cb, NULL)); + VC_ERROR_CHECK(vc_widget_set_service_state_changed_cb(&__vc_service_state_changed_cb, NULL)); + VC_ERROR_CHECK(vc_widget_set_current_language_changed_cb(&__vc_language_changed_cb, NULL)); + VC_ERROR_CHECK(vc_widget_set_send_current_command_list_cb(__vc_widget_send_current_command_group_cb, NULL)); + VC_ERROR_CHECK(vc_widget_prepare()); + VC_ELM_LOG_DBG("VC default language used %s", lang); + vcw.lang = lang; + + return 1; +} + +int _vc_elm_widget_wrapper_deinitialize() +{ + if (vcw.group) { + VC_ERROR_CHECK(vc_cmd_list_destroy(vcw.group, true)); + vcw.group = NULL; + } + + if (vcw.lang) { + free(vcw.lang); + vcw.lang = NULL; + } + + VC_ERROR_CHECK(vc_widget_unprepare()); + VC_ERROR_CHECK(vc_widget_deinitialize()); + vcw.initialized = 0; + + return 0; +} + +static bool __cb(vc_cmd_h vc_command, void *user_data) +{ + char *cmd = NULL; + vc_cmd_format_e type; + (void)user_data; + + vc_cmd_get_format(vc_command, &type); + vc_cmd_get_command(vc_command, &cmd); + VC_ELM_LOG_DBG("cmd: %s %d", cmd, type); + return 1; +} + +int _vc_elm_widget_wrapper_commit_commands(vc_elm_widget_wrapper_result_cb callback, void *data) +{ + if (!vcw.group) { + VC_ELM_LOG_WARN("commit 2"); + return -1; + } + + VC_ELM_LOG_WARN("commit %p", (void*)vcw.group); + vc_cmd_list_foreach_commands(vcw.group, &__cb, NULL); + + vcw.result_cb = callback; + vcw.data = data; + VC_ELM_LOG_WARN("commit ok"); + return 0; +} + +int _vc_elm_widget_wrapper_add_command(const char *cmd, const char *param1) +{ + vc_cmd_h cmdh; + size_t len = 1; + char* command; + if (!vcw.group) { + VC_ERROR_CHECK(vc_cmd_list_create(&vcw.group)); + VC_ELM_LOG_WARN("new_command_group %p", (void*)vcw.group); + } + if (NULL == cmd) + return VC_ELM_ERROR_INVALID_PARAMETER; + len += strlen(cmd); + if (NULL != param1) { + len = len + strlen(param1) + 1; + command = (char *)calloc(len, sizeof(char)); + if (NULL == command) { + VC_ELM_LOG_ERR("Fail to allocate memory"); + return -1; + } + snprintf(command, len, "%s %s", cmd, param1); + } else { + command = (char *)calloc(len, sizeof(char)); + if (NULL == command) { + VC_ELM_LOG_ERR("Fail to allocate memory"); + return -1; + } + snprintf(command, len, "%s", cmd); + } + VC_ERROR_CHECK(vc_cmd_create(&cmdh)); + VC_ERROR_CHECK(vc_cmd_set_command(cmdh, command)); + VC_ERROR_CHECK(vc_cmd_set_format(cmdh, VC_CMD_FORMAT_FIXED)); + VC_ERROR_CHECK(vc_cmd_set_type(cmdh, VC_COMMAND_TYPE_WIDGET)); + VC_ERROR_CHECK(vc_cmd_list_add(vcw.group, cmdh)); + + free(command); + return 0; +} + +static void __vc_state_changed_cb(vc_state_e previous, vc_state_e current, void *user_data) +{ + const char *prev = NULL; + const char *curr = NULL; + char *tmp_lang = NULL; + char *lang = NULL; + (void)user_data; + + switch (previous) { + case VC_STATE_INITIALIZED: + prev = "VC_STATE_INITIALIZED"; + break; + case VC_STATE_READY: + prev = "VC_STATE_READY"; + break; + case VC_STATE_NONE: + curr = "VC_STATE_READY"; + break; + default: + VC_ELM_LOG_ERR("unkown value"); + exit(-1); + } + + switch (current) { + case VC_STATE_INITIALIZED: + curr = "VC_STATE_INITIALIZED"; + break; + case VC_STATE_READY: + curr = "VC_STATE_READY"; + vc_widget_set_foreground(EINA_TRUE); + vc_widget_get_current_language(&tmp_lang); + if (NULL != tmp_lang) { + int ret = asprintf(&lang, "%s.UTF-8", tmp_lang); + if (-1 == ret) { + VC_ELM_LOG_ERR("error changing locale"); + exit(-1); + } + VC_ELM_LOG_DBG("locale changing - %s", setlocale(LC_ALL, lang)); + } + break; + case VC_STATE_NONE: + curr = "VC_STATE_READY"; + break; + default: + VC_ELM_LOG_ERR("unkown value"); + exit(-1); + } + + free(lang); + free(tmp_lang); + + VC_ELM_LOG_DBG("VC state changed from %s to %s", prev, curr); +} + +static void __vc_service_state_changed_cb(vc_service_state_e previous, vc_service_state_e current, void *user_data) +{ + (void)user_data; + + if ((VC_SERVICE_STATE_PROCESSING == previous && VC_SERVICE_STATE_READY == current) || (VC_SERVICE_STATE_RECORDING == previous && VC_SERVICE_STATE_READY == current)) { + VC_ELM_LOG_DBG("VC Service processing ends, clear commands"); + if (NULL != vcw.group) { + vc_cmd_list_destroy(vcw.group, true); + vcw.group = NULL; + } + } +} + +static void __vc_error_cb(vc_error_e reason, void *user_data) +{ + (void)user_data; + VC_ELM_LOG_ERR("VC Error occured : %d", reason); +} + +static void __vc_result_cb(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char *result, void *user_data) +{ + vc_cmd_h vc_command = NULL; + char *cmd_name = NULL; + int ret = 0; + vc_cmd_format_e type; + (void)user_data; + (void)result; + if (event != VC_RESULT_EVENT_RESULT_SUCCESS) + return; + + vc_cmd_list_first(vc_cmd_list); + while (VC_ERROR_ITERATION_END != ret) { + if (0 != vc_cmd_list_get_current(vc_cmd_list, &vc_command)) { + VC_ELM_LOG_ERR("cannot get command from list"); + break; + } + + if (NULL == vc_command) + break; + + VC_ERROR_CHECK(vc_cmd_get_format(vc_command, &type)); + VC_ERROR_CHECK(vc_cmd_get_command(vc_command, &cmd_name)); + + if (vcw.result_cb) { + vcw.result_cb(cmd_name, NULL, NULL, vcw.data); + break; + } + + ret = vc_cmd_list_next(vc_cmd_list); + } + + free(cmd_name); +} + +void __vc_show_tooltip_callback(bool show, void *data) +{ + (void)data; + VC_ELM_LOG_DBG("show tooltips %d", show); + + if (vcw.tooltips_cb && _vc_elm_core_get_tooltip_show()) + vcw.tooltips_cb(show); +} + +void _vc_elm_widget_wrapper_set_show_tooltips_callback(vc_elm_widget_wrapper_show_tooltips_callback callback) +{ + vcw.tooltips_cb = callback; +} + +static void __vc_language_changed_cb(const char *previous, const char *current, void *data) +{ + char *lang; + int ret; + (void)previous; + (void)current; + (void)data; + + VC_ELM_LOG_INFO("Widget language changed from %s to %s", previous, current); + + ret = asprintf(&lang, "%s.UTF-8", current); + if (-1 == ret) { + VC_ELM_LOG_ERR("Error setting locale"); + return; + } + VC_ELM_LOG_INFO("Locale changing - %s", setlocale(LC_ALL, lang)); + free(lang); + + if (NULL != vcw.language_changed_cb) { + vcw.language_changed_cb(previous, current, vcw.lang_user_data); + } else { + VC_ELM_LOG_DBG("Not registered language changed callback"); + } + return; +} + +int vc_elm_widget_wrapper_set_current_language_changed_callback(vc_elm_widget_wrapper_language_changed_callback callback, void *data) +{ + if (NULL == callback) { + VC_ELM_LOG_ERR("Null parameter"); + return -1; + } + + vcw.language_changed_cb = callback; + vcw.lang_user_data = data; + return 0; + +} + +int vc_elm_widget_wrapper_unset_current_language_changed_callback() +{ + if (NULL == vcw.language_changed_cb) { + VC_ELM_LOG_ERR("No registered cb"); + return -1; + } + + vcw.language_changed_cb = NULL; + vcw.lang_user_data = NULL; + return 0; +} diff --git a/src/vc_elm_widget_wrapper.h b/src/vc_elm_widget_wrapper.h new file mode 100644 index 0000000..85f4f40 --- /dev/null +++ b/src/vc_elm_widget_wrapper.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011-2014 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 __VC_ELM_WIDGET_WRAPPER_H__ +#define __VC_ELM_WIDGET_WRAPPER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +typedef int (*vc_elm_widget_wrapper_result_cb)(const char *cmd, const char *param1, const char *param2, void *data); + +typedef void (*vc_elm_widget_wrapper_show_tooltips_callback)(bool show_or_hide); + +typedef void (*vc_elm_widget_wrapper_language_changed_callback)(const char *previous, const char * current, void *data); + +/** + * @brief Function that initializes VC_Widget_Wrapper + */ +int _vc_elm_widget_wrapper_initialize(); + +/** + * @brief Function that deinitializes VC_Widget_Wrapper + */ +int _vc_elm_widget_wrapper_deinitialize(); + +/** + * @brief Function that adds a voice command + * @param[in] command text + * @param[in] parameter text + */ +int _vc_elm_widget_wrapper_add_command(const char *cmd, const char *param1); + +/** + * @brief Function shows registers all the added commands in voice control + * @param[in] result callback for registered commands + * @param[in] additional data to be passed to the callback + */ +int _vc_elm_widget_wrapper_commit_commands(vc_elm_widget_wrapper_result_cb callback, void *data); + +/** + * @brief Function that sets the show tooltips callback + * @param[in] callback that will be called when tooltips should be shown/hidden + */ +void _vc_elm_widget_wrapper_set_show_tooltips_callback(vc_elm_widget_wrapper_show_tooltips_callback callback); + +int vc_elm_widget_wrapper_set_current_language_changed_callback(vc_elm_widget_wrapper_language_changed_callback callback, void *user_data); + +int vc_elm_widget_wrapper_unset_current_language_changed_callback(); + + +#ifdef __cplusplus +} +#endif + +#endif/*__VC_ELM_WIDGET_WRAPPER_H__*/ diff --git a/voice-control-elm-config.xml b/voice-control-elm-config.xml new file mode 100644 index 0000000..b52415d --- /dev/null +++ b/voice-control-elm-config.xml @@ -0,0 +1,216 @@ + + + + + + click + + + + scroll_up + scroll up + + + scroll_down + scroll down + + + center + center + + + scroll_left + scroll left + + + scroll_right + scroll right + + + up + up + + + down + down + + + left + left + + + right + right + + + top + top + + + bottom + bottom + + + zoom_out + zoom out + + + zoom_in + zoom in + + + fill + fill + + + + + Elm_Bubble + + click + + + + Elm_Button + + click + + + + Elm_Check + + click + + + + Elm_Entry + + click + up + down + scroll_up + scroll_down + + + + Elm_Gengrid + + scroll_up + scroll_down + up + down + top + bottom + left + right + scroll_left + scroll_right + + + + Elm_Genlist + + click + scroll_up + scroll_down + up + down + top + bottom + + + + Elm_Label + + null + + + + Elm_List + + scroll_up + scroll_down + up + down + top + bottom + + + + Elm_Radio + + click + + + + Elm_Scroller + + up + down + left + right + top + bottom + + + + Elm_Slider + + up + down + left + right + top + bottom + scroll_up + scroll_down + scroll_right + scroll_left + center + + + + Elm_Spinner + + up + down + left + right + top + bottom + + + + Elm_Toolbar + + up + down + top + bottom + scroll_left + scroll_right + right + left + scroll_up + scroll_down + + + + elm_item + + click + + + + + on + center + /usr/share/voice/vc-elm/image.png + + + + 2.4 + TV + 1.12 + +