--- /dev/null
+Dongyeol Lee <dy3.lee@samsung.com>
+Wonnam Jang <wn.jang@samsung.com>
+Kwangyoun Kim <ky85.kim@samsung.com>
+Witold Goralski <w.goralski@samsung.com>
+Jakub Borowski <j.borowski@samsung.com>
\ No newline at end of file
--- /dev/null
+# @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)
+
--- /dev/null
+
+ 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.
--- /dev/null
+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.
--- /dev/null
+vc-widget-elm (0.2.0) -- Thu, 29 May 2014
+
+ * Update version 0.2.0 (Kwangyoun Kim <ky85.kim@samsung.com>)
+
+vc-widget-elm (0.0.1)
+ * Release version 0.1.0 (Lukasz Wrzosek <l.wrzosek@samsung.com>)
--- /dev/null
+# 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})
--- /dev/null
+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"
--- /dev/null
+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"
--- /dev/null
+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 "명도"
--- /dev/null
+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"
--- /dev/null
+#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;
+ }
+ }
+ }
+ }
+
+ }
+}
--- /dev/null
+#include "tooltip.edc"
--- /dev/null
+# 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 <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> 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 <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> 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
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+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
--- /dev/null
+/*
+ * 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 <voice_control_elm.h>
+ *
+ * @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.<br>
+ * - Widget hints are shown on the User's wish.<br>
+ * - User speaks the hint name of the widget he/she wants to trigger and the action he/she wants to perform on that widget.<br>
+ * - The voice command is interpreted and the requested action on the widget is performed.<br>
+ *
+ * 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.<br>
+ * 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 <appcore-efl.h>
+ * #include <voice_control_elm.h>
+ *
+ * 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:<br>
+ * - http://tizen.org/feature/microphone<br>
+ *
+ * It is recommended to design feature related codes in your application for reliability.<br>
+ * 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.<br>
+ * 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.<br>
+ * More details on featuring your application can be found from <a href="../org.tizen.mobile.native.appprogramming/html/ide_sdk_tools/feature_element.htm"><b>Feature Element</b>.</a>
+ *
+ */
+
+
+
--- /dev/null
+/**
+
+
+* @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 <appcore-efl.h>
+* #include <voice_control_elm.h>
+*
+* 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
+* <define>
+* <domain name="mydomain"/>
+* <permit>
+* <smack permit="vc-server" type="rwx" />
+* <smack permit="dbus" type="rwx" />
+* </permit>
+* <request>
+* <smack request="dbus" type="rwx" />
+* <smack request="sound_server" type="rw" />
+* <smack request="vc-server" type="rwx" />
+* </request>
+* </define>
+* @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.
+*
+* @}
+*/
--- /dev/null
+/**
+ *
+ * @addtogroup voice-control-elm-devguide
+ * @{
+ * @section voice-control-elm-devguide_SUPPORTED_WIDGETS_TABLE APPENDIX: Supported default Elementary widgets
+ *
+ * @htmlonly
+
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:x="urn:schemas-microsoft-com:office:excel"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1250">
+<meta name=ProgId content=Excel.Sheet>
+<meta name=Generator content="Microsoft Excel 12">
+<link rel=File-List href="vc-widget-elm_%20commands_files/filelist.xml">
+<style id="voice-control-elm_ commands_1608_Styles">
+<!--table
+ {mso-displayed-decimal-separator:"\,";
+ mso-displayed-thousand-separator:" ";}
+.xl151608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:11.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Calibri, sans-serif;
+ mso-font-charset:238;
+ mso-number-format:General;
+ text-align:general;
+ vertical-align:bottom;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:nowrap;}
+.xl631608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:1.0pt solid windowtext;
+ border-right:1.0pt solid windowtext;
+ border-bottom:.5pt solid windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl641608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:.5pt solid windowtext;
+ border-right:2.0pt double windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl651608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:.5pt solid windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:2.0pt double windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl661608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:.5pt solid windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl671608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:.5pt solid windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl681608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:.5pt solid windowtext;
+ border-right:none;
+ border-bottom:none;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl691608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:.5pt solid windowtext;
+ border-right:1.0pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl701608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl711608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:2.0pt double windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl721608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:2.0pt double windowtext;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl731608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:none;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl741608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:none;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl751608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:none;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl761608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:none;
+ background:white;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl771608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl781608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:2.0pt double windowtext;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl791608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:none;
+ background:white;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl801608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:none;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl811608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:.5pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl821608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:8.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:none;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl831608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:2.0pt double windowtext;
+ background:white;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl841608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:none;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl851608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:2.0pt double windowtext;
+ border-bottom:none;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl861608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:none;
+ border-bottom:none;
+ border-left:2.0pt double windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl871608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl881608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl891608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:2.0pt double windowtext;
+ border-bottom:none;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl901608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:none;
+ border-bottom:none;
+ border-left:2.0pt double windowtext;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl911608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl921608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:2.0pt double windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl931608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:none;
+ border-left:2.0pt double windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl941608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:none;
+ border-left:none;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl951608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:2.0pt double windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl961608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:2.0pt double windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl971608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:2.0pt double windowtext;
+ background:white;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl981608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:none;
+ border-left:none;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl991608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1001608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:none;
+ border-bottom:1.0pt solid windowtext;
+ border-left:none;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1011608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:none;
+ border-left:none;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1021608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:none;
+ border-bottom:1.0pt solid windowtext;
+ border-left:none;
+ background:white;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1031608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:1.0pt solid windowtext;
+ border-right:none;
+ border-bottom:1.0pt solid windowtext;
+ border-left:none;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1041608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:1.0pt solid windowtext;
+ border-right:2.0pt double windowtext;
+ border-bottom:none;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1051608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:1.0pt solid windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:.5pt solid windowtext;
+ border-left:none;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1061608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:1.0pt solid windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:.5pt solid windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1071608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:1.0pt solid windowtext;
+ border-right:none;
+ border-bottom:.5pt solid windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1081608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:1.0pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1091608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:1.0pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:none;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1101608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:1.0pt solid windowtext;
+ background:white;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1111608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:1.0pt solid windowtext;
+ background:#D8D8D8;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1121608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:1.0pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:none;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1131608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:1.0pt solid windowtext;
+ background:white;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1141608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:1.0pt solid windowtext;
+ border-bottom:none;
+ border-left:none;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1151608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:1.0pt solid windowtext;
+ border-bottom:none;
+ border-left:none;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1161608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:1.0pt solid windowtext;
+ background:#D8D8D8;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1171608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:1.0pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1181608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:.5pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:1.0pt solid windowtext;
+ background:#D8D8D8;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1191608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:.5pt solid windowtext;
+ border-bottom:1.0pt solid windowtext;
+ border-left:1.0pt solid windowtext;
+ background:#D8D8D8;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1201608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:1.0pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:none;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1211608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:.5pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:1.0pt solid windowtext;
+ background:white;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1221608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:.5pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:1.0pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1231608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:1.0pt solid windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:1.0pt solid windowtext;
+ border-left:1.0pt solid windowtext;
+ background:#D8D8D8;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1241608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, serif;
+ mso-font-charset:238;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:.5pt solid windowtext;
+ border-bottom:2.0pt double windowtext;
+ border-left:1.0pt solid windowtext;
+ background:#D8D8D8;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1251608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:1.0pt solid windowtext;
+ border-left:1.0pt solid windowtext;
+ background:#D8D8D8;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1261608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:1.0pt solid windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1271608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:2.0pt double windowtext;
+ border-bottom:1.0pt solid windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1281608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:none;
+ border-bottom:1.0pt solid windowtext;
+ border-left:none;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1291608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:1.0pt solid windowtext;
+ border-bottom:1.0pt solid windowtext;
+ border-left:none;
+ background:#BFBFBF;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1301608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:1.0pt solid windowtext;
+ background:#D8D8D8;
+ mso-pattern:black none;
+ white-space:normal;}
+.xl1311608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:1.0pt solid windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:1.0pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1321608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:1.0pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1331608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:1.0pt solid windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1341608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, monospace;
+ mso-font-charset:129;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:none;
+ border-bottom:2.0pt double windowtext;
+ border-left:.5pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1351608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, serif;
+ mso-font-charset:238;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:2.0pt double windowtext;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:1.0pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+.xl1361608
+ {padding-top:1px;
+ padding-right:1px;
+ padding-left:1px;
+ mso-ignore:padding;
+ color:black;
+ font-size:10.0pt;
+ font-weight:400;
+ font-style:normal;
+ text-decoration:none;
+ font-family:Cambria, serif;
+ mso-font-charset:238;
+ mso-number-format:General;
+ text-align:center;
+ vertical-align:middle;
+ border-top:none;
+ border-right:.5pt solid windowtext;
+ border-bottom:none;
+ border-left:1.0pt solid windowtext;
+ mso-background-source:auto;
+ mso-pattern:auto;
+ white-space:normal;}
+-->
+</style>
+</head>
+
+<body>
+<!--[if !excel]> <![endif]-->
+<!--The following information was generated by Microsoft Office Excel's Publish
+as Web Page wizard.-->
+<!--If the same item is republished from Excel, all information between the DIV
+tags will be replaced.-->
+<!----------------------------->
+<!--START OF OUTPUT FROM EXCEL PUBLISH AS WEB PAGE WIZARD -->
+<!----------------------------->
+
+<div id="voice-control-elm_ commands_1608" align=center x:publishsource="Excel">
+
+<table border=0 cellpadding=0 cellspacing=0 width=1193 style='border-collapse:
+ collapse;table-layout:fixed;width:895pt'>
+ <col width=91 style='mso-width-source:userset;mso-width-alt:3328;width:68pt'>
+ <col width=78 style='mso-width-source:userset;mso-width-alt:2852;width:59pt'>
+ <col width=64 span=16 style='width:48pt'>
+ <tr height=21 style='height:15.75pt'>
+ <td height=21 class=xl151608 colspan=6 width=425 style='height:15.75pt;
+ width:319pt'>voice-control-elm - supported commands for Elementary widgets:</td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ <td class=xl151608 width=64 style='width:48pt'></td>
+ </tr>
+ <tr height=34 style='height:25.5pt'>
+ <td rowspan=2 height=69 class=xl1311608 width=91 style='height:51.75pt;
+ width:68pt'>Widget Type</td>
+ <td rowspan=2 class=xl1331608 width=78 style='border-bottom:2.0pt double black;
+ width:59pt'>sub widget</td>
+ <td class=xl1041608 width=64 style='width:48pt'>Action</td>
+ <td class=xl1051608 width=64 style='width:48pt'>click</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>scroll up</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>scroll down</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>center</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>scroll left</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>scroll right</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>up</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>down</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>left</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>right</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>top/home</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>bottom/end</td>
+ <td class=xl1061608 width=64 style='border-left:none;width:48pt'>zoom out</td>
+ <td class=xl1071608 width=64 style='border-left:none;width:48pt'>zoom in</td>
+ <td class=xl631608 width=64 style='width:48pt'>fill</td>
+ </tr>
+ <tr height=35 style='height:26.25pt'>
+ <td height=35 class=xl641608 width=64 style='height:26.25pt;width:48pt'>Command</td>
+ <td class=xl651608 width=64 style='border-left:none;width:48pt'>( )</td>
+ <td class=xl661608 width=64 style='border-left:none;width:48pt'>scroll up</td>
+ <td class=xl661608 width=64 style='border-left:none;width:48pt'>scroll down</td>
+ <td class=xl661608 width=64 style='border-left:none;width:48pt'>center</td>
+ <td class=xl671608 width=64 style='border-left:none;width:48pt'>scroll left</td>
+ <td class=xl671608 width=64 style='border-left:none;width:48pt'>scroll right</td>
+ <td class=xl661608 width=64 style='border-left:none;width:48pt'>up</td>
+ <td class=xl661608 width=64 style='border-left:none;width:48pt'>down</td>
+ <td class=xl661608 width=64 style='border-left:none;width:48pt'>left</td>
+ <td class=xl661608 width=64 style='border-left:none;width:48pt'>right</td>
+ <td class=xl661608 width=64 style='border-left:none;width:48pt'>home</td>
+ <td class=xl661608 width=64 style='border-left:none;width:48pt'>end</td>
+ <td class=xl661608 width=64 style='border-left:none;width:48pt'>out</td>
+ <td class=xl681608 width=64 style='border-left:none;width:48pt'>in</td>
+ <td class=xl691608 width=64 style='width:48pt'>fill</td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1081608 width=91 style='height:27.0pt;width:68pt'>Actionslider
+ (CallSlider)</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>3</td>
+ <td class=xl721608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl741608 width=64 style='width:48pt'>moves center</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl761608 width=64 style='width:48pt'>moves left</td>
+ <td class=xl761608 width=64 style='width:48pt'>moves right</td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1081608 width=91 style='height:16.5pt;width:68pt'>Background</td>
+ <td class=xl771608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl781608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1101608 width=91 style='height:16.5pt;width:68pt'>Bubble</td>
+ <td class=xl771608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl791608 width=64 style='width:48pt'>click</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1081608 width=91 style='height:16.5pt;width:68pt'>Button</td>
+ <td class=xl771608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl801608 width=64 style='width:48pt'>click</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1111608 width=91 style='height:27.0pt;width:68pt'>Calender</td>
+ <td class=xl811608 width=78 style='width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;width:48pt'>5</td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl821608 width=64 style='border-top:none;width:48pt'>previous month</td>
+ <td class=xl741608 width=64 style='border-top:none;width:48pt'>next month</td>
+ <td class=xl741608 width=64 style='border-top:none;width:48pt'>move up</td>
+ <td class=xl741608 width=64 style='border-top:none;width:48pt'>moves down</td>
+ <td class=xl741608 width=64 style='border-top:none;width:48pt'>move left</td>
+ <td class=xl741608 width=64 style='border-top:none;width:48pt'>move right</td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl1121608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1131608 width=91 style='height:16.5pt;width:68pt'>Checkbox</td>
+ <td class=xl811608 width=78 style='width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;width:48pt'>1</td>
+ <td class=xl831608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>click</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=21 style='height:15.75pt'>
+ <td rowspan=5 height=122 class=xl1111608 width=91 style='border-bottom:2.0pt double black;
+ height:91.5pt;border-top:none;width:68pt'>Clock</td>
+ <td class=xl841608 width=78 style='border-top:none;width:59pt'>edit</td>
+ <td class=xl851608 width=64 style='width:48pt'>1</td>
+ <td class=xl861608 width=64 style='border-left:none;width:48pt'>edit</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=20 style='height:15.0pt'>
+ <td height=20 class=xl881608 width=78 style='height:15.0pt;border-left:none;
+ width:59pt'>done</td>
+ <td class=xl891608 width=64 style='border-left:none;width:48pt'>1</td>
+ <td class=xl861608 width=64 style='border-left:none;width:48pt'>done</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=40 style='mso-height-source:userset;height:30.0pt'>
+ <td height=40 class=xl881608 width=78 style='height:30.0pt;border-left:none;
+ width:59pt'>hour</td>
+ <td class=xl891608 width=64 style='border-left:none;width:48pt'>2</td>
+ <td class=xl901608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl911608 width=64 style='width:48pt'>hour up</td>
+ <td class=xl911608 width=64 style='width:48pt'>hour down</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=20 style='height:15.0pt'>
+ <td height=20 class=xl881608 width=78 style='height:15.0pt;border-left:none;
+ width:59pt'>minute</td>
+ <td class=xl891608 width=64 style='border-left:none;width:48pt'>2</td>
+ <td class=xl901608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl911608 width=64 style='width:48pt'>min up</td>
+ <td class=xl911608 width=64 style='width:48pt'>min down</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=21 style='height:15.75pt'>
+ <td height=21 class=xl811608 width=78 style='height:15.75pt;width:59pt'>second</td>
+ <td class=xl921608 width=64 style='width:48pt'>2</td>
+ <td class=xl781608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>sec up</td>
+ <td class=xl801608 width=64 style='width:48pt'>sec down</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=52 style='height:39.0pt'>
+ <td rowspan=3 height=155 class=xl1351608 width=91 style='height:116.25pt;
+ border-top:none;width:68pt'>Colorselector</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>hue</td>
+ <td class=xl851608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>4</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl911608 width=64 style='width:48pt'>move left <br>
+ 5 step</td>
+ <td class=xl911608 width=64 style='width:48pt'>move right <br>
+ 5 step</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl911608 width=64 style='width:48pt'>move left</td>
+ <td class=xl911608 width=64 style='width:48pt'>move right</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=51 style='height:38.25pt'>
+ <td height=51 class=xl881608 width=78 style='height:38.25pt;border-left:none;
+ width:59pt'>saturation</td>
+ <td class=xl891608 width=64 style='border-left:none;width:48pt'>4</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl911608 width=64 style='width:48pt'>move left <br>
+ 5 step</td>
+ <td class=xl911608 width=64 style='width:48pt'>move right <br>
+ 5 step</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl911608 width=64 style='width:48pt'>move left</td>
+ <td class=xl911608 width=64 style='width:48pt'>move right</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=52 style='height:39.0pt'>
+ <td height=52 class=xl811608 width=78 style='height:39.0pt;width:59pt'>lightness</td>
+ <td class=xl921608 width=64 style='width:48pt'>4</td>
+ <td class=xl781608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl911608 width=64 style='width:48pt'>move left <br>
+ 5 step</td>
+ <td class=xl911608 width=64 style='width:48pt'>move right <br>
+ 5 step</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl911608 width=64 style='width:48pt'>move left</td>
+ <td class=xl911608 width=64 style='width:48pt'>move right</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1081608 width=91 style='height:16.5pt;width:68pt'>CtxPopup</td>
+ <td class=xl771608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-left:none;width:48pt'>1</td>
+ <td class=xl801608 width=64 style='width:48pt'>click</td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl1121608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=21 style='height:15.75pt'>
+ <td rowspan=2 height=56 class=xl1101608 width=91 style='border-bottom:2.0pt double black;
+ height:42.0pt;width:68pt'>Datetime</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>button name</td>
+ <td class=xl851608 width=64 style='border-left:none;width:48pt'>1</td>
+ <td class=xl931608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>click</td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl1151608 width=64 style='border-top:none;width:48pt'> </td>
+ </tr>
+ <tr height=35 style='height:26.25pt'>
+ <td height=35 class=xl811608 width=78 style='height:26.25pt;width:59pt'>scroll
+ bar</td>
+ <td class=xl921608 width=64 style='width:48pt'>5</td>
+ <td class=xl951608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl791608 width=64 style='width:48pt'>scroll left</td>
+ <td class=xl791608 width=64 style='width:48pt'>scroll right</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>move left<span
+ style='mso-spacerun:yes'> </span></td>
+ <td class=xl801608 width=64 style='width:48pt'>move right</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=21 style='height:15.75pt'>
+ <td rowspan=7 height=144 class=xl1111608 width=91 style='border-bottom:2.0pt double black;
+ height:108.0pt;border-top:none;width:68pt'>Dayselector</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>Monday</td>
+ <td class=xl851608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl861608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=20 style='height:15.0pt'>
+ <td height=20 class=xl881608 width=78 style='height:15.0pt;border-left:none;
+ width:59pt'>Thueday</td>
+ <td class=xl891608 width=64 style='border-left:none;width:48pt'>1</td>
+ <td class=xl861608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='mso-height-source:userset;height:16.5pt'>
+ <td height=22 class=xl881608 width=78 style='height:16.5pt;border-left:none;
+ width:59pt'>Wednesday</td>
+ <td class=xl891608 width=64 style='border-left:none;width:48pt'>1</td>
+ <td class=xl861608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=20 style='height:15.0pt'>
+ <td height=20 class=xl881608 width=78 style='height:15.0pt;border-left:none;
+ width:59pt'>Thursday</td>
+ <td class=xl891608 width=64 style='border-left:none;width:48pt'>1</td>
+ <td class=xl861608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=20 style='height:15.0pt'>
+ <td height=20 class=xl881608 width=78 style='height:15.0pt;border-left:none;
+ width:59pt'>Firday</td>
+ <td class=xl891608 width=64 style='border-left:none;width:48pt'>1</td>
+ <td class=xl861608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=20 style='height:15.0pt'>
+ <td height=20 class=xl881608 width=78 style='height:15.0pt;border-left:none;
+ width:59pt'>Saturday</td>
+ <td class=xl891608 width=64 style='border-left:none;width:48pt'>1</td>
+ <td class=xl861608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=21 style='height:15.75pt'>
+ <td height=21 class=xl811608 width=78 style='height:15.75pt;width:59pt'>Sunday</td>
+ <td class=xl921608 width=64 style='width:48pt'>1</td>
+ <td class=xl951608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1161608 width=91 style='height:27.0pt;border-top:none;
+ width:68pt'>Diskselector</td>
+ <td class=xl811608 width=78 style='width:59pt'>-</td>
+ <td class=xl711608 width=64 style='width:48pt'>5</td>
+ <td class=xl961608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>click</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl761608 width=64 style='border-top:none;width:48pt'>scroll left</td>
+ <td class=xl761608 width=64 style='border-top:none;width:48pt'>scroll right</td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>moves left</td>
+ <td class=xl801608 width=64 style='width:48pt'><span
+ style='mso-spacerun:yes'> </span>moves right</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1171608 width=91 style='height:16.5pt;border-top:none;
+ width:68pt'>Entry</td>
+ <td class=xl811608 width=78 style='width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;width:48pt'>1</td>
+ <td class=xl801608 width=64 style='width:48pt'>click</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1111608 width=91 style='height:27.0pt;border-top:none;
+ width:68pt'>File Selector Button</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl971608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl1151608 width=64 style='border-top:none;width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1111608 width=91 style='height:27.0pt;width:68pt'>File
+ Selector Entry</td>
+ <td class=xl771608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl721608 width=64 style='border-top:none;border-left:none;
+ width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl1121608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=21 style='height:15.75pt'>
+ <td rowspan=2 height=56 class=xl1111608 width=91 style='height:42.0pt;
+ width:68pt'>File Selector</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>button name</td>
+ <td class=xl851608 width=64 style='border-left:none;width:48pt'>1</td>
+ <td class=xl931608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>click</td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl1151608 width=64 style='border-top:none;width:48pt'> </td>
+ </tr>
+ <tr height=35 style='height:26.25pt'>
+ <td height=35 class=xl811608 width=78 style='height:26.25pt;width:59pt'>list
+ name</td>
+ <td class=xl921608 width=64 style='width:48pt'>7</td>
+ <td class=xl951608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll up</td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll down</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>moves up</td>
+ <td class=xl801608 width=64 style='width:48pt'>move down</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl791608 width=64 style='width:48pt'>move top</td>
+ <td class=xl791608 width=64 style='width:48pt'>move bottom</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1111608 width=91 style='height:27.0pt;width:68pt'>Flip</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl951608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>moves up</td>
+ <td class=xl801608 width=64 style='width:48pt'>move down</td>
+ <td class=xl801608 width=64 style='width:48pt'>moves left</td>
+ <td class=xl801608 width=64 style='width:48pt'><span
+ style='mso-spacerun:yes'> </span>moves right</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1161608 width=91 style='height:27.0pt;width:68pt'>Flip
+ selector</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>2</td>
+ <td class=xl721608 width=64 style='border-top:none;border-left:none;
+ width:48pt'> </td>
+ <td class=xl981608 width=64 style='border-top:none;width:48pt'><s
+ style='visibility:hidden;mso-ignore:visibility'> </s></td>
+ <td class=xl981608 width=64 style='border-top:none;width:48pt'><s
+ style='visibility:hidden;mso-ignore:visibility'> </s></td>
+ <td class=xl981608 width=64 style='border-top:none;width:48pt'><s
+ style='visibility:hidden;mso-ignore:visibility'> </s></td>
+ <td class=xl981608 width=64 style='border-top:none;width:48pt'><s
+ style='visibility:hidden;mso-ignore:visibility'> </s></td>
+ <td class=xl981608 width=64 style='border-top:none;width:48pt'><s
+ style='visibility:hidden;mso-ignore:visibility'> </s></td>
+ <td class=xl801608 width=64 style='width:48pt'>moves up</td>
+ <td class=xl801608 width=64 style='width:48pt'>moves down</td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1181608 width=91 style='height:16.5pt;width:68pt'>Frame</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl961608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>click</td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl1121608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1081608 width=91 style='height:27.0pt;border-top:none;
+ width:68pt'>Genlist</td>
+ <td class=xl771608 width=78 style='border-left:none;width:59pt'>button name</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>7</td>
+ <td class=xl951608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll up</td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll down</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>moves up</td>
+ <td class=xl801608 width=64 style='width:48pt'>move down</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>move top</td>
+ <td class=xl801608 width=64 style='width:48pt'>move bottom</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1111608 width=91 style='height:16.5pt;width:68pt'>GL
+ View</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1161608 width=91 style='height:16.5pt;width:68pt'>Hover</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl721608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1161608 width=91 style='height:16.5pt;border-top:none;
+ width:68pt'>Hoversel</td>
+ <td class=xl771608 width=78 style='border-left:none;width:59pt'>button name</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl801608 width=64 style='width:48pt'>click</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1111608 width=91 style='height:16.5pt;border-top:none;
+ width:68pt'>Icon</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl971608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl1121608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1111608 width=91 style='height:16.5pt;width:68pt'>Image</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl831608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>click</td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl1121608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1081608 width=91 style='height:27.0pt;width:68pt'>index
+ (Fast Scroll)</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>sub (A~Z)</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl971608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl991608 width=64 style='width:48pt'><s style='visibility:hidden;
+ mso-ignore:visibility'> </s></td>
+ <td class=xl991608 width=64 style='width:48pt'><s style='visibility:hidden;
+ mso-ignore:visibility'> </s></td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl991608 width=64 style='width:48pt'><s style='visibility:hidden;
+ mso-ignore:visibility'> </s></td>
+ <td class=xl991608 width=64 style='width:48pt'><s style='visibility:hidden;
+ mso-ignore:visibility'> </s></td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl991608 width=64 style='width:48pt'><s style='visibility:hidden;
+ mso-ignore:visibility'> </s></td>
+ <td class=xl991608 width=64 style='width:48pt'><s style='visibility:hidden;
+ mso-ignore:visibility'> </s></td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1141608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1111608 width=91 style='height:16.5pt;width:68pt'>Inwin</td>
+ <td class=xl771608 width=78 style='border-left:none;width:59pt'>button name</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl971608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl1121608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1111608 width=91 style='height:27.0pt;width:68pt'>List</td>
+ <td class=xl771608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>button name</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>7</td>
+ <td class=xl971608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll up</td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll down</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>moves up</td>
+ <td class=xl801608 width=64 style='width:48pt'>move down</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>move top</td>
+ <td class=xl801608 width=64 style='width:48pt'>move bottom</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl1091608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1081608 width=91 style='height:16.5pt;width:68pt'>Label</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl1121608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1191608 width=91 style='height:27.0pt;width:68pt'>Map</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>10</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll up</td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll down</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll left</td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll right</td>
+ <td class=xl801608 width=64 style='width:48pt'>moves up</td>
+ <td class=xl801608 width=64 style='width:48pt'>move down</td>
+ <td class=xl801608 width=64 style='width:48pt'>move left</td>
+ <td class=xl801608 width=64 style='width:48pt'>move right</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>zoom out</td>
+ <td class=xl801608 width=64 style='width:48pt'>zoom in</td>
+ <td class=xl1121608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1111608 width=91 style='height:16.5pt;width:68pt'>Mapbuf</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl721608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl1151608 width=64 style='border-top:none;width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1111608 width=91 style='height:16.5pt;width:68pt'>Menu</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1161608 width=91 style='height:16.5pt;width:68pt'>Notify</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl721608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1181608 width=91 style='height:27.0pt;width:68pt'>Panel</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>5</td>
+ <td class=xl1001608 width=64 style='width:48pt'>click</td>
+ <td class=xl791608 width=64 style='width:48pt'>show / hide</td>
+ <td class=xl791608 width=64 style='width:48pt'>show / hide</td>
+ <td class=xl751608 width=64 style='width:48pt'> </td>
+ <td class=xl791608 width=64 style='width:48pt'>show / hide</td>
+ <td class=xl791608 width=64 style='width:48pt'>show / hide</td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl1121608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1181608 width=91 style='height:16.5pt;width:68pt'>Photo</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl1011608 width=64 style='width:48pt'>click</td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl1121608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='mso-height-source:userset;height:27.0pt'>
+ <td height=36 class=xl1181608 width=91 style='height:27.0pt;width:68pt'>Photocam</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>14</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll up</td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll down</td>
+ <td class=xl801608 width=64 style='width:48pt'>move center</td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll left</td>
+ <td class=xl801608 width=64 style='width:48pt'>scroll right</td>
+ <td class=xl801608 width=64 style='width:48pt'>move up small</td>
+ <td class=xl801608 width=64 style='width:48pt'>move down small</td>
+ <td class=xl801608 width=64 style='width:48pt'>move left small</td>
+ <td class=xl801608 width=64 style='width:48pt'>move right small</td>
+ <td class=xl801608 width=64 style='width:48pt'>move to top</td>
+ <td class=xl801608 width=64 style='width:48pt'>move to botton</td>
+ <td class=xl801608 width=64 style='width:48pt'>zoom out</td>
+ <td class=xl801608 width=64 style='width:48pt'>zoom in</td>
+ <td class=xl1201608 width=64 style='width:48pt'>fill window</td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1211608 width=91 style='height:16.5pt;width:68pt'>Popup</td>
+ <td class=xl771608 width=78 style='border-left:none;width:59pt'>button name</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl1011608 width=64 style='width:48pt'>click</td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl1151608 width=64 style='border-top:none;width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1171608 width=91 style='height:16.5pt;border-top:none;
+ width:68pt'>Progress bar</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl721608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1211608 width=91 style='height:16.5pt;width:68pt'>Radio</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl1021608 width=64 style='width:48pt'>click</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1161608 width=91 style='height:16.5pt;border-top:none;
+ width:68pt'>Route</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1221608 width=91 style='height:27.0pt;width:68pt'>SegmentControl</td>
+ <td class=xl771608 width=78 style='border-left:none;width:59pt'>button name</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl1021608 width=64 style='width:48pt'>click</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1181608 width=91 style='height:16.5pt;width:68pt'>Separator</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=53 style='height:39.75pt'>
+ <td height=53 class=xl1221608 width=91 style='height:39.75pt;width:68pt'>Slider</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>11</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl801608 width=64 style='width:48pt'>move up more</td>
+ <td class=xl801608 width=64 style='width:48pt'>move down <br>
+ more</td>
+ <td class=xl801608 width=64 style='width:48pt'>move center</td>
+ <td class=xl801608 width=64 style='width:48pt'>move left more</td>
+ <td class=xl801608 width=64 style='width:48pt'>move right more</td>
+ <td class=xl801608 width=64 style='width:48pt'>move up</td>
+ <td class=xl801608 width=64 style='width:48pt'>move down</td>
+ <td class=xl801608 width=64 style='width:48pt'>move left</td>
+ <td class=xl801608 width=64 style='width:48pt'>move right</td>
+ <td class=xl801608 width=64 style='width:48pt'>move home</td>
+ <td class=xl801608 width=64 style='width:48pt'>move end</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1171608 width=91 style='height:16.5pt;border-top:none;
+ width:68pt'>Slideshow</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='height:27.0pt'>
+ <td height=36 class=xl1181608 width=91 style='height:27.0pt;width:68pt'>Spinner</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>6</td>
+ <td class=xl721608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl791608 width=64 style='width:48pt'>click left</td>
+ <td class=xl791608 width=64 style='width:48pt'>click right</td>
+ <td class=xl791608 width=64 style='width:48pt'>click left</td>
+ <td class=xl791608 width=64 style='width:48pt'>click right</td>
+ <td class=xl791608 width=64 style='width:48pt'>move start</td>
+ <td class=xl791608 width=64 style='width:48pt'>move end</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1231608 width=91 style='height:16.5pt;width:68pt'>Thumbnail</td>
+ <td class=xl701608 width=78 style='border-left:none;width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl1021608 width=64 style='width:48pt'>click</td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl731608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=36 style='mso-height-source:userset;height:27.0pt'>
+ <td height=36 class=xl1171608 width=91 style='height:27.0pt;width:68pt'>Toolbar</td>
+ <td class=xl771608 width=78 style='border-left:none;width:59pt'>button name</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>10</td>
+ <td class=xl931608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl1031608 width=64 style='width:48pt'>move up more</td>
+ <td class=xl1031608 width=64 style='width:48pt'>move down <br>
+ more</td>
+ <td class=xl871608 width=64 style='width:48pt'> </td>
+ <td class=xl1031608 width=64 style='width:48pt'>move left more</td>
+ <td class=xl1031608 width=64 style='width:48pt'>move right more</td>
+ <td class=xl1011608 width=64 style='border-top:none;width:48pt'>moves up</td>
+ <td class=xl1011608 width=64 style='border-top:none;width:48pt'>move down</td>
+ <td class=xl1011608 width=64 style='border-top:none;width:48pt'>move left</td>
+ <td class=xl1011608 width=64 style='border-top:none;width:48pt'>move right</td>
+ <td class=xl1011608 width=64 style='border-top:none;width:48pt'>move top</td>
+ <td class=xl1011608 width=64 style='border-top:none;width:48pt'>move bottom</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1161608 width=91 style='height:16.5pt;border-top:none;
+ width:68pt'>Tooltips</td>
+ <td class=xl701608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl721608 width=64 style='border-left:none;width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1241608 width=91 style='height:16.5pt;width:68pt'>video</td>
+ <td class=xl771608 width=78 style='border-left:none;width:59pt'>button name</td>
+ <td class=xl711608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>1</td>
+ <td class=xl971608 width=64 style='border-left:none;width:48pt'>click</td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl941608 width=64 style='width:48pt'> </td>
+ <td class=xl1151608 width=64 style='width:48pt'> </td>
+ </tr>
+ <tr height=22 style='height:16.5pt'>
+ <td height=22 class=xl1251608 width=91 style='height:16.5pt;border-top:none;
+ width:68pt'>Web</td>
+ <td class=xl1261608 width=78 style='border-top:none;border-left:none;
+ width:59pt'>-</td>
+ <td class=xl1271608 width=64 style='border-top:none;border-left:none;
+ width:48pt'>None</td>
+ <td class=xl1281608 width=64 style='border-top:none;width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1281608 width=64 style='width:48pt'> </td>
+ <td class=xl1291608 width=64 style='width:48pt'> </td>
+ </tr>
+ <![if supportMisalignedColumns]>
+ <tr height=0 style='display:none'>
+ <td width=91 style='width:68pt'></td>
+ <td width=78 style='width:59pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ <td width=64 style='width:48pt'></td>
+ </tr>
+ <![endif]>
+</table>
+
+</div>
+
+
+<!----------------------------->
+<!--END OF OUTPUT FROM EXCEL PUBLISH AS WEB PAGE WIZARD-->
+<!----------------------------->
+</body>
+
+</html>
+
+*
+* @endhtmlonly
+* @}
+*/
--- /dev/null
+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)
--- /dev/null
+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}
--- /dev/null
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef VOICE_CONTROL_ELEMENTARY_H_
+#define VOICE_CONTROL_ELEMENTARY_H_
+
+
+#include <Elementary.h>
+#include <Evas.h>
+#include <tizen.h>
+
+/**
+* @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_ */
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_" />
+ </request>
+</manifest>
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_" />
+ </request>
+</manifest>
--- /dev/null
+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
--- /dev/null
+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})
--- /dev/null
+/*
+ * 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 <voice_control_elm.h>
+
+#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 <voice_control_widget.h>
+
+/**
+* @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
--- /dev/null
+/*
+ * 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 <voice_control_elm.h>
+/**
+ * @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__*/
--- /dev/null
+/*
+ * 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 <assert.h>
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <Ecore_Evas.h>
+#include <libxml/parser.h>
+
+#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;
+}
--- /dev/null
+/*
+ * 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 <voice_control_elm.h>
+/**
+ * @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__*/
--- /dev/null
+/*
+ * 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 <math.h>
+#include <limits.h>
+#include <libintl.h>
+
+#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;
+}
--- /dev/null
+/*
+ * 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 <Eina.h>
+#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_X.h>
+#include <Elementary.h>
+#include <dlog.h>
+
+#define ELM_INTERNAL_API_ARGESFSDFEFC
+#include <elm_widget.h>
+#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__*/
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__*/
--- /dev/null
+/*
+ * 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 <voice_control_elm.h>
+#include <stdlib.h>
+#include <math.h>
+
+#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[] = "<font_size=24><font color=\"black\">";
+ const char font_post[] = "</font></font_size>";
+
+ 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);
+ }
+}
--- /dev/null
+/*
+ * 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__*/
--- /dev/null
+/*
+ * 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 <voice_control_widget.h>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <stdbool.h>
+
+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__*/
--- /dev/null
+<?xml version="1.0"?>
+<voice-control-elm>
+ <voice-control-elm-config>
+ <action-list>
+ <action>
+ <action-name>click</action-name>
+ <action-command/>
+ </action>
+ <action>
+ <action-name>scroll_up</action-name>
+ <action-command>scroll up</action-command>
+ </action>
+ <action>
+ <action-name>scroll_down</action-name>
+ <action-command>scroll down</action-command>
+ </action>
+ <action>
+ <action-name>center</action-name>
+ <action-command>center</action-command>
+ </action>
+ <action>
+ <action-name>scroll_left</action-name>
+ <action-command>scroll left</action-command>
+ </action>
+ <action>
+ <action-name>scroll_right</action-name>
+ <action-command>scroll right</action-command>
+ </action>
+ <action>
+ <action-name>up</action-name>
+ <action-command>up</action-command>
+ </action>
+ <action>
+ <action-name>down</action-name>
+ <action-command>down</action-command>
+ </action>
+ <action>
+ <action-name>left</action-name>
+ <action-command>left</action-command>
+ </action>
+ <action>
+ <action-name>right</action-name>
+ <action-command>right</action-command>
+ </action>
+ <action>
+ <action-name>top</action-name>
+ <action-command>top</action-command>
+ </action>
+ <action>
+ <action-name>bottom</action-name>
+ <action-command>bottom</action-command>
+ </action>
+ <action>
+ <action-name>zoom_out</action-name>
+ <action-command>zoom out</action-command>
+ </action>
+ <action>
+ <action-name>zoom_in</action-name>
+ <action-command>zoom in</action-command>
+ </action>
+ <action>
+ <action-name>fill</action-name>
+ <action-command>fill</action-command>
+ </action>
+ </action-list>
+ <widget-list>
+ <widget>
+ <widget-name>Elm_Bubble</widget-name>
+ <actions>
+ <action-name>click</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_Button</widget-name>
+ <actions>
+ <action-name>click</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_Check</widget-name>
+ <actions>
+ <action-name>click</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_Entry</widget-name>
+ <actions>
+ <action-name>click</action-name>
+ <action-name>up</action-name>
+ <action-name>down</action-name>
+ <action-name>scroll_up</action-name>
+ <action-name>scroll_down</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_Gengrid</widget-name>
+ <actions>
+ <action-name>scroll_up</action-name>
+ <action-name>scroll_down</action-name>
+ <action-name>up</action-name>
+ <action-name>down</action-name>
+ <action-name>top</action-name>
+ <action-name>bottom</action-name>
+ <action-name>left</action-name>
+ <action-name>right</action-name>
+ <action-name>scroll_left</action-name>
+ <action-name>scroll_right</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_Genlist</widget-name>
+ <actions>
+ <action-name>click</action-name>
+ <action-name>scroll_up</action-name>
+ <action-name>scroll_down</action-name>
+ <action-name>up</action-name>
+ <action-name>down</action-name>
+ <action-name>top</action-name>
+ <action-name>bottom</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_Label</widget-name>
+ <actions>
+ <action-name>null</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_List</widget-name>
+ <actions>
+ <action-name>scroll_up</action-name>
+ <action-name>scroll_down</action-name>
+ <action-name>up</action-name>
+ <action-name>down</action-name>
+ <action-name>top</action-name>
+ <action-name>bottom</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_Radio</widget-name>
+ <actions>
+ <action-name>click</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_Scroller</widget-name>
+ <actions>
+ <action-name>up</action-name>
+ <action-name>down</action-name>
+ <action-name>left</action-name>
+ <action-name>right</action-name>
+ <action-name>top</action-name>
+ <action-name>bottom</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_Slider</widget-name>
+ <actions>
+ <action-name>up</action-name>
+ <action-name>down</action-name>
+ <action-name>left</action-name>
+ <action-name>right</action-name>
+ <action-name>top</action-name>
+ <action-name>bottom</action-name>
+ <action-name>scroll_up</action-name>
+ <action-name>scroll_down</action-name>
+ <action-name>scroll_right</action-name>
+ <action-name>scroll_left</action-name>
+ <action-name>center</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_Spinner</widget-name>
+ <actions>
+ <action-name>up</action-name>
+ <action-name>down</action-name>
+ <action-name>left</action-name>
+ <action-name>right</action-name>
+ <action-name>top</action-name>
+ <action-name>bottom</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>Elm_Toolbar</widget-name>
+ <actions>
+ <action-name>up</action-name>
+ <action-name>down</action-name>
+ <action-name>top</action-name>
+ <action-name>bottom</action-name>
+ <action-name>scroll_left</action-name>
+ <action-name>scroll_right</action-name>
+ <action-name>right</action-name>
+ <action-name>left</action-name>
+ <action-name>scroll_up</action-name>
+ <action-name>scroll_down</action-name>
+ </actions>
+ </widget>
+ <widget>
+ <widget-name>elm_item</widget-name>
+ <actions>
+ <action-name>click</action-name>
+ </actions>
+ </widget>
+ </widget-list>
+ <hint>
+ <hint-show>on</hint-show>
+ <default-hint-direction>center</default-hint-direction>
+ <default-hint-image>/usr/share/voice/vc-elm/image.png</default-hint-image>
+ </hint>
+ </voice-control-elm-config>
+ <voice-control-elm-info>
+ <tizen-version>2.4</tizen-version>
+ <profile>TV</profile>
+ <efl-version>1.12</efl-version>
+ </voice-control-elm-info>
+</voice-control-elm>