Upload initial version 95/262095/1
authorJihoon Kim <jihoon48.kim@samsung.com>
Thu, 6 May 2021 10:39:12 +0000 (19:39 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Tue, 3 Aug 2021 02:00:16 +0000 (11:00 +0900)
Change-Id: I28892702bf366c803c7f6c20f7d947a5003d3720
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
192 files changed:
AUTHORS [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
LICENSE [new file with mode: 0644]
NEWS [new file with mode: 0644]
NOTICE [new file with mode: 0644]
README [new file with mode: 0644]
capi/CMakeLists.txt [new file with mode: 0644]
capi/include/cscl-ui-controller.h [new file with mode: 0644]
capi/include/cscl-ui-event-callback.h [new file with mode: 0644]
capi/include/cscl-ui-graphics-backend.h [new file with mode: 0644]
capi/include/cscl-ui-nui.h [new file with mode: 0644]
capi/include/cscl-ui-win.h [new file with mode: 0644]
capi/include/cscl-ui-window-backend.h [new file with mode: 0644]
capi/scl-ui-nui-capi.pc.in [new file with mode: 0644]
capi/src/cscl-ui-controller.cpp [new file with mode: 0644]
capi/src/cscl-ui-nui.cpp [new file with mode: 0644]
libscl-ui-nui.manifest [new file with mode: 0644]
libscl-ui-nui.pc.in [new file with mode: 0644]
packaging/libscl-ui-nui.changes [new file with mode: 0644]
packaging/libscl-ui-nui.spec [new file with mode: 0644]
res/put_record.h [new file with mode: 0644]
res/sclresource.cpp [new file with mode: 0644]
res/sclresource.h [new file with mode: 0644]
res/sclresourcekeys.h [new file with mode: 0644]
res/simple_debug.cpp [new file with mode: 0644]
res/simple_debug.h [new file with mode: 0644]
res/simple_debug_test.cpp [new file with mode: 0644]
scl/_auto_metadata.h [new file with mode: 0644]
scl/autopopup_configure_bin_parser.cpp [new file with mode: 0644]
scl/autopopup_configure_bin_parser.h [new file with mode: 0644]
scl/autopopup_configure_parser.cpp [new file with mode: 0644]
scl/autopopup_configure_parser.h [new file with mode: 0644]
scl/binary_xmlresource.cpp [new file with mode: 0644]
scl/binary_xmlresource.h [new file with mode: 0644]
scl/default_configure_bin_parser.cpp [new file with mode: 0644]
scl/default_configure_bin_parser.h [new file with mode: 0644]
scl/default_configure_parser.cpp [new file with mode: 0644]
scl/default_configure_parser.h [new file with mode: 0644]
scl/file_storage.cpp [new file with mode: 0644]
scl/file_storage.h [new file with mode: 0644]
scl/file_storage_impl.h [new file with mode: 0644]
scl/imetadata_provider.h [new file with mode: 0644]
scl/input_mode_configure_bin_parser.cpp [new file with mode: 0644]
scl/input_mode_configure_bin_parser.h [new file with mode: 0644]
scl/input_mode_configure_parser.cpp [new file with mode: 0644]
scl/input_mode_configure_parser.h [new file with mode: 0644]
scl/iparserinfo_provider.h [new file with mode: 0644]
scl/istring_collector.h [new file with mode: 0644]
scl/istring_provider.h [new file with mode: 0644]
scl/key_coordinate_frame_bin_parser.cpp [new file with mode: 0644]
scl/key_coordinate_frame_bin_parser.h [new file with mode: 0644]
scl/label_properties_bin_parser.cpp [new file with mode: 0644]
scl/label_properties_bin_parser.h [new file with mode: 0644]
scl/label_properties_parser.cpp [new file with mode: 0644]
scl/label_properties_parser.h [new file with mode: 0644]
scl/layout_bin_parser.cpp [new file with mode: 0644]
scl/layout_bin_parser.h [new file with mode: 0644]
scl/layout_parser.cpp [new file with mode: 0644]
scl/layout_parser.h [new file with mode: 0644]
scl/layout_parser_helper.cpp [new file with mode: 0644]
scl/layout_parser_helper.h [new file with mode: 0644]
scl/magnifier_configure_bin_parser.cpp [new file with mode: 0644]
scl/magnifier_configure_bin_parser.h [new file with mode: 0644]
scl/magnifier_configure_parser.cpp [new file with mode: 0644]
scl/magnifier_configure_parser.h [new file with mode: 0644]
scl/main_entry_parser.cpp [new file with mode: 0644]
scl/main_entry_parser.h [new file with mode: 0644]
scl/metadata.h [new file with mode: 0644]
scl/metadata_bin_parser.cpp [new file with mode: 0644]
scl/metadata_bin_parser.h [new file with mode: 0644]
scl/metadata_provider.h [new file with mode: 0644]
scl/modifier_decoration_bin_parser.cpp [new file with mode: 0644]
scl/modifier_decoration_bin_parser.h [new file with mode: 0644]
scl/modifier_decoration_parser.cpp [new file with mode: 0644]
scl/modifier_decoration_parser.h [new file with mode: 0644]
scl/nine_patch_file_list_bin_parser.cpp [new file with mode: 0644]
scl/nine_patch_file_list_bin_parser.h [new file with mode: 0644]
scl/nine_patch_file_list_parser.cpp [new file with mode: 0644]
scl/nine_patch_file_list_parser.h [new file with mode: 0644]
scl/parserinfo_provider.h [new file with mode: 0644]
scl/sclactionstate.cpp [new file with mode: 0644]
scl/sclactionstate.h [new file with mode: 0644]
scl/sclanimator-nui.cpp [new file with mode: 0644]
scl/sclanimator-nui.h [new file with mode: 0644]
scl/sclanimator.cpp [new file with mode: 0644]
scl/sclanimator.h [new file with mode: 0644]
scl/sclbackendcallback.h [new file with mode: 0644]
scl/sclconfig.h [new file with mode: 0644]
scl/sclcontext.cpp [new file with mode: 0644]
scl/sclcontext.h [new file with mode: 0644]
scl/sclcontroller.cpp [new file with mode: 0644]
scl/sclcontroller.h [new file with mode: 0644]
scl/scldebug.cpp [new file with mode: 0644]
scl/scldebug.h [new file with mode: 0644]
scl/scleffect.cpp [new file with mode: 0644]
scl/scleffect.h [new file with mode: 0644]
scl/sclerroradjustment.cpp [new file with mode: 0644]
scl/sclerroradjustment.h [new file with mode: 0644]
scl/scleventcallback.h [new file with mode: 0644]
scl/scleventhandler.cpp [new file with mode: 0644]
scl/scleventhandler.h [new file with mode: 0644]
scl/sclevents-nui.cpp [new file with mode: 0644]
scl/sclevents-nui.h [new file with mode: 0644]
scl/sclevents.cpp [new file with mode: 0644]
scl/sclevents.h [new file with mode: 0644]
scl/sclfeedback.cpp [new file with mode: 0644]
scl/sclfeedback.h [new file with mode: 0644]
scl/sclfontproxy.cpp [new file with mode: 0644]
scl/sclfontproxy.h [new file with mode: 0644]
scl/sclgraphics-nui.cpp [new file with mode: 0644]
scl/sclgraphics-nui.h [new file with mode: 0644]
scl/sclgraphics.cpp [new file with mode: 0644]
scl/sclgraphics.h [new file with mode: 0644]
scl/sclgraphicsbackendcallback.h [new file with mode: 0644]
scl/sclgraphicsinfo.h [new file with mode: 0644]
scl/sclgwes.cpp [new file with mode: 0644]
scl/sclgwes.h [new file with mode: 0644]
scl/sclheaders.h [new file with mode: 0644]
scl/sclimageproxy.cpp [new file with mode: 0644]
scl/sclimageproxy.h [new file with mode: 0644]
scl/sclintl.h [new file with mode: 0644]
scl/sclkeydefines.h [new file with mode: 0644]
scl/sclkeyfocushandler.cpp [new file with mode: 0644]
scl/sclkeyfocushandler.h [new file with mode: 0644]
scl/sclres.cpp [new file with mode: 0644]
scl/sclres.h [new file with mode: 0644]
scl/sclres_manager.cpp [new file with mode: 0644]
scl/sclres_manager.h [new file with mode: 0644]
scl/sclres_type.h [new file with mode: 0644]
scl/sclresourcecache.cpp [new file with mode: 0644]
scl/sclresourcecache.h [new file with mode: 0644]
scl/sclstructs.h [new file with mode: 0644]
scl/sclui.cpp [new file with mode: 0644]
scl/sclui.h [new file with mode: 0644]
scl/scluibuilder.cpp [new file with mode: 0644]
scl/scluibuilder.h [new file with mode: 0644]
scl/scluiimpl.cpp [new file with mode: 0644]
scl/scluiimpl.h [new file with mode: 0644]
scl/sclutils-linux.cpp [new file with mode: 0644]
scl/sclutils.cpp [new file with mode: 0644]
scl/sclutils.h [new file with mode: 0644]
scl/sclversion.h [new file with mode: 0644]
scl/sclwindowbackendcallback.h [new file with mode: 0644]
scl/sclwindows-nui.cpp [new file with mode: 0644]
scl/sclwindows-nui.h [new file with mode: 0644]
scl/sclwindows.cpp [new file with mode: 0644]
scl/sclwindows.h [new file with mode: 0644]
scl/string_bin_parser.cpp [new file with mode: 0644]
scl/string_bin_parser.h [new file with mode: 0644]
scl/string_collector.h [new file with mode: 0644]
scl/string_provider.h [new file with mode: 0644]
scl/xml_parser_utils.cpp [new file with mode: 0644]
scl/xml_parser_utils.h [new file with mode: 0644]
scl/xmlresource.cpp [new file with mode: 0644]
scl/xmlresource.h [new file with mode: 0644]
xml2binary/CMakeLists.txt [new file with mode: 0644]
xml2binary/data/auto_codes.py [new file with mode: 0755]
xml2binary/data/metadata.xml [new file with mode: 0644]
xml2binary/encode_autopopup_configure.cpp [new file with mode: 0644]
xml2binary/encode_default_configure.cpp [new file with mode: 0644]
xml2binary/encode_input_mode_configure.cpp [new file with mode: 0644]
xml2binary/encode_key_coordinate_frame.cpp [new file with mode: 0644]
xml2binary/encode_label_properties_frame.cpp [new file with mode: 0644]
xml2binary/encode_layout.cpp [new file with mode: 0644]
xml2binary/encode_magnifier_configure.cpp [new file with mode: 0644]
xml2binary/encode_metadata.cpp [new file with mode: 0644]
xml2binary/encode_modifier_decoration.cpp [new file with mode: 0644]
xml2binary/encode_nine_patch.cpp [new file with mode: 0644]
xml2binary/include/_auto_metadata.h [new file with mode: 0644]
xml2binary/include/encode_autopopup_configure.h [new file with mode: 0644]
xml2binary/include/encode_default_configure.h [new file with mode: 0644]
xml2binary/include/encode_input_mode_configure.h [new file with mode: 0644]
xml2binary/include/encode_key_coordinate_frame.h [new file with mode: 0644]
xml2binary/include/encode_label_properties_frame.h [new file with mode: 0644]
xml2binary/include/encode_layout.h [new file with mode: 0644]
xml2binary/include/encode_magnifier_configure.h [new file with mode: 0644]
xml2binary/include/encode_metadata.h [new file with mode: 0644]
xml2binary/include/encode_modifier_decoration.h [new file with mode: 0644]
xml2binary/include/encode_nine_patch.h [new file with mode: 0644]
xml2binary/include/imetadata_encoder.h [new file with mode: 0644]
xml2binary/include/imetadata_helper.h [new file with mode: 0644]
xml2binary/include/imetadata_parser.h [new file with mode: 0644]
xml2binary/include/istring_encoder.h [new file with mode: 0644]
xml2binary/include/metadata.h [new file with mode: 0644]
xml2binary/include/metadata_handler.h [new file with mode: 0644]
xml2binary/include/resource_storage.h [new file with mode: 0644]
xml2binary/include/resource_storage_impl.h [new file with mode: 0644]
xml2binary/include/string_encoder.h [new file with mode: 0644]
xml2binary/metadata_handler.cpp [new file with mode: 0644]
xml2binary/xml2dat.cpp [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..e28dee6
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+Developer:
+  Ji-hoon Lee <dalton.lee at samsung dot com>
+  Yanjie Hu <yanjie.hu at samsung dot com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0d1297b
--- /dev/null
@@ -0,0 +1,153 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(libscl-ui-nui CXX)
+
+SET(SRCS
+    scl/sclres_manager.cpp
+    scl/sclres.cpp
+    scl/main_entry_parser.cpp
+    scl/input_mode_configure_parser.cpp
+    scl/layout_parser.cpp
+    scl/layout_parser_helper.cpp
+    scl/modifier_decoration_parser.cpp
+    scl/label_properties_parser.cpp
+    scl/default_configure_parser.cpp
+    scl/autopopup_configure_parser.cpp
+    scl/magnifier_configure_parser.cpp
+    scl/nine_patch_file_list_parser.cpp
+    scl/xmlresource.cpp
+    scl/xml_parser_utils.cpp
+    scl/string_bin_parser.cpp
+    scl/metadata_bin_parser.cpp
+    scl/input_mode_configure_bin_parser.cpp
+    scl/layout_bin_parser.cpp
+    scl/key_coordinate_frame_bin_parser.cpp
+    scl/modifier_decoration_bin_parser.cpp
+    scl/label_properties_bin_parser.cpp
+    scl/default_configure_bin_parser.cpp
+    scl/autopopup_configure_bin_parser.cpp
+    scl/magnifier_configure_bin_parser.cpp
+    scl/nine_patch_file_list_bin_parser.cpp
+    scl/binary_xmlresource.cpp
+    scl/file_storage.cpp
+    scl/sclerroradjustment.cpp
+    scl/sclutils-linux.cpp
+    scl/scldebug.cpp
+    scl/sclutils.cpp
+    scl/sclcontroller.cpp
+    scl/sclgwes.cpp
+    scl/sclevents.cpp
+#    scl/sclwindows-efl.cpp
+#    scl/sclgraphics-efl.cpp
+#    scl/sclanimator-efl.cpp
+#    scl/sclevents-efl.cpp
+
+    scl/sclwindows-nui.cpp
+    scl/sclgraphics-nui.cpp
+    scl/sclanimator-nui.cpp
+    scl/sclevents-nui.cpp
+
+    scl/sclfeedback.cpp
+    scl/scluibuilder.cpp
+    scl/scluiimpl.cpp
+    scl/sclui.cpp
+    scl/scleffect.cpp
+    scl/scleventhandler.cpp
+    scl/sclwindows.cpp
+    scl/sclgraphics.cpp
+    scl/sclimageproxy.cpp
+    scl/sclfontproxy.cpp
+    scl/sclcontext.cpp
+    scl/sclactionstate.cpp
+    scl/sclresourcecache.cpp
+    scl/sclkeyfocushandler.cpp
+    scl/sclanimator.cpp
+    res/sclresource.cpp
+    res/simple_debug.cpp
+)
+
+SET(PACKAGE ${PROJECT_NAME})
+SET(PKGNAME ${PACKAGE})
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(LIBDIR ${LIB_INSTALL_DIR})
+SET(INCLUDEDIR "\${PREFIX}/scl/include")
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+    SET(CMAKE_BUILD_TYPE "Release")
+ENDIF()
+MESSAGE(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src
+                    ${CMAKE_SOURCE_DIR}/src/include
+                    ${CMAKE_SOURCE_DIR}/scl
+                    ${CMAKE_SOURCE_DIR}/scl/include
+                    ${CMAKE_SOURCE_DIR}/xmlresource/include
+                    ${CMAKE_SOURCE_DIR}/binary_xmlresource/include
+                    ${CMAKE_SOURCE_DIR}/binary_xmlresource/include/interface
+                    ${CMAKE_SOURCE_DIR}/sclres
+                    ${CMAKE_SOURCE_DIR}/scl/gwes
+                    ${CMAKE_SOURCE_DIR}/scl/gwes/efl
+                    ${CMAKE_SOURCE_DIR}/res )
+
+INCLUDE(FindPkgConfig)
+SET(PKGS_CHECK_MODULES
+        elementary
+        glib-2.0
+        feedback
+        dlog
+        libxml-2.0
+        tts
+        vconf
+        eldbus
+        libscl-common
+        )
+
+IF (with_wayland)
+        ADD_DEFINITIONS("-DWAYLAND")
+        SET(PKGS_CHECK_MODULES ${PKGS_CHECK_MODULES} ecore-wl2)
+ENDIF(with_wayland)
+
+pkg_check_modules(pkgs REQUIRED ${PKGS_CHECK_MODULES})
+
+FOREACH(flag ${pkgs_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Wno-stringop-truncation")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -g")
+
+ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE}\"")
+ADD_DEFINITIONS("-DPACKAGE_NAME=\"${PKGNAME}\"")
+ADD_DEFINITIONS("-DLOG_TAG=\"LIBSCL_UI\"")
+ADD_DEFINITIONS("-DDEFAULT_THEME=\"default\"")
+ADD_DEFINITIONS("-DIMG_PATH_PREFIX=\"image\"")
+ADD_DEFINITIONS("-D__NUI__")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIBDIR})
+
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclui.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclconfig.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclstructs.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/scleventcallback.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclgraphicsinfo.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclgraphicsbackendcallback.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclwindowbackendcallback.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclutils.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclfeedback.h" DESTINATION include/${name})
+
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclcontroller.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclgwes.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclwindows.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclgraphics.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclevents.h" DESTINATION include/${name})
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclcontext.h" DESTINATION include/${name})
+
+CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIBDIR}/pkgconfig)
+
+ADD_SUBDIRECTORY(capi)
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..5737e30
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,4 @@
+2012-02-21     11:15   Ji-hoon Lee <dalton.lee@samsung.com>
+
+       Initial version.
+
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..7d1c323
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,365 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+
+   Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.  This file is offered as-is,
+without warranty of any kind.
+
+Basic Installation
+==================
+
+   Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.  Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below.  The lack of an optional feature in a given package is not
+necessarily a bug.  More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+   The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package, generally using the just-built uninstalled binaries.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.  When installing into a prefix owned by root, it is
+     recommended that the package be configured and built as a regular
+     user, and only the `make install' phase executed with root
+     privileges.
+
+  5. Optionally, type `make installcheck' to repeat any self-tests, but
+     this time using the binaries in their final installed location.
+     This target does not install anything.  Running this target as a
+     regular user, particularly if the prior `make install' required
+     root privileges, verifies that the installation completed
+     correctly.
+
+  6. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  7. Often, you can also type `make uninstall' to remove the installed
+     files again.  In practice, not all packages have tested that
+     uninstallation works correctly, even though it is required by the
+     GNU Coding Standards.
+
+  8. Some packages, particularly those that use Automake, provide `make
+     distcheck', which can by used by developers to test that all other
+     targets like `make install' and `make uninstall' work correctly.
+     This target is generally not run by end users.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.  This
+is known as a "VPATH" build.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+   By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.  In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+   The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+   The first method involves providing an override variable for each
+affected directory.  For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'.  Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated.  The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+   The second method involves providing the `DESTDIR' variable.  For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names.  The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters.  On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+   Some packages offer the ability to configure how verbose the
+execution of `make' will be.  For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
+a workaround.  If GNU CC is not installed, it is therefore recommended
+to try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
+   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+   On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'.  It is recommended to use the following options:
+
+     ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS
+     KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+     Print a summary of the options unique to this package's
+     `configure', and exit.  The `short' variant lists options used
+     only in the top level, while the `recursive' variant lists options
+     also present in any nested packages.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+     Use DIR as the installation prefix.  *note Installation Names::
+     for more details, including other options available for fine-tuning
+     the installation locations.
+
+`--no-create'
+`-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..1eeae25
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE file for Apache License terms and conditions.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..9ed1ede
--- /dev/null
+++ b/README
@@ -0,0 +1,5 @@
+libscl-ui
+==============
+
+This is a library that helps developing S/W Keyboards.
+
diff --git a/capi/CMakeLists.txt b/capi/CMakeLists.txt
new file mode 100644 (file)
index 0000000..42717f8
--- /dev/null
@@ -0,0 +1,83 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(scl-ui-nui-capi CXX)
+
+# Find Packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+    elementary
+    glib-2.0
+    feedback
+    dlog
+    libxml-2.0
+    tts
+    vconf
+    eldbus
+    libscl-common
+    ecore-wl2
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++11")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
+
+#SET(CAPI_LIBSCL_UI_NUI inputmethod_unittests)
+
+SET(fw_name "scl-ui-nui-capi")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DTIZEN_DEBUG")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib")
+
+AUX_SOURCE_DIRECTORY(src SOURCES)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../scl LIBSCL_SOURCES)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../res LIBSCL_RES_SOURCES)
+ADD_LIBRARY(${fw_name} SHARED 
+        ${SOURCES}
+        ${LIBSCL_SOURCES}
+        ${LIBSCL_RES_SOURCES}
+        )
+TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS} ${pkgs_LDFLAGS})
+
+SET_TARGET_PROPERTIES(${fw_name}
+     PROPERTIES
+     VERSION ${FULLVER}
+     SOVERSION ${MAJORVER}
+     CLEAN_DIRECT_OUTPUT 1
+)
+
+INSTALL(TARGETS ${fw_name} DESTINATION ${LIBDIR})
+
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/capi/include/cscl-ui-nui.h" DESTINATION include)
+INSTALL(FILES "${CMAKE_SOURCE_DIR}/capi/include/cscl-ui-controller.h" DESTINATION include)
+
+SET(PC_NAME ${fw_name})
+SET(PC_REQUIRED ${dependents})
+SET(PC_LDFLAGS -l${fw_name})
+
+CONFIGURE_FILE(
+    scl-ui-nui-capi.pc.in
+    ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc
+    @ONLY
+)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIBDIR}/pkgconfig)
+
+#SET(SOURCES "")
+
+#INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../inputmethod/include
+#                    ${CMAKE_CURRENT_SOURCE_DIR}/../remote_input/include)
+
+SET(INC_DIR include)
+INCLUDE_DIRECTORIES(${INC_DIR})
+
+#AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../remote_input/src SCL_UI_SOURCES)
+
+ADD_DEFINITIONS("-DFULLVER=\"${FULLVER}\"")
diff --git a/capi/include/cscl-ui-controller.h b/capi/include/cscl-ui-controller.h
new file mode 100644 (file)
index 0000000..94d2103
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021 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 __SCL_CAPI_CONTROLLER_H__
+#define __SCL_CAPI_CONTROLLER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int scl_controller_mouse_press(int x, int y);
+int scl_controller_mouse_release(int x, int y);
+int scl_controller_mouse_move(int x, int y, int touch_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SCL_CAPI_CONTROLLER_H__ */
diff --git a/capi/include/cscl-ui-event-callback.h b/capi/include/cscl-ui-event-callback.h
new file mode 100644 (file)
index 0000000..9927af4
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021 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 __SCL_EVENT_CALLBACK_H__
+#define __SCL_EVENT_CALLBACK_H__
+
+#include <sclui.h>
+
+class CUIEventCallback : public ISCLUIEventCallback
+{
+public :
+    /*
+    Ecore_Timer* word_timer = NULL;
+    static Eina_Bool _multi_tap_timer_cb(void *data)
+    {
+        LOGD("Time Out");
+        ise_send_event(MVK_Done, KEY_MASK_NULL);
+        return ECORE_CALLBACK_CANCEL;
+    }
+    */
+    SCLEventReturnType on_event_key_clicked(SclUIEventDesc event_desc);
+    SCLEventReturnType on_event_drag_state_changed(SclUIEventDesc event_desc);
+    SCLEventReturnType on_event_notification(SCLUINotiType noti_type, SclNotiDesc *etc_info);
+};
+
+#endif /* __SCL_EVENT_CALLBACK_H__ */
diff --git a/capi/include/cscl-ui-graphics-backend.h b/capi/include/cscl-ui-graphics-backend.h
new file mode 100644 (file)
index 0000000..5da8688
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2021 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 __SCL_GRAPHICS_BACKEND_H__
+#define __SCL_GRAPHICS_BACKEND_H__
+
+#include <sclui.h>
+
+class CUIGraphicsBackendCallback : public ISCLUIGraphicsBackendCallback
+{
+public :
+    void on_draw_text(const SclFontInfo& font_info, const SclColor& color, const char *str, int pos_x, int pos_y, int w, int h,
+                      SCLLabelAlignment align, int padding_x, int padding_y, int inner_width, int inner_height, void* user_data);
+
+    void on_draw_image(const char *image_path, int dest_x, int dest_y, int dest_weight, int dest_height, int src_x, int src_y, int src_width, int src_height, void* user_data);
+
+    void on_draw_rectangle(int pos_x, int pos_y, int width, int height, bool fill, int fill_color_r, int fill_color_g, int fill_color_b, int fill_color_a, void* user_data);
+};
+
+#endif /* __SCL_GRAPHICS_BACKEND_H__ */
diff --git a/capi/include/cscl-ui-nui.h b/capi/include/cscl-ui-nui.h
new file mode 100644 (file)
index 0000000..572bc3b
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2021 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 __SCL_CSHARP_NUI_H__
+#define __SCL_CSHARP_NUI_H__
+
+#include <tizen.h>
+#include <cscl-ui-controller.h>
+
+#define MAX_FONT_NAME_LEN 32
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+typedef struct _FontInfo {
+    char font_name[MAX_FONT_NAME_LEN];
+    short font_size;
+    bool is_italic;
+    bool is_bold;
+} FontInfo;
+
+typedef struct {
+    char r, g, b, a;
+} Color;
+*/
+
+typedef enum _LabelAlignment {
+    LABEL_ALIGN_LEFT_TOP = 0,
+    LABEL_ALIGN_CENTER_TOP,
+    LABEL_ALIGN_RIGHT_TOP,
+    LABEL_ALIGN_LEFT_MIDDLE,
+    LABEL_ALIGN_CENTER_MIDDLE,
+    LABEL_ALIGN_RIGHT_MIDDLE,
+    LABEL_ALIGN_LEFT_BOTTOM,
+    LABEL_ALIGN_CENTER_BOTTOM,
+    LABEL_ALIGN_RIGHT_BOTTOM,
+    MAX_LABEL_ALIGNMENT
+} LabelAlignment;
+
+/* graphics backend */
+typedef void (*scl_nui_draw_text_cb)(const char *font_name, short font_size, bool is_italic, bool is_bold, int r, int g, int b, int a,
+                                     const char *str, int pos_x, int pos_y, int w, int h,
+                                     LabelAlignment align, int padding_x, int padding_y, int inner_width, int inner_height, void* user_data);
+
+typedef void (*scl_nui_draw_image_cb)(const char *image_path, int dest_x, int dest_y, int dest_weight, int dest_height, int src_x, int src_y, int src_width, int src_height, void* user_data);
+typedef void (*scl_nui_draw_rectangle_cb)(int pos_x, int pos_y, int width, int height, bool fill, int fill_color_r, int fill_color_g, int fill_color_b, int fill_color_a, void* user_data);
+
+/* window backend */
+typedef void (*scl_nui_update_window_cb)(int x, int y, int width, int height, void* user_data);
+
+int scl_nui_init(const char *entry_filepath);
+int scl_nui_fini();
+
+int scl_nui_set_input_mode(const char *input_mode);
+int scl_nui_set_update_pending(bool pend);
+
+int scl_nui_set_draw_text_cb(scl_nui_draw_text_cb callback, void *user_data);
+int scl_nui_set_draw_image_cb(scl_nui_draw_image_cb callback, void *user_data);
+int scl_nui_set_draw_rectangle_cb(scl_nui_draw_rectangle_cb callback, void *user_data);
+
+int scl_nui_set_cur_sublayout(const char *sub_layout_name);
+int scl_nui_set_string_substitution(const char *original, const char *substitute);
+
+int scl_nui_set_update_window_cb(scl_nui_update_window_cb callback, void *user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SCL_CSHARP_NUI_H__ */
diff --git a/capi/include/cscl-ui-win.h b/capi/include/cscl-ui-win.h
new file mode 100644 (file)
index 0000000..f971ed9
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021 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 __SCL_CAPI_WIN_H__
+#define __SCL_CAPI_WIN_H__
+
+#include "Evas.h"
+
+Evas_Object *get_main_window();
+
+#endif /* __SCL_CAPI_WIN_H__ */
diff --git a/capi/include/cscl-ui-window-backend.h b/capi/include/cscl-ui-window-backend.h
new file mode 100644 (file)
index 0000000..337e4e9
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021 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 __SCL_WINDOW_BACKEND_H__
+#define __SCL_WINDOW_BACKEND_H__
+
+#include <sclui.h>
+
+class CUIWindowBackendCallback : public ISCLUIWindowBackendCallback
+{
+public :
+    void update_window(int x, int y, int width, int height, void* user_data);
+};
+
+#endif /* __SCL_WINDOW_BACKEND_H__ */
diff --git a/capi/scl-ui-nui-capi.pc.in b/capi/scl-ui-nui-capi.pc.in
new file mode 100644 (file)
index 0000000..7740411
--- /dev/null
@@ -0,0 +1,14 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=@LIBDIR@
+includedir=/usr/include
+
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir}
+
diff --git a/capi/src/cscl-ui-controller.cpp b/capi/src/cscl-ui-controller.cpp
new file mode 100644 (file)
index 0000000..faaf68c
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2021 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 <dlog.h>
+#include <tizen.h>
+#include "cscl-ui-controller.h"
+#include "sclcontroller.h"
+#include "cscl-ui-win.h"
+
+using namespace std;
+using namespace scl;
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "CSCLUINUI"
+
+EXPORT_API int scl_controller_mouse_press(int x, int y)
+{
+    LOGD("mouse down x:%d, y:%d", x, y);
+    //return 0;
+
+    CSCLController *controller = CSCLController::get_instance();
+    if (controller) {
+        LOGD("mouse down x:%d, y:%d", x, y);
+        controller->mouse_press(get_main_window(), x, y);
+        return 0;
+    }
+    else {
+        LOGW("No controller");
+        return 1;
+    }
+}
+
+
+EXPORT_API int scl_controller_mouse_release(int x, int y)
+{
+    LOGD("mouse release x:%d, y:%d", x, y);
+
+    CSCLController *controller = CSCLController::get_instance();
+    if (controller) {
+        LOGD("mouse release x:%d, y:%d", x, y);
+        controller->mouse_release(get_main_window(), x, y);
+        return 0;
+    }
+    else {
+        LOGW("No controller");
+        return 1;
+    }
+}
+
+EXPORT_API int scl_controller_mouse_move(int x, int y, int touch_id)
+{
+    CSCLController *controller = CSCLController::get_instance();
+    LOGD("mouse move x:%d, y:%d", x, y);
+
+    if (controller) {
+        LOGD("mouse move x:%d, y:%d", x, y);
+        controller->mouse_move(get_main_window(), x, y, touch_id);
+        return 0;
+    }
+    else {
+        LOGW("No controller");
+        return 1;
+    }
+}
diff --git a/capi/src/cscl-ui-nui.cpp b/capi/src/cscl-ui-nui.cpp
new file mode 100644 (file)
index 0000000..02f4d7d
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2021 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 <dlog.h>
+#include <sclui.h>
+#include <Elementary.h>
+#include "cscl-ui-nui.h"
+#include "cscl-ui-graphics-backend.h"
+#include "cscl-ui-window-backend.h"
+#include "cscl-ui-event-callback.h"
+
+using namespace std;
+using namespace scl;
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "CSCLUINUI"
+
+#define USE_ELM_WIN 1
+
+#ifdef USE_ELM_WIN
+static Evas_Object *g_win = NULL;
+#endif
+
+static CSCLUI *g_ui = NULL;
+
+static scl_nui_draw_text_cb g_draw_text_cb;
+static void *g_draw_text_cb_data = NULL;
+
+static scl_nui_draw_image_cb g_draw_image_cb = NULL;
+static void *g_draw_image_cb_data = NULL;
+
+static scl_nui_draw_rectangle_cb g_draw_rectangle_cb = NULL;
+static void *g_draw_rectangle_cb_data = NULL;
+
+static scl_nui_update_window_cb g_update_window_cb = NULL;
+static void *g_update_window_cb_data = NULL;
+
+void CUIGraphicsBackendCallback::on_draw_text(const SclFontInfo& font_info, const SclColor& color, const char *str, int pos_x, int pos_y, int w, int h,
+                                      SCLLabelAlignment align, int padding_x, int padding_y, int inner_width, int inner_height, void* user_data)
+                      //const char *str, int x, int y, int w, int h, int fontsize, void* user_data)
+{
+    LOGD("draw text : %p", g_draw_text_cb);
+    if (g_draw_text_cb) {
+        //g_draw_text_cb(str, pos_x, pos_y, w, h, font_info.font_size, user_data);
+        /*
+        FontInfo fi;
+        strcpy(fi.font_name, font_info.font_name);
+        fi.font_size = font_info.font_size;
+        fi.is_bold = font_info.is_bold;
+        fi.is_italic = font_info.is_italic;
+
+        Color ci;
+        ci.a = color.a;
+        ci.b = color.b;
+        ci.g = color.g;
+        ci.r = color.r;
+        */
+
+        /*
+        g_draw_text_cb(fi, ci, str, pos_x, pos_y, w, h,
+                       (LabelAlignment)align, padding_x, padding_y, inner_width, inner_height, user_data);
+        */
+        g_draw_text_cb(font_info.font_name, font_info.font_size, font_info.is_bold, font_info.is_italic,
+                       color.r, color.g, color.b, color.a,
+                       str, pos_x, pos_y, w, h,
+                       (LabelAlignment)align, padding_x, padding_y, inner_width, inner_height, user_data);
+    }
+}
+
+void CUIGraphicsBackendCallback::on_draw_image(const char *image_path, int dest_x, int dest_y, int dest_weight, int dest_height, int src_x, int src_y, int src_width, int src_height, void* user_data)
+{
+    LOGD("draw image : %p", g_draw_image_cb);
+    if (g_draw_image_cb) {
+        g_draw_image_cb(image_path, dest_x, dest_y, dest_weight, dest_height, src_x, src_y, src_width, src_height, user_data);
+    }
+}
+
+void CUIGraphicsBackendCallback::on_draw_rectangle(int pos_x, int pos_y, int width, int height, bool fill, int fill_color_r, int fill_color_g, int fill_color_b, int fill_color_a, void* user_data)
+{
+    LOGD("draw rectangle : %p", g_draw_rectangle_cb);
+    if (g_draw_rectangle_cb) {
+        g_draw_rectangle_cb(pos_x, pos_y, width, height,
+                            fill, fill_color_r, fill_color_g, fill_color_b, fill_color_a, user_data);
+    }
+}
+
+void CUIWindowBackendCallback::update_window(int x, int y, int width, int height, void* user_data)
+{
+    LOGD("update_window : %p", g_update_window_cb);
+    if (g_update_window_cb) {
+        g_update_window_cb(x, y, width, height, user_data);
+    }
+}
+
+SCLEventReturnType CUIEventCallback::on_event_key_clicked(SclUIEventDesc event_desc)
+{
+    LOGI("");
+    return SCL_EVENT_PASS_ON;
+}
+
+SCLEventReturnType CUIEventCallback::on_event_notification(SCLUINotiType noti_type, SclNotiDesc *etc_info)
+{
+    LOGI("");
+    return SCL_EVENT_PASS_ON;
+}
+
+SCLEventReturnType CUIEventCallback::on_event_drag_state_changed(SclUIEventDesc event_desc)
+{
+    LOGI("");
+    return SCL_EVENT_PASS_ON;
+}
+
+static CUIGraphicsBackendCallback callback;
+
+static CUIWindowBackendCallback window_callback;
+
+static CUIEventCallback event_callback;
+
+Evas_Object *get_main_window()
+{
+    return g_win;
+}
+
+EXPORT_API int scl_nui_init(const char *entry_filepath)
+{
+#ifdef USE_ELM_WIN
+    elm_init(0, NULL);
+#endif
+
+    //LOGI("################## Hello ################");
+
+    //sleep(10);
+
+    if (!g_ui) {
+        g_ui = new CSCLUI;
+    }
+
+    if (!g_ui)
+        return 1;
+
+#ifdef USE_ELM_WIN
+    g_win = elm_win_add(NULL, "test", ELM_WIN_UTILITY);
+#endif
+
+    g_ui->init(g_win, SCL_PARSER_TYPE_XML, entry_filepath);
+
+    g_ui->set_graphics_backend_callback(&callback, NULL);
+
+    g_ui->set_window_backend_callback(&window_callback, NULL);
+
+    /* Default ISE callback */
+    g_ui->set_ui_event_callback(&event_callback);
+
+    return 0;
+}
+
+EXPORT_API int scl_nui_fini()
+{
+    int ret = 0;
+
+#ifdef USE_ELM_WIN
+    if (g_win)
+        evas_object_del(g_win);
+
+    g_win = NULL;
+#endif
+
+    if (g_ui)
+        g_ui->fini();
+    else
+        ret = 1;
+
+#ifdef USE_ELM_WIN
+    elm_shutdown();
+#endif
+
+    return ret;
+}
+
+EXPORT_API int scl_nui_set_input_mode(const char *input_mode)
+{
+    if (!g_ui)
+        return 1;
+
+    g_ui->set_input_mode(input_mode);
+
+    return 0;
+}
+
+EXPORT_API int scl_nui_set_update_pending(bool pend)
+{
+    if (!g_ui)
+        return 1;
+
+    g_ui->set_update_pending(pend);
+    return 0;
+}
+
+EXPORT_API int scl_nui_set_draw_text_cb(scl_nui_draw_text_cb callback, void *user_data)
+{
+    g_draw_text_cb = callback;
+    g_draw_text_cb_data = user_data;
+
+    return 0;
+}
+
+EXPORT_API int scl_nui_set_draw_image_cb(scl_nui_draw_image_cb callback, void *user_data)
+{
+    g_draw_image_cb = callback;
+    g_draw_image_cb_data = user_data;
+
+    return 0;
+}
+
+EXPORT_API int scl_nui_set_draw_rectangle_cb(scl_nui_draw_rectangle_cb callback, void *user_data)
+{
+    g_draw_rectangle_cb = callback;
+    g_draw_rectangle_cb_data = user_data;
+
+    return 0;
+}
+
+EXPORT_API int scl_nui_set_cur_sublayout(const char *sub_layout_name)
+{
+    if (!g_ui)
+        return 1;
+
+    LOGD("cur sublayout : %s", sub_layout_name);
+
+    g_ui->set_cur_sublayout(sub_layout_name);
+
+    return 0;
+}
+
+EXPORT_API int scl_nui_set_string_substitution(const char *original, const char *substitute)
+{
+    if (!g_ui)
+        return 1;
+
+    LOGD("original : %s, substitute : %s", original, substitute);
+
+    g_ui->set_string_substitution(original, substitute);
+
+    return 0;
+}
+
+EXPORT_API int scl_nui_set_update_window_cb(scl_nui_update_window_cb callback, void *user_data)
+{
+    g_update_window_cb = callback;
+    g_update_window_cb_data = user_data;
+
+    return 0;
+}
diff --git a/libscl-ui-nui.manifest b/libscl-ui-nui.manifest
new file mode 100644 (file)
index 0000000..017d22d
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+    <domain name="_"/>
+ </request>
+</manifest>
diff --git a/libscl-ui-nui.pc.in b/libscl-ui-nui.pc.in
new file mode 100644 (file)
index 0000000..38a81db
--- /dev/null
@@ -0,0 +1,14 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=@LIBDIR@
+includedir=${prefix}/include
+
+Name: libscl-ui-nui
+Description: SCL UI - A library for developing XML-based software keyboards
+Version: 1.0
+Requires: libscl-common
+Libs: -L${libdir} -lscl-ui-nui
+Cflags: -I${includedir}/libscl-ui-nui
+
diff --git a/packaging/libscl-ui-nui.changes b/packaging/libscl-ui-nui.changes
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packaging/libscl-ui-nui.spec b/packaging/libscl-ui-nui.spec
new file mode 100644 (file)
index 0000000..bcf02f5
--- /dev/null
@@ -0,0 +1,88 @@
+%bcond_with x
+%bcond_with wayland
+
+Name:       libscl-ui-nui
+Summary:    A library for developing XML-based software keyboards
+Version:    0.6.88
+Release:    1
+Group:      Graphics & UI Framework/Input
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+BuildRequires:  cmake
+BuildRequires:  pkgconfig(libtzplatform-config)
+BuildRequires:  pkgconfig(elementary)
+BuildRequires:  pkgconfig(eldbus)
+BuildRequires:  pkgconfig(ecore-wl2)
+BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(feedback)
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(libxml-2.0)
+BuildRequires:  pkgconfig(tts)
+BuildRequires:  pkgconfig(libscl-common)
+
+
+%description
+A library that helps developing S/W Keyboard
+
+%package devel
+Summary:    SCL-UI header file
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+A devel package of libscl-ui library that helps developing S/W Keyboard
+
+%prep
+%setup -q
+
+
+%build
+export CFLAGS+=" -fvisibility=hidden -DTIZEN_DEBUG_ENABLE -Werror"
+export CXXFLAGS+=" -fvisibility=hidden -fvisibility-inlines-hidden -DTIZEN_DEBUG_ENABLE -Werror"
+export FFLAGS+=" -DTIZEN_DEBUG_ENABLE"
+
+# The -fvisibility=hidden option disables a generation of the rtti information for
+# some classes with hidden visibility, this information is critically needed for
+# ubsan VPTR check. Since this library needed to ise-default package, we should
+# just disable visibility option with ubsan to avoid situation with undefined
+# refernce to typeinfo.
+%{?ubsan:
+export CFLAGS=$(echo $CFLAGS | sed -e "s/-fvisibility=hidden//g")
+export CXXFLAGS=$(echo $CXXFLAGS | sed -e "s/-fvisibility=hidden//g" -e "s/-fvisibility-inlines-hidden//g")
+}
+
+rm -rf CMakeFiles
+rm -rf CMakeCache.txt
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+
+%cmake . -Dwith_wayland=TRUE -DMAJORVER=${MAJORVER} -DFULLVER=%{version}
+
+make %{?_smp_mflags}
+
+%install
+rm -rf %{buildroot}
+
+%make_install
+
+
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%{_libdir}/*.so
+%{_libdir}/*.so.*
+#%{_libdir}/%{name}.so.*
+%license LICENSE
+
+%files devel
+%defattr(-,root,root,-)
+#%{_includedir}/cscl-ui-nui.h
+#%{_includedir}/cscl-ui-controller.h
+%{_libdir}/pkgconfig/*.pc
+%{_includedir}/*
+#%{_libdir}/pkgconfig/%{name}.pc
diff --git a/res/put_record.h b/res/put_record.h
new file mode 100644 (file)
index 0000000..9c0deef
--- /dev/null
@@ -0,0 +1,618 @@
+/*
+ * Copyright (c) 2012 - 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 __PUT_RECORD_H__
+#define __PUT_RECORD_H__
+/*This file is just for debug*/
+/*Use this file to output scl resources in txt format*/
+
+// Open this flag to output the scl txt
+// #define __SCL_TXT_DEBUG
+
+/////////////////////////////////////////////////////
+#ifdef __SCL_TXT_DEBUG
+
+#include <stdio.h>
+#include <string>
+#include <unistd.h>
+using namespace std;
+#include "sclresource.h"
+
+#define ENCODE 0
+#define DECODE 1
+#define PARSER 2
+static const string get_folder() {
+    return string(getenv("HOME")) + "/";
+}
+
+static inline void
+put_str(FILE* fp, const char* str) {
+    assert(fp);
+    if (NULL != str) {
+        fprintf(fp, "%s\n", str);
+    } else {
+        fprintf(fp, "String:NULL\n");
+    }
+}
+
+static inline void
+put_int(FILE* fp, int data) {
+    assert(fp);
+    fprintf(fp, "%d\n", data);
+}
+static inline void
+put_flt(FILE* fp, double data) {
+    assert(fp);
+    fprintf(fp, "%lf\n", data);
+}
+static inline void
+put_color(FILE* fp, const SclColor& c) {
+    assert(fp);
+
+    fprintf(fp, "Color:\n");
+    put_int(fp, c.r);
+    put_int(fp, c.g);
+    put_int(fp, c.b);
+    put_int(fp, c.a);
+}
+
+static inline void
+put_point(FILE* fp, const SclPoint& p) {
+    assert(fp);
+
+    fprintf(fp, "Point:\n");
+    put_int(fp, p.x);
+    put_int(fp, p.y);
+}
+static inline void
+put_rect(FILE* fp, const SclRect& r) {
+    assert(fp);
+
+    fprintf(fp, "Rect:\n");
+    put_int(fp, r.left);
+    put_int(fp, r.top);
+    put_int(fp, r.right);
+    put_int(fp, r.bottom);
+}
+
+static inline void
+put_note(FILE*fp, int no) {
+    fprintf(fp, "--------------------------");
+    fprintf(fp, "%d", no);
+    fprintf(fp, "--------------------------\n\n");
+}
+
+static inline void
+put_note(FILE*fp, int i, int j) {
+    fprintf(fp, "--------------------------");
+    fprintf(fp, "i is %d, j is %d", i, j);
+    fprintf(fp, "--------------------------\n\n");
+}
+static inline void
+put_seperator(FILE *fp) {
+    fprintf(fp, "\n##########\n\n");
+}
+
+static void
+put_magnifier_wnd_configure_record(FILE* fp, const SclMagnifierWndConfigure& record) {
+    assert(fp);
+
+    put_int(fp, record.style);
+    put_int(fp, record.width);
+    put_int(fp, record.height);
+    put_rect(fp, record.label_area_rect);
+    put_str(fp, record.bg_image_path);
+    put_seperator(fp);
+
+    put_str(fp, record.bg_shift_image_path);
+    put_str(fp, record.bg_shift_lock_image_path);
+    put_str(fp, record.bg_long_key_image_path);
+    put_int(fp, record.use_actual_window);
+    put_str(fp, record.label_type);
+    put_seperator(fp);
+
+    put_int(fp, record.padding_x);
+    put_int(fp, record.padding_y);
+    put_int(fp, record.show_shift_label);
+}
+
+static void
+put_autopopup_configure_record(FILE*fp, const SclAutoPopupConfigure& record) {
+    assert(fp);
+
+    put_str(fp, record.bg_image_path);
+    put_color(fp, record.bg_color);
+    put_flt(fp, record.bg_line_width);
+    put_color(fp, record.bg_line_color);
+    put_int(fp, record.bg_padding);
+    put_seperator(fp);
+
+    for (int i = 0; i < SCL_BUTTON_STATE_MAX; ++i) {
+        put_str(fp, record.button_image_path[i]);
+    }
+    put_seperator(fp);
+
+    put_int(fp, record.sw_button_style);
+    put_int(fp, record.button_width);
+    put_int(fp, record.button_height);
+    put_int(fp, record.button_spacing);
+
+    put_str(fp, record.label_type);
+    put_seperator(fp);
+    for (int i = 0; i < MAX_WND_DECORATOR; ++i) {
+        put_str(fp, record.decoration_image_path[i]);
+    }
+
+    put_seperator(fp);
+    put_int(fp, record.decoration_size);
+    put_int(fp, record.max_column);
+    put_int(fp, record.add_grab_left);
+    put_int(fp, record.add_grab_right);
+    put_int(fp, record.add_grab_top);
+    put_seperator(fp);
+    put_int(fp, record.add_grab_bottom);
+}
+
+static void
+put_nine_patch_info_record(FILE* fp, const SclNinePatchInfo& record) {
+    assert(fp);
+
+    put_str(fp, record.image_path);
+    put_int(fp, record.left);
+    put_int(fp, record.right);
+    put_int(fp, record.top);
+    put_int(fp, record.bottom);
+}
+
+static void
+put_modifier_decoration_record(FILE* fp, const SclModifierDecoration& record) {
+    assert(fp);
+
+    put_int(fp, record.extract_background);
+    put_str(fp, record.name);
+    put_seperator(fp);
+
+    for (int i = 0; i < DISPLAYMODE_MAX; ++i) {
+        for (int j = 0; j < KEY_MODIFIER_MAX; ++j) {
+            put_str(fp, record.bg_image_path[i][j]);
+        }
+    }
+}
+
+static void
+put_default_configure_record(FILE* fp, const SclDefaultConfigure& record) {
+    put_int(fp, record.display_mode);
+    put_str(fp, record.input_mode);
+    put_str(fp, record.image_file_base_path);
+    put_int(fp, record.target_screen_width);
+    put_int(fp, record.target_screen_height);
+    put_seperator(fp);
+
+    put_int(fp, record.auto_detect_landscape);
+    put_int(fp, record.use_magnifier_window);
+    put_int(fp, record.use_auto_popup);
+    put_int(fp, record.use_zoom_window);
+    put_int(fp, record.on_error_noti_send);
+    put_seperator(fp);
+    put_int(fp, record.use_word_deletion);
+    put_int(fp, record.sw_button_style);
+    put_seperator(fp);
+    for (int i = 0; i < DISPLAYMODE_MAX; ++i) {
+        put_int(fp, record.touch_offset_level[i]);
+    }
+
+    put_seperator(fp);
+    for (int i = 0; i < DISPLAYMODE_MAX; ++i) {
+        put_point(fp, record.touch_offset[i]);
+    }
+
+    put_seperator(fp);
+    put_str(fp, record.default_sub_layout);
+    put_int(fp, record.use_actual_dim_window);
+    put_color(fp, record.dim_color);
+}
+
+static void put_label_properties_record(FILE* fp, const SclLabelProperties& record) {
+    put_str(fp, record.label_type);
+    put_str(fp, record.font_name);
+    put_int(fp, record.font_size);
+    put_seperator(fp);
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            put_color(fp, record.font_color[i][j]);
+        }
+    }
+    put_seperator(fp);
+    put_int(fp, record.alignment);
+    put_int(fp, record.padding_x);
+    put_int(fp, record.padding_y);
+    put_int(fp, record.inner_width);
+    put_int(fp, record.inner_height);
+    put_int(fp, record.shadow_distance);
+    put_int(fp, record.shadow_direction);
+    put_seperator(fp);
+
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            put_color(fp, record.shadow_color[i][j]);
+        }
+    }
+}
+
+static void put_key_coordinate_record(FILE* fp, const SclLayoutKeyCoordinate& record) {
+    put_int(fp, record.x);
+    put_int(fp, record.y);
+    put_int(fp, record.width);
+    put_int(fp, record.height);
+    put_seperator(fp);
+    put_int(fp, record.add_hit_left);
+    put_int(fp, record.add_hit_right);
+    put_int(fp, record.add_hit_top);
+    put_int(fp, record.add_hit_bottom);
+    put_seperator(fp);
+
+    put_int(fp, record.popup_relative_x);
+    put_int(fp, record.popup_relative_y);
+    put_int(fp, record.extract_offset_x);
+    put_int(fp, record.extract_offset_y);
+    put_seperator(fp);
+    put_str(fp, record.sub_layout);
+    put_seperator(fp);
+
+    put_int(fp, record.magnifier_offset_x);
+    put_int(fp, record.magnifier_offset_y);
+    put_seperator(fp);
+    put_str(fp, record.custom_id);
+    put_int(fp, record.button_type);
+    put_int(fp, record.key_type);
+    put_int(fp, record.popup_type);
+    put_seperator(fp);
+
+    put_int(fp, record.use_magnifier);
+    put_int(fp, record.use_long_key_magnifier);
+
+    put_seperator(fp);
+    for (int i = 0; i < SCL_DRAG_STATE_MAX; ++i) {
+        put_str(fp, record.popup_input_mode[i]);
+    }
+    put_seperator(fp);
+    put_str(fp, record.sound_style);
+    put_str(fp, record.vibe_style);
+    put_int(fp, record.is_side_button);
+    put_int(fp, record.label_count);
+    put_seperator(fp);
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_LABEL_FOR_ONE; ++j) {
+            put_str(fp, record.label[i][j]);
+        }
+    }
+    put_seperator(fp);
+    put_str(fp, record.label_type);
+    put_seperator(fp);
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            put_str(fp, record.image_label_path[i][j]);
+        }
+    }
+    put_str(fp, record.image_label_type);
+    put_seperator(fp);
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            put_str(fp, record.bg_image_path[i][j]);
+        }
+    }
+    put_seperator(fp);
+    put_int(fp, record.key_value_count);
+    put_seperator(fp);
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_MULTITAP_CHAR; ++j) {
+            put_str(fp, record.key_value[i][j]);
+        }
+    }
+    put_seperator(fp);
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_LABEL_FOR_ONE; ++j) {
+            put_int(fp, record.key_event[i][j]);
+        }
+    }
+    put_seperator(fp);
+    put_str(fp, record.long_key_value);
+    put_int(fp, record.use_repeat_key);
+    put_seperator(fp);
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_AUTOPOPUP_STRING; ++j) {
+            put_str(fp, record.autopopup_key_labels[i][j]);
+            put_str(fp, record.autopopup_key_values[i][j]);
+            put_int(fp, record.autopopup_key_events[i][j]);
+        }
+    }
+    put_seperator(fp);
+    put_int(fp, record.dont_close_popup);
+    put_int(fp, record.extra_option);
+    put_int(fp, record.multitouch_type);
+    put_seperator(fp);
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_LABEL_FOR_ONE; ++j) {
+            put_str(fp, record.magnifier_label[i][j]);
+        }
+    }
+    put_seperator(fp);
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_MULTITAP_CHAR; ++j) {
+            put_str(fp, record.hint_string[i][j]);
+        }
+    }
+}
+static void put_input_mode_configure_record(FILE* fp, const SclInputModeConfigure& record) {
+    put_str(fp, record.name);
+    put_str(fp, record.layouts[0]);
+    put_str(fp, record.layouts[1]);
+    put_int(fp, record.use_virtual_window);
+    put_int(fp, record.use_dim_window);
+    put_flt(fp, record.timeout);
+}
+static void put_layout_record(FILE* fp, const SclLayout& record ) {
+    put_str(fp, record.name);
+    put_int(fp, record.display_mode);
+    put_int(fp, record.style);
+    put_int(fp, record.width);
+    put_int(fp, record.height);
+    put_seperator(fp);
+    put_int(fp, record.use_sw_button);
+    put_int(fp, record.extract_background);
+    put_int(fp, record.use_magnifier_window);
+    put_int(fp, record.key_width);
+    put_int(fp, record.key_height);
+    put_seperator(fp);
+    put_int(fp, record.use_sw_background);
+    put_flt(fp, record.bg_line_width);
+    put_int(fp, record.add_grab_left);
+    put_int(fp, record.add_grab_right);
+    put_int(fp, record.add_grab_top);
+    put_int(fp, record.add_grab_bottom);
+    put_seperator(fp);
+    for (int i = 0; i < SCL_BUTTON_STATE_MAX; ++i) {
+        put_str(fp, record.image_path[i]);
+    }
+    put_seperator(fp);
+    //key_background_image
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            put_str(fp, record.key_background_image[i][j]);
+        }
+    }
+}
+
+static void put_input_mode_configure_table(int flag, const PSclInputModeConfigure table) {
+    string file_name;
+    if (flag == ENCODE)
+        file_name = "encode_input_mode_configure.txt";
+    else if (flag == DECODE)
+        file_name = "decode_input_mode_configure.txt";
+    else
+        file_name = "sclres_input_mode_configure.txt";
+
+    string path = get_folder() + file_name;
+    FILE *fp = fopen(path.c_str(), "w+");
+    if (!fp) {
+        perror("Warning: path.c_str()");
+        return;
+    }
+    for (int i = 0; i < MAX_SCL_INPUT_MODE; ++i) {
+        put_note(fp, i);
+        put_input_mode_configure_record(fp, table[i]);
+    }
+
+    fclose(fp);
+}
+
+static void put_layout_table(int flag, const PSclLayout table) {
+    string file_name;
+    if (flag == ENCODE)
+        file_name = "encode_layout.txt";
+    else if (flag == DECODE)
+        file_name = "decode_layout.txt";
+    else
+        file_name = "sclres_layout.txt";
+
+    string path = get_folder() + file_name;
+    FILE *fp = fopen(path.c_str(), "w+");
+    if (!fp) {
+        perror("Warning: path.c_str()");
+        return;
+    }
+    for (int i = 0; i < MAX_SCL_LAYOUT; ++i) {
+        put_note(fp, i);
+        put_layout_record(fp, table[i]);
+    }
+    fclose(fp);
+}
+
+static void
+put_key_coordinate_frame(int flag, const PSclLayoutKeyCoordinatePointerTable frame) {
+    string file_name;
+    if (flag == ENCODE) {
+        file_name = "encode_key_coordinate_frame.txt";
+    } else if (flag == DECODE) {
+        file_name = "decode_key_coordinate_frame.txt";
+    } else {
+        file_name = "sclres_key_coordinate_frame.txt";
+    }
+
+    string path = get_folder() + file_name;
+    FILE *fp = fopen(path.c_str(), "w+");
+    if (!fp) {
+        perror("Warning: path.c_str()");
+        return;
+    }
+    for (int i = 0; i < MAX_SCL_LAYOUT; ++i) {
+        if (frame[i][0] == NULL) break;
+
+        for (int j = 0; j < MAX_KEY; ++j) {
+            put_note(fp, i, j);
+            const SclLayoutKeyCoordinatePointer p = frame[i][j];
+            if (!p) break;
+            const SclLayoutKeyCoordinate& cur = *p;
+            put_key_coordinate_record(fp, cur);
+        }
+    }
+    fclose(fp);
+}
+
+static void
+put_label_properties_frame(int flag, const PSclLabelPropertiesTable frame) {
+    string file_name;
+    if (flag == ENCODE) {
+        file_name = "encode_label_properties_frame.txt";
+    } else if (flag == DECODE) {
+        file_name = "decode_label_properties_frame.txt";
+    } else {
+        file_name = "sclres_label_properties_frame.txt";
+    }
+
+    string path = get_folder() + file_name;
+    FILE *fp = fopen(path.c_str(), "w+");
+    if (!fp) {
+        perror("Warning: path.c_str()");
+        return;
+    }
+    for (int i = 0; i < MAX_SCL_LABEL_PROPERTIES; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_LABEL_FOR_ONE; ++j) {
+            put_note(fp, i, j);
+            put_label_properties_record(fp, frame[i][j]);
+        }
+    }
+    fclose(fp);
+}
+
+static void
+put_default_configure(int flag, const SclDefaultConfigure& record) {
+    string file_name;
+    if (flag == ENCODE) {
+        file_name = "encode_default_configure.txt";
+    } else if (flag == DECODE) {
+        file_name = "decode_default_configure.txt";
+    } else {
+        file_name = "sclres_default_configure.txt";
+    }
+
+    string path = get_folder() + file_name;
+    FILE *fp = fopen(path.c_str(), "w+");
+    if (!fp) {
+        perror("Warning: path.c_str()");
+        return;
+    }
+    put_default_configure_record(fp, record);
+    fclose(fp);
+}
+
+static void
+put_autopopup_configure(int flag, const SclAutoPopupConfigure& record) {
+    string file_name;
+    if (flag == ENCODE) {
+        file_name = "encode_autopopup_configure.txt";
+    } else if (flag == DECODE) {
+        file_name = "decode_autopopup_configure.txt";
+    } else {
+        file_name = "sclres_autopopup_configure.txt";
+    }
+
+    string path = get_folder() + file_name;
+    FILE *fp = fopen(path.c_str(), "w+");
+    if (!fp) {
+        perror("Warning: path.c_str()");
+        return;
+    }
+    put_autopopup_configure_record(fp, record);
+    fclose(fp);
+}
+
+static void
+put_nine_patch_info(int flag, const SclNinePatchInfo* table) {
+    static const int MAX_NINE_PATCH_FILE_LIST = 128;
+
+    string file_name;
+    if (flag == ENCODE) {
+        file_name = "encode_nine_patch_info.txt";
+    } else if (flag == DECODE) {
+        file_name = "decode_nine_patch_info.txt";
+    } else {
+        file_name = "sclres_nine_patch_info.txt";
+    }
+
+    string path = get_folder() + file_name;
+    FILE *fp = fopen(path.c_str(), "w+");
+    if (!fp) {
+        perror("Warning: path.c_str()");
+        return;
+    }
+
+    for (int i = 0; i < MAX_NINE_PATCH_FILE_LIST; ++i) {
+        put_note(fp, i);
+        put_nine_patch_info_record(fp, table[i]);
+    }
+    fclose(fp);
+}
+
+
+static void
+put_magnifier_wnd_configure(int flag, const SclMagnifierWndConfigure& record) {
+    string file_name;
+    if (flag == ENCODE) {
+        file_name = "encode_magnifier_wnd_configure.txt";
+    } else if (flag == DECODE) {
+        file_name = "decode_magnifier_wnd_configure.txt";
+    } else {
+        file_name = "sclres_magnifier_wnd_configure.txt";
+    }
+
+    string path = get_folder() + file_name;
+    FILE *fp = fopen(path.c_str(), "w+");
+    if (!fp) {
+        perror("Warning: path.c_str()");
+        return;
+    }
+    put_magnifier_wnd_configure_record(fp, record);
+    fclose(fp);
+}
+
+static void
+put_modifier_decoration(int flag, const PSclModifierDecoration table) {
+    string file_name;
+    if (flag == ENCODE) {
+        file_name = "encode_modifier_decoration.txt";
+    } else if (flag == DECODE) {
+        file_name = "decode_modifier_decoration.txt";
+    } else {
+        file_name = "sclres_modifier_decoration.txt";
+    }
+
+    string path = get_folder() + file_name;
+    FILE *fp = fopen(path.c_str(), "w+");
+    if (!fp) {
+        perror("Warning: path.c_str()");
+        return;
+    }
+
+    for (int i = 0; i < MAX_SCL_MODIFIER_DECORATION_NUM; ++i) {
+        put_note(fp, i);
+        put_modifier_decoration_record(fp, table[i]);
+    }
+    fclose(fp);
+}
+#endif
+#endif
diff --git a/res/sclresource.cpp b/res/sclresource.cpp
new file mode 100644 (file)
index 0000000..06c2b25
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include "scltypes.h"
+#include "sclconfig.h"
+#include "sclstructs.h"
+#include "sclresource.h"
+
diff --git a/res/sclresource.h b/res/sclresource.h
new file mode 100644 (file)
index 0000000..6dd8341
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012 - 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 "scltypes.h"
+#include "sclconfig.h"
+#include "sclstructs.h"
+#include "sclkeydefines.h"
+
+/* This prevents "deprecated conversion" warnings.. */
+#pragma GCC diagnostic ignored "-Wwrite-strings"
+
+#ifndef __SCL_RESOURCE_H__
+#define __SCL_RESOURCE_H__
+
+#define RESOURCE_DATA_LABEL_LEN 10
+#define RESOURCE_DATA_IMG_PATH_LEN 50
+#define RESOURCE_DATA_KEY_VALUE_LEN 8
+#define RESOURCE_DATA_AUTOPOPUP_KEY_LEN 4
+
+#define DEFAULT_FONT_NAME "SLP:style=medium"
+
+#define MAX_KEY 127
+
+#endif
diff --git a/res/sclresourcekeys.h b/res/sclresourcekeys.h
new file mode 100644 (file)
index 0000000..064cfd5
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_RESOURCEKEYS_H__
+#define __SCL_RESOURCEKEYS_H__
+
+#endif
diff --git a/res/simple_debug.cpp b/res/simple_debug.cpp
new file mode 100644 (file)
index 0000000..e1dbedb
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2012 - 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 "simple_debug.h"
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <dlog.h>
+
+SclLog::SclLog() : m_flog(NULL) {
+    char *env = NULL;
+    char *scllog = NULL;
+    char log_path[128];
+
+    /*
+     * Use export scllog="true" to enable scllog
+     */
+    scllog = getenv("scllog");
+    if (scllog == NULL || 0 != strcmp(scllog, "true")) {
+        return;
+    }
+
+    env = getenv("HOME");
+    if (env == NULL) {
+        return;
+    }
+
+    snprintf(log_path, 128, "%s/scl.log", env);
+}
+
+SclLog::~SclLog() {
+    if (m_flog != NULL) {
+        fclose(m_flog);
+    }
+}
+
+SclLog*
+SclLog::get_instance() {
+    static SclLog instance;
+    return &instance;
+}
+
+void
+SclLog::log(enum LOG_LEVEL level, const char* fmt, ...) {
+    static const char *log_message[MAX_LOG_LEVEL] = {
+        "message", "warning", "debug", "error"
+    };
+
+    if (level >= MAX_LOG_LEVEL)
+        return;
+
+    char str_log[128];
+    va_list ap;
+    va_start(ap, fmt);
+    vsnprintf(str_log, sizeof(str_log), fmt, ap);
+    va_end(ap);
+
+    if (m_flog == NULL) {
+        switch (level) {
+            case WARNING:
+            {
+                LOGW("%s", str_log);
+                break;
+            }
+            case ERROR:
+            {
+                LOGE("%s", str_log);
+                break;
+            }
+            case DEBUG:
+            {
+                LOGD("%s", str_log);
+                break;
+            }
+            default:
+            {
+                LOGI("%s", str_log);
+            }
+        }
+    } else {
+        /*
+         * log current time
+         */
+        time_t now;
+        struct tm timenow;
+
+        time(&now);
+        localtime_r(&now, &timenow);
+
+        char buf[64] = { 0 };
+        asctime_r(&timenow, buf);
+
+        fprintf(m_flog, "[ %s ] %s\n", log_message[level], buf);
+        fprintf(m_flog, "\t%s\n", str_log);
+
+        fflush(m_flog);
+    }
+}
+
+void
+SCLLOG(enum SclLog::LOG_LEVEL level, const char* fmt, ...) {
+    SclLog *log = SclLog::get_instance();
+    if (log) {
+        char str_log[128];
+        va_list ap;
+        va_start(ap, fmt);
+        vsnprintf(str_log, sizeof(str_log), fmt, ap);
+        va_end(ap);
+        log->log(level, str_log);
+    }
+}
+
+static struct timeval g_time_begin;
+static struct timeval g_time_end;
+void
+SCLLOG_TIME_BEGIN() {
+    gettimeofday(&g_time_begin, NULL);
+}
+
+void
+SCLLOG_TIME_END(const char *msg) {
+    gettimeofday(&g_time_end, NULL);
+
+    long diff = (g_time_end.tv_sec - g_time_begin.tv_sec) * 1000000 + g_time_end.tv_usec - g_time_begin.tv_usec;
+    fprintf(stdout, "%s use %ld usec\n", msg, diff);
+}
diff --git a/res/simple_debug.h b/res/simple_debug.h
new file mode 100644 (file)
index 0000000..4f9a9cc
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 - 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 __SIMPLE_DEBUG_H__
+#define __SIMPLE_DEBUG_H__
+#include <stdio.h>
+
+class SclLog {
+    public:
+        enum LOG_LEVEL {
+            MESSAGE = 0,
+            WARNING,
+            DEBUG,
+            ERROR,
+            MAX_LOG_LEVEL
+        };
+
+        static SclLog* get_instance();
+        void log(enum LOG_LEVEL, const char* fmt, ...);
+        ~SclLog();
+    private:
+        SclLog();
+
+        FILE *m_flog;
+};
+
+
+void SCLLOG(enum SclLog::LOG_LEVEL level, const char* fmt, ...);
+
+void SCLLOG_TIME_BEGIN();
+void SCLLOG_TIME_END(const char *msg);
+#endif
diff --git a/res/simple_debug_test.cpp b/res/simple_debug_test.cpp
new file mode 100644 (file)
index 0000000..9c662c9
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 - 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.
+ *
+ */
+
+/*
+ * Use `g++ -I. simple_debug.cpp simple_debug_test.cpp` to compiler it
+ */
+#include <simple_debug.h>
+#include <stdio.h>
+
+int main() {
+    /* Test SclLog */
+    SclLog *log = SclLog::get_instance();
+    if (log) {
+        log->log(SclLog::WARNING, "Test %d\n", 100);
+    }
+
+    /* Test SCLLOG */
+    SCLLOG(SclLog::ERROR, "%s/%d", "SCLLOG", 100);
+    return 0;
+}
diff --git a/scl/_auto_metadata.h b/scl/_auto_metadata.h
new file mode 100644 (file)
index 0000000..0441ba5
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ * Copyright (c) 2012 - 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.
+ *
+ */
+
+/*This file is generated by auto_codes.py.*/
+
+#ifndef __AUTO_METADATA_H__
+#define __AUTO_METADATA_H__
+
+#include <memory.h>
+typedef struct _Input_mode_configure_width {
+       int name;
+       int layout_portrait;
+       int layout_landscape;
+       int use_virtual_window;
+       int use_dim_window;
+       int timeout;
+}Input_mode_configure_width;
+
+typedef struct _Layout_width {
+       int name;
+       int display_mode;
+       int style;
+       int width;
+       int height;
+       int use_sw_button;
+       int use_magnifier_window;
+       int extract_background;
+       int key_width;
+       int key_height;
+       int key_spacing;
+       int row_spacing;
+       int use_sw_background;
+       int bg_color;
+       int bg_line_width;
+       int bg_line_color;
+       int add_grab_left;
+       int add_grab_right;
+       int add_grab_top;
+       int add_grab_bottom;
+       int image_path;
+       int key_background_image;
+       int sound_style;
+       int vibe_style;
+       int label_type;
+       int modifier_decorator;
+}Layout_width;
+
+typedef struct _Key_coordinate_record_width {
+       int x;
+       int y;
+       int width;
+       int height;
+       int add_hit_left;
+       int add_hit_right;
+       int add_hit_top;
+       int add_hit_bottom;
+       int popup_relative_x;
+       int popup_relative_y;
+       int extract_offset_x;
+       int extract_offset_y;
+       int sub_layout;
+       int magnifier_offset_x;
+       int magnifier_offset_y;
+       int custom_id;
+       int button_type;
+       int key_type;
+       int popup_type;
+       int use_magnifier;
+       int use_long_key_magnifier;
+       int popup_input_mode;
+       int sound_style;
+       int vibe_style;
+       int is_side_button;
+       int label_count;
+       int label;
+       int label_type;
+       int image_label_path;
+       int image_label_type;
+       int bg_image_path;
+       int key_value_count;
+       int key_value;
+       int key_event;
+       int long_key_type;
+       int long_key_value;
+       int long_key_event;
+       int use_repeat_key;
+       int autopopup_key_labels;
+       int autopopup_key_values;
+       int autopopup_key_events;
+       int dont_close_popup;
+       int extra_option;
+       int multitouch_type;
+       int modifier_decorator;
+       int magnifier_label;
+       int hint_string;
+}Key_coordinate_record_width;
+
+typedef struct _Label_properties_record_width {
+       int label_type;
+       int font_name;
+       int font_size;
+       int font_color;
+       int alignment;
+       int padding_x;
+       int padding_y;
+       int inner_width;
+       int inner_height;
+       int shadow_distance;
+       int shadow_direction;
+       int shadow_color;
+}Label_properties_record_width;
+
+typedef struct _Default_configure_width {
+       int display_mode;
+       int input_mode;
+       int image_file_base_path;
+       int target_screen_width;
+       int target_screen_height;
+       int auto_detect_landscape;
+       int use_magnifier_window;
+       int use_auto_popup;
+       int use_zoom_window;
+       int on_error_noti_send;
+       int use_word_deletion;
+       int sw_button_style;
+       int touch_offset_level;
+       int touch_offset;
+       int default_sub_layout;
+       int use_actual_dim_window;
+       int dim_color;
+}Default_configure_width;
+
+typedef struct _Magnifier_configure_width {
+       int style;
+       int width;
+       int height;
+       int label_area_rect;
+       int bg_image_path;
+       int bg_shift_image_path;
+       int bg_shift_lock_image_path;
+       int bg_long_key_image_path;
+       int use_actual_window;
+       int label_type;
+       int padding_x;
+       int padding_y;
+       int show_shift_label;
+}Magnifier_configure_width;
+
+typedef struct _Autopopup_configure_width {
+       int bg_image_path;
+       int bg_color;
+       int bg_line_width;
+       int bg_line_color;
+       int bg_padding;
+       int button_image_path;
+       int sw_button_style;
+       int button_width;
+       int button_height;
+       int button_spacing;
+       int label_type;
+       int decoration_image_path;
+       int decoration_size;
+       int max_column;
+       int add_grab_left;
+       int add_grab_right;
+       int add_grab_top;
+       int add_grab_bottom;
+}Autopopup_configure_width;
+
+typedef struct _Modifier_decoration_width {
+       int extract_background;
+       int name;
+       int bg_image_path;
+}Modifier_decoration_width;
+
+typedef struct _Nine_patch_width {
+       int image_path;
+       int left;
+       int right;
+       int top;
+       int bottom;
+}Nine_patch_width;
+
+template <class T>
+void set_input_mode_configure_width(T& md_helper,
+       Input_mode_configure_width & record_width) {
+       md_helper.set_current_metadata_record("input_mode_configure");
+       memset(&record_width, 0x00, sizeof(Input_mode_configure_width));
+
+       record_width.name = md_helper.get_width("name");
+       record_width.layout_portrait = md_helper.get_width("layout_portrait");
+       record_width.layout_landscape = md_helper.get_width("layout_landscape");
+       record_width.use_virtual_window = md_helper.get_width("use_virtual_window");
+       record_width.use_dim_window = md_helper.get_width("use_dim_window");
+       record_width.timeout = md_helper.get_width("timeout");
+}
+
+template <class T>
+void set_layout_width(T& md_helper,
+       Layout_width & record_width) {
+       md_helper.set_current_metadata_record("layout");
+       memset(&record_width, 0x00, sizeof(Layout_width));
+
+       record_width.name = md_helper.get_width("name");
+       record_width.display_mode = md_helper.get_width("display_mode");
+       record_width.style = md_helper.get_width("style");
+       record_width.width = md_helper.get_width("width");
+       record_width.height = md_helper.get_width("height");
+       record_width.use_sw_button = md_helper.get_width("use_sw_button");
+       record_width.use_magnifier_window = md_helper.get_width("use_magnifier_window");
+       record_width.extract_background = md_helper.get_width("extract_background");
+       record_width.key_width = md_helper.get_width("key_width");
+       record_width.key_height = md_helper.get_width("key_height");
+       record_width.key_spacing = md_helper.get_width("key_spacing");
+       record_width.row_spacing = md_helper.get_width("row_spacing");
+       record_width.use_sw_background = md_helper.get_width("use_sw_background");
+       record_width.bg_color = md_helper.get_width("bg_color");
+       record_width.bg_line_width = md_helper.get_width("bg_line_width");
+       record_width.bg_line_color = md_helper.get_width("bg_line_color");
+       record_width.add_grab_left = md_helper.get_width("add_grab_left");
+       record_width.add_grab_right = md_helper.get_width("add_grab_right");
+       record_width.add_grab_top = md_helper.get_width("add_grab_top");
+       record_width.add_grab_bottom = md_helper.get_width("add_grab_bottom");
+       record_width.image_path = md_helper.get_width("image_path");
+       record_width.key_background_image = md_helper.get_width("key_background_image");
+       record_width.sound_style = md_helper.get_width("sound_style");
+       record_width.vibe_style = md_helper.get_width("vibe_style");
+       record_width.label_type = md_helper.get_width("label_type");
+       record_width.modifier_decorator = md_helper.get_width("modifier_decorator");
+}
+
+template <class T>
+void set_key_coordinate_record_width(T *md_helper,
+       Key_coordinate_record_width & record_width) {
+       if (md_helper) {
+               md_helper->set_current_metadata_record("key_coordinate_record");
+               memset(&record_width, 0x00, sizeof(Key_coordinate_record_width));
+
+               record_width.x = md_helper->get_width("x");
+               record_width.y = md_helper->get_width("y");
+               record_width.width = md_helper->get_width("width");
+               record_width.height = md_helper->get_width("height");
+               record_width.add_hit_left = md_helper->get_width("add_hit_left");
+               record_width.add_hit_right = md_helper->get_width("add_hit_right");
+               record_width.add_hit_top = md_helper->get_width("add_hit_top");
+               record_width.add_hit_bottom = md_helper->get_width("add_hit_bottom");
+               record_width.popup_relative_x = md_helper->get_width("popup_relative_x");
+               record_width.popup_relative_y = md_helper->get_width("popup_relative_y");
+               record_width.extract_offset_x = md_helper->get_width("extract_offset_x");
+               record_width.extract_offset_y = md_helper->get_width("extract_offset_y");
+               record_width.sub_layout = md_helper->get_width("sub_layout");
+               record_width.magnifier_offset_x = md_helper->get_width("magnifier_offset_x");
+               record_width.magnifier_offset_y = md_helper->get_width("magnifier_offset_y");
+               record_width.custom_id = md_helper->get_width("custom_id");
+               record_width.button_type = md_helper->get_width("button_type");
+               record_width.key_type = md_helper->get_width("key_type");
+               record_width.popup_type = md_helper->get_width("popup_type");
+               record_width.use_magnifier = md_helper->get_width("use_magnifier");
+               record_width.use_long_key_magnifier = md_helper->get_width("use_long_key_magnifier");
+               record_width.popup_input_mode = md_helper->get_width("popup_input_mode");
+               record_width.sound_style = md_helper->get_width("sound_style");
+               record_width.vibe_style = md_helper->get_width("vibe_style");
+               record_width.is_side_button = md_helper->get_width("is_side_button");
+               record_width.label_count = md_helper->get_width("label_count");
+               record_width.label = md_helper->get_width("label");
+               record_width.label_type = md_helper->get_width("label_type");
+               record_width.image_label_path = md_helper->get_width("image_label_path");
+               record_width.image_label_type = md_helper->get_width("image_label_type");
+               record_width.bg_image_path = md_helper->get_width("bg_image_path");
+               record_width.key_value_count = md_helper->get_width("key_value_count");
+               record_width.key_value = md_helper->get_width("key_value");
+               record_width.key_event = md_helper->get_width("key_event");
+               record_width.long_key_type = md_helper->get_width("long_key_type");
+               record_width.long_key_value = md_helper->get_width("long_key_value");
+               record_width.long_key_event = md_helper->get_width("long_key_event");
+               record_width.use_repeat_key = md_helper->get_width("use_repeat_key");
+               record_width.autopopup_key_labels = md_helper->get_width("autopopup_key_labels");
+               record_width.autopopup_key_values = md_helper->get_width("autopopup_key_values");
+               record_width.autopopup_key_events = md_helper->get_width("autopopup_key_events");
+               record_width.dont_close_popup = md_helper->get_width("dont_close_popup");
+               record_width.extra_option = md_helper->get_width("extra_option");
+               record_width.multitouch_type = md_helper->get_width("multitouch_type");
+               record_width.modifier_decorator = md_helper->get_width("modifier_decorator");
+               record_width.magnifier_label = md_helper->get_width("magnifier_label");
+               record_width.hint_string = md_helper->get_width("hint_string");
+       }
+}
+
+template <class T>
+void set_label_properties_record_width(T& md_helper,
+       Label_properties_record_width & record_width) {
+       md_helper.set_current_metadata_record("label_properties_record");
+       memset(&record_width, 0x00, sizeof(Label_properties_record_width));
+
+       record_width.label_type = md_helper.get_width("label_type");
+       record_width.font_name = md_helper.get_width("font_name");
+       record_width.font_size = md_helper.get_width("font_size");
+       record_width.font_color = md_helper.get_width("font_color");
+       record_width.alignment = md_helper.get_width("alignment");
+       record_width.padding_x = md_helper.get_width("padding_x");
+       record_width.padding_y = md_helper.get_width("padding_y");
+       record_width.inner_width = md_helper.get_width("inner_width");
+       record_width.inner_height = md_helper.get_width("inner_height");
+       record_width.shadow_distance = md_helper.get_width("shadow_distance");
+       record_width.shadow_direction = md_helper.get_width("shadow_direction");
+       record_width.shadow_color = md_helper.get_width("shadow_color");
+}
+
+template <class T>
+void set_default_configure_width(T& md_helper,
+       Default_configure_width & record_width) {
+       md_helper.set_current_metadata_record("default_configure");
+       memset(&record_width, 0x00, sizeof(Default_configure_width));
+
+       record_width.display_mode = md_helper.get_width("display_mode");
+       record_width.input_mode = md_helper.get_width("input_mode");
+       record_width.image_file_base_path = md_helper.get_width("image_file_base_path");
+       record_width.target_screen_width = md_helper.get_width("target_screen_width");
+       record_width.target_screen_height = md_helper.get_width("target_screen_height");
+       record_width.auto_detect_landscape = md_helper.get_width("auto_detect_landscape");
+       record_width.use_magnifier_window = md_helper.get_width("use_magnifier_window");
+       record_width.use_auto_popup = md_helper.get_width("use_auto_popup");
+       record_width.use_zoom_window = md_helper.get_width("use_zoom_window");
+       record_width.on_error_noti_send = md_helper.get_width("on_error_noti_send");
+       record_width.use_word_deletion = md_helper.get_width("use_word_deletion");
+       record_width.sw_button_style = md_helper.get_width("sw_button_style");
+       record_width.touch_offset_level = md_helper.get_width("touch_offset_level");
+       record_width.touch_offset = md_helper.get_width("touch_offset");
+       record_width.default_sub_layout = md_helper.get_width("default_sub_layout");
+       record_width.use_actual_dim_window = md_helper.get_width("use_actual_dim_window");
+       record_width.dim_color = md_helper.get_width("dim_color");
+}
+
+template <class T>
+void set_magnifier_configure_width(T& md_helper,
+       Magnifier_configure_width & record_width) {
+       md_helper.set_current_metadata_record("magnifier_configure");
+       memset(&record_width, 0x00, sizeof(Magnifier_configure_width));
+
+       record_width.style = md_helper.get_width("style");
+       record_width.width = md_helper.get_width("width");
+       record_width.height = md_helper.get_width("height");
+       record_width.label_area_rect = md_helper.get_width("label_area_rect");
+       record_width.bg_image_path = md_helper.get_width("bg_image_path");
+       record_width.bg_shift_image_path = md_helper.get_width("bg_shift_image_path");
+       record_width.bg_shift_lock_image_path = md_helper.get_width("bg_shift_lock_image_path");
+       record_width.bg_long_key_image_path = md_helper.get_width("bg_long_key_image_path");
+       record_width.use_actual_window = md_helper.get_width("use_actual_window");
+       record_width.label_type = md_helper.get_width("label_type");
+       record_width.padding_x = md_helper.get_width("padding_x");
+       record_width.padding_y = md_helper.get_width("padding_y");
+       record_width.show_shift_label = md_helper.get_width("show_shift_label");
+}
+
+template <class T>
+void set_autopopup_configure_width(T& md_helper,
+       Autopopup_configure_width & record_width) {
+       md_helper.set_current_metadata_record("autopopup_configure");
+       memset(&record_width, 0x00, sizeof(Autopopup_configure_width));
+
+       record_width.bg_image_path = md_helper.get_width("bg_image_path");
+       record_width.bg_color = md_helper.get_width("bg_color");
+       record_width.bg_line_width = md_helper.get_width("bg_line_width");
+       record_width.bg_line_color = md_helper.get_width("bg_line_color");
+       record_width.bg_padding = md_helper.get_width("bg_padding");
+       record_width.button_image_path = md_helper.get_width("button_image_path");
+       record_width.sw_button_style = md_helper.get_width("sw_button_style");
+       record_width.button_width = md_helper.get_width("button_width");
+       record_width.button_height = md_helper.get_width("button_height");
+       record_width.button_spacing = md_helper.get_width("button_spacing");
+       record_width.label_type = md_helper.get_width("label_type");
+       record_width.decoration_image_path = md_helper.get_width("decoration_image_path");
+       record_width.decoration_size = md_helper.get_width("decoration_size");
+       record_width.max_column = md_helper.get_width("max_column");
+       record_width.add_grab_left = md_helper.get_width("add_grab_left");
+       record_width.add_grab_right = md_helper.get_width("add_grab_right");
+       record_width.add_grab_top = md_helper.get_width("add_grab_top");
+       record_width.add_grab_bottom = md_helper.get_width("add_grab_bottom");
+}
+
+template <class T>
+void set_modifier_decoration_width(T& md_helper,
+       Modifier_decoration_width & record_width) {
+       md_helper.set_current_metadata_record("modifier_decoration");
+       memset(&record_width, 0x00, sizeof(Modifier_decoration_width));
+
+       record_width.extract_background = md_helper.get_width("extract_background");
+       record_width.name = md_helper.get_width("name");
+       record_width.bg_image_path = md_helper.get_width("bg_image_path");
+}
+
+template <class T>
+void set_nine_patch_width(T& md_helper,
+       Nine_patch_width & record_width) {
+       md_helper.set_current_metadata_record("nine_patch");
+       memset(&record_width, 0x00, sizeof(Nine_patch_width));
+
+       record_width.image_path = md_helper.get_width("image_path");
+       record_width.left = md_helper.get_width("left");
+       record_width.right = md_helper.get_width("right");
+       record_width.top = md_helper.get_width("top");
+       record_width.bottom = md_helper.get_width("bottom");
+}
+
+
+#endif //End __AUTO_METADATA_H__
diff --git a/scl/autopopup_configure_bin_parser.cpp b/scl/autopopup_configure_bin_parser.cpp
new file mode 100644 (file)
index 0000000..2584604
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2012 - 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 "autopopup_configure_bin_parser.h"
+#include <assert.h>
+using namespace std;
+#include "put_record.h"
+
+BinAutoPopupConfigParser::BinAutoPopupConfigParser() {
+    memset((void*)&m_autopopup_configure, 0x00, sizeof(SclAutoPopupConfigure));
+    parser_info_provider = NULL;
+}
+
+BinAutoPopupConfigParser::~BinAutoPopupConfigParser() {
+}
+
+BinAutoPopupConfigParser* BinAutoPopupConfigParser::get_instance() {
+    static BinAutoPopupConfigParser instance;
+
+    return &instance;
+}
+
+void
+BinAutoPopupConfigParser::decode_color(SclColor& color, int width) {
+    if (width <= 0) return;
+
+    color.r = m_storage.get<sint_t>(width);
+    color.g = m_storage.get<sint_t>(width);
+    color.b = m_storage.get<sint_t>(width);
+    color.a = m_storage.get<sint_t>(width);
+}
+
+void BinAutoPopupConfigParser::init(const FileStorage& storage, int offset, int size, IParserInfo_Provider* provider) {
+    m_storage.set_str_provider(provider);
+    m_storage.get_storage(storage, offset, size);
+    this->parser_info_provider = provider;
+
+    parsing_autopopup_configure();
+}
+
+void BinAutoPopupConfigParser::parsing_autopopup_configure() {
+    Autopopup_configure_width record_width;
+    set_autopopup_configure_width(*parser_info_provider, record_width);
+
+    PSclAutoPopupConfigure cur = &m_autopopup_configure;
+
+    // skip data_size
+    m_storage.advance(8);
+
+    //bg_image_path
+    m_storage.get_str(&(cur->bg_image_path), record_width.bg_image_path, m_string_collector);
+
+    //bg_color
+    decode_color(cur->bg_color, record_width.bg_color);
+    //double value
+        cur->bg_line_width = m_storage.get<float_t>(record_width.bg_line_width);
+
+    //bg_line_color
+        decode_color(cur->bg_line_color, record_width.bg_line_color);
+
+    //bg_padding
+    cur->bg_padding = m_storage.get<sint_t>(record_width.bg_padding);
+
+    //button_image_path
+    for (int i = 0; i < SCL_BUTTON_STATE_MAX; ++i) {
+        m_storage.get_str(&(cur->button_image_path[i]), record_width.button_image_path, m_string_collector);
+    }
+
+    //sw_button_style
+    cur->sw_button_style = m_storage.get<sint_t>(record_width.sw_button_style);
+
+    //button_width
+    cur->button_width = m_storage.get<sint_t>(record_width.button_width);
+
+    //button_height
+    cur->button_height = m_storage.get<sint_t>(record_width.button_height);
+
+    //button_spacing
+    cur->button_spacing = m_storage.get<sint_t>(record_width.button_spacing);
+
+    m_storage.get_str(&(cur->label_type), record_width.label_type, m_string_collector);
+
+    for (int i = 0; i < MAX_WND_DECORATOR; ++i) {
+        m_storage.get_str(&(cur->decoration_image_path[i]), record_width.decoration_image_path, m_string_collector);
+    }
+
+    //decoration_size
+    cur->decoration_size = m_storage.get<sint_t>(record_width.decoration_size);
+
+    //max_column
+    cur->max_column = m_storage.get<sint_t>(record_width.max_column);
+
+    //add_grab_left
+    cur->add_grab_left = m_storage.get<sint_t>(record_width.add_grab_left);
+
+    //add_grab_right
+    cur->add_grab_right = m_storage.get<sint_t>(record_width.add_grab_right);
+
+    //add_grab_top
+    cur->add_grab_top = m_storage.get<sint_t>(record_width.add_grab_top);
+
+    //add_grab_bottom
+    cur->add_grab_bottom = m_storage.get<sint_t>(record_width.add_grab_bottom);
+#ifdef __SCL_TXT_DEBUG
+    put_autopopup_configure(DECODE, m_autopopup_configure);
+#endif
+}
+
+PSclAutoPopupConfigure BinAutoPopupConfigParser::get_autopopup_configure() {
+    return &m_autopopup_configure;
+}
diff --git a/scl/autopopup_configure_bin_parser.h b/scl/autopopup_configure_bin_parser.h
new file mode 100644 (file)
index 0000000..a904708
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 - 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 __BinAutoPopupConfigParser__H__
+#define __BinAutoPopupConfigParser__H__
+#include "sclres_type.h"
+#include "string_collector.h"
+#include "iparserinfo_provider.h"
+#include "file_storage_impl.h"
+#include "_auto_metadata.h"
+
+class BinAutoPopupConfigParser {
+public:
+    ~BinAutoPopupConfigParser();
+    static BinAutoPopupConfigParser *get_instance();
+    void init(const FileStorage& storage, int, int, IParserInfo_Provider*);
+
+    PSclAutoPopupConfigure get_autopopup_configure();
+
+private:
+    BinAutoPopupConfigParser();
+    void parsing_autopopup_configure();
+    void decode_color(SclColor&, int width);
+private:
+    SclAutoPopupConfigure m_autopopup_configure;
+    StringCollector m_string_collector;
+    FileStorage m_storage;
+    IParserInfo_Provider* parser_info_provider;
+};
+
+
+#endif
diff --git a/scl/autopopup_configure_parser.cpp b/scl/autopopup_configure_parser.cpp
new file mode 100644 (file)
index 0000000..2a0ee32
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2012 - 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 <assert.h>
+#include <string.h>
+#include <libxml/parser.h>
+
+#include "autopopup_configure_parser.h"
+#include "xml_parser_utils.h"
+#include "simple_debug.h"
+using namespace std;
+
+class AutoPopupConfigureParserImpl {
+    public:
+        AutoPopupConfigureParserImpl() {
+            memset((void*)&m_autopopup_configure, 0x00, sizeof(SclAutoPopupConfigure));
+
+            m_autopopup_configure.add_grab_left = NOT_USED;
+            m_autopopup_configure.add_grab_right = NOT_USED;
+            m_autopopup_configure.add_grab_top = NOT_USED;
+            m_autopopup_configure.add_grab_bottom = NOT_USED;
+        }
+
+        ~AutoPopupConfigureParserImpl() {
+            reset();
+        }
+
+        void reset() {
+            sclint loop;
+            for (loop = 0; loop < SCL_BUTTON_STATE_MAX; loop++) {
+                if (m_autopopup_configure.button_image_path[loop]) {
+                    xmlFree(m_autopopup_configure.button_image_path[loop]);
+                    m_autopopup_configure.button_image_path[loop] = NULL;
+                }
+            }
+            for (loop = 0; loop < MAX_WND_DECORATOR; loop++) {
+                if (m_autopopup_configure.decoration_image_path[loop]) {
+                    xmlFree(m_autopopup_configure.decoration_image_path[loop]);
+                    m_autopopup_configure.decoration_image_path[loop] = NULL;
+                }
+            }
+
+            if (m_autopopup_configure.label_type) {
+                xmlFree(m_autopopup_configure.label_type);
+                m_autopopup_configure.label_type = NULL;
+            }
+
+            if (m_autopopup_configure.bg_image_path) {
+                xmlFree(m_autopopup_configure.bg_image_path);
+                m_autopopup_configure.bg_image_path = NULL;
+            }
+
+            if (m_autopopup_configure.line_image_path) {
+                xmlFree(m_autopopup_configure.line_image_path);
+                m_autopopup_configure.line_image_path = NULL;
+            }
+
+            memset((void*)&m_autopopup_configure, 0x00, sizeof(SclAutoPopupConfigure));
+
+            m_autopopup_configure.add_grab_left = NOT_USED;
+            m_autopopup_configure.add_grab_right = NOT_USED;
+            m_autopopup_configure.add_grab_top = NOT_USED;
+            m_autopopup_configure.add_grab_bottom = NOT_USED;
+        }
+
+        int reload_autopopup_configure(const char* input_file) {
+            reset();
+            return parsing_autopopup_configure(input_file);
+        }
+        int parsing_autopopup_configure(const char* input_file) {
+            xmlDocPtr doc;
+            xmlNodePtr cur_node;
+
+            doc = xmlReadFile(input_file, NULL, 0);
+            if (doc == NULL) {
+                SCLLOG(SclLog::WARNING, "Could not load file: %s.", input_file);
+                return -1;
+            }
+
+            cur_node = xmlDocGetRootElement(doc);
+            if (cur_node == NULL) {
+                SCLLOG(SclLog::WARNING, "AutoPopupConfigParser: empty document.\n");
+                xmlFreeDoc(doc);
+                return -1;
+            }
+            if (0 != xmlStrcmp(cur_node->name, (const xmlChar*)"autopopup_configure"))
+            {
+                SCLLOG(SclLog::WARNING, "AutoPopup_Configure: root name error: %s\n!", (char *)cur_node->name);
+                xmlFreeDoc(doc);
+                return -1;
+            }
+
+            cur_node = cur_node->xmlChildrenNode;
+
+            while (cur_node != NULL) {
+                if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"background_image_path")) {
+                    xmlChar* temp = xmlNodeGetContent(cur_node);
+                    m_autopopup_configure.bg_image_path = (sclchar *)temp;
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"background_color")) {
+                    parsing_background_color(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"background_line_width")) {
+                    m_autopopup_configure.bg_line_width = get_content_int(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"background_line_color")) {
+                    parsing_background_line_color(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"background_padding")) {
+                    m_autopopup_configure.bg_padding = get_content_int(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"button_image_path")) {
+                    parsing_button_image_path(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"sw_button_style")) {
+                    m_autopopup_configure.sw_button_style = get_content_int(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"button_size")) {
+                    parsing_button_size(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"button_spacing")) {
+                    m_autopopup_configure.button_spacing = get_content_int(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"line_image_path")) {
+                    xmlChar* temp = xmlNodeGetContent(cur_node);
+                    m_autopopup_configure.line_image_path = (sclchar *)temp;
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"label_type")) {
+                    xmlChar* temp = xmlNodeGetContent(cur_node);
+                    m_autopopup_configure.label_type = (sclchar *)temp;
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"window_decorator")) {
+                    get_prop_number(cur_node, "size", &(m_autopopup_configure.decoration_size));
+                    parsing_window_decorator_image_path(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"max_column")) {
+                    m_autopopup_configure.max_column = get_content_int(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"grab_area")) {
+                    parsing_grab_area(cur_node);
+                }
+
+                cur_node = cur_node->next;
+            }
+            xmlFreeDoc(doc);
+            return 0;
+        }
+        void parsing_background_color(const xmlNodePtr cur_node) {
+            assert(cur_node != NULL);
+
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"r")) {
+                    m_autopopup_configure.bg_color.r = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"g")) {
+                    m_autopopup_configure.bg_color.g = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"b")) {
+                    m_autopopup_configure.bg_color.b = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"a")) {
+                    m_autopopup_configure.bg_color.a = get_content_int(child_node);
+                }
+
+                child_node = child_node->next;
+            }
+        }
+
+        void parsing_background_line_color(const xmlNodePtr cur_node) {
+            assert(cur_node != NULL);
+
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"r")) {
+                    m_autopopup_configure.bg_line_color.r = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"g")) {
+                    m_autopopup_configure.bg_line_color.g = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"b")) {
+                    m_autopopup_configure.bg_line_color.b = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"a")) {
+                    m_autopopup_configure.bg_line_color.a = get_content_int(child_node);
+                }
+
+                child_node = child_node->next;
+            }
+        }
+
+        void parsing_button_image_path(const xmlNodePtr cur_node) {
+            assert(cur_node != NULL);
+            assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"button_image_path"));
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"image")) {
+                    int button_state = get_button_state_prop(child_node);
+                    if (button_state >= 0 && button_state < SCL_BUTTON_STATE_MAX) {
+                        m_autopopup_configure.button_image_path[button_state] = (sclchar*)xmlNodeGetContent(child_node);
+                    }
+                }
+                child_node = child_node->next;
+            }
+        }
+
+        void parsing_button_size(const xmlNodePtr cur_node) {
+            assert(cur_node != NULL);
+
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"width")) {
+                    m_autopopup_configure.button_width = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"height")) {
+                    m_autopopup_configure.button_height = get_content_int(child_node);
+                }
+                child_node = child_node->next;
+            }
+        }
+
+        void parsing_window_decorator_image_path(const xmlNodePtr cur_node) {
+            assert(cur_node != NULL);
+            assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"window_decorator"));
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"image")) {
+                    if (equal_prop(child_node, "direction", "top_left")) {
+                        m_autopopup_configure.decoration_image_path[WND_DECORATOR_TOP_LEFT] = (sclchar *)xmlNodeGetContent(child_node);
+                    } else if (equal_prop(child_node, "direction", "top_center")) {
+                        m_autopopup_configure.decoration_image_path[WND_DECORATOR_TOP_CENTER] = (sclchar *)xmlNodeGetContent(child_node);
+                    } else if (equal_prop(child_node, "direction", "top_right")) {
+                        m_autopopup_configure.decoration_image_path[WND_DECORATOR_TOP_RIGHT] = (sclchar *)xmlNodeGetContent(child_node);
+                    } else if (equal_prop(child_node, "direction", "middle_left")) {
+                        m_autopopup_configure.decoration_image_path[WND_DECORATOR_MIDDLE_LEFT] = (sclchar *)xmlNodeGetContent(child_node);
+                    } else if (equal_prop(child_node, "direction", "middle_center")) {
+                        m_autopopup_configure.decoration_image_path[WND_DECORATOR_MIDDLE_CENTER] = (sclchar *)xmlNodeGetContent(child_node);
+                    } else if (equal_prop(child_node, "direction", "middle_right")) {
+                        m_autopopup_configure.decoration_image_path[WND_DECORATOR_MIDDLE_RIGHT] = (sclchar *)xmlNodeGetContent(child_node);
+                    } else if (equal_prop(child_node, "direction", "bottom_left")) {
+                        m_autopopup_configure.decoration_image_path[WND_DECORATOR_BOTTOM_LEFT] = (sclchar *)xmlNodeGetContent(child_node);
+                    } else if (equal_prop(child_node, "direction", "bottom_center")) {
+                        m_autopopup_configure.decoration_image_path[WND_DECORATOR_BOTTOM_CENTER] = (sclchar *)xmlNodeGetContent(child_node);
+                    } else if (equal_prop(child_node, "direction", "bottom_right")) {
+                        m_autopopup_configure.decoration_image_path[WND_DECORATOR_BOTTOM_RIGHT] = (sclchar *)xmlNodeGetContent(child_node);
+                    }
+                }
+                child_node = child_node->next;
+            }
+        }
+
+        void parsing_grab_area(const xmlNodePtr cur_node) {
+            assert(cur_node != NULL);
+
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"left")) {
+                    m_autopopup_configure.add_grab_left = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"right")) {
+                    m_autopopup_configure.add_grab_right = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"top")) {
+                    m_autopopup_configure.add_grab_top = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"bottom")) {
+                    m_autopopup_configure.add_grab_bottom = get_content_int(child_node);
+                }
+                child_node = child_node->next;
+            }
+        }
+
+        int get_button_state_prop(const xmlNodePtr cur_node) {
+            assert(cur_node != NULL);
+            int button_state = -1;
+
+            if (equal_prop(cur_node, "button_state", "pressed")) {
+                button_state = BUTTON_STATE_PRESSED;
+            } else if (equal_prop(cur_node, "button_state", "normal")) {
+                button_state = BUTTON_STATE_NORMAL;
+            } else if (equal_prop(cur_node, "button_state", "disabled")) {
+                button_state = BUTTON_STATE_DISABLED;
+            } else if (equal_prop(cur_node, "button_state", "toggled")) {
+                button_state = BUTTON_STATE_TOGGLED;
+            }
+            return button_state;
+        }
+        SCLDisplayMode get_content_displaymode(const xmlNodePtr cur_node) {
+            assert(cur_node != NULL);
+
+            SCLDisplayMode display_mode = DISPLAYMODE_PORTRAIT;
+
+            xmlChar* key = xmlNodeGetContent(cur_node);
+            if (key!= NULL) {
+                if (0 == strcmp("landscape", (const char*)key)) {
+                    display_mode = DISPLAYMODE_LANDSCAPE;
+                }
+                xmlFree(key);
+            }
+
+            return display_mode;
+        }
+        SclAutoPopupConfigure m_autopopup_configure;
+};
+
+AutoPopupConfigParser::AutoPopupConfigParser() {
+    m_impl = new AutoPopupConfigureParserImpl;
+}
+
+AutoPopupConfigParser::~AutoPopupConfigParser() {
+    if (m_impl) {
+        SCLLOG(SclLog::MESSAGE, "~AutoPopupConfigParser() has called");
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+
+AutoPopupConfigParser*
+AutoPopupConfigParser::get_instance() {
+    static AutoPopupConfigParser instance;
+    return &instance;
+}
+
+int
+AutoPopupConfigParser::init(const char* file) {
+    return m_impl->parsing_autopopup_configure(file);
+}
+
+int
+AutoPopupConfigParser::reload(const char* file) {
+    return m_impl->reload_autopopup_configure(file);
+}
+
+PSclAutoPopupConfigure
+AutoPopupConfigParser::get_autopopup_configure() {
+    return &m_impl->m_autopopup_configure;
+}
diff --git a/scl/autopopup_configure_parser.h b/scl/autopopup_configure_parser.h
new file mode 100644 (file)
index 0000000..86bc848
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 - 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 __AutoPopupConfigParser__H__
+#define __AutoPopupConfigParser__H__
+#include "sclres_type.h"
+
+typedef SclAutoPopupConfigure *PSclAutoPopupConfigure;
+
+class AutoPopupConfigureParserImpl;
+
+class AutoPopupConfigParser {
+    AutoPopupConfigureParserImpl *m_impl;
+    public:
+        int init(const char* file);
+        int reload(const char* file);
+        PSclAutoPopupConfigure get_autopopup_configure();
+    public:
+        ~AutoPopupConfigParser();
+        static AutoPopupConfigParser *get_instance();
+    private:
+        AutoPopupConfigParser();
+};
+
+
+#endif
diff --git a/scl/binary_xmlresource.cpp b/scl/binary_xmlresource.cpp
new file mode 100644 (file)
index 0000000..25b29e3
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2012 - 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 "binary_xmlresource.h"
+#include "string_bin_parser.h"
+#include "metadata_bin_parser.h"
+#include "parserinfo_provider.h"
+#include "string_provider.h"
+#include "metadata_provider.h"
+#include <assert.h>
+#include "simple_debug.h"
+
+using namespace binary_xmlresource;
+
+BinResource::BinResource() {
+    m_input_mode_configure_parser = NULL;
+    m_layout_parser = NULL;
+    m_key_coordinate_frame_parser = NULL;
+    m_modifier_decoration_parser = NULL;
+    m_label_properties_parser = NULL;
+    m_default_configure_parser = NULL;
+    m_autopopup_configure_parser = NULL;
+    m_magnifier_configure_parser = NULL;
+    m_nine_patch_file_list_parser = NULL;
+
+    memset(m_info, 0x00, sizeof(m_info));
+}
+
+BinResource::~BinResource() {
+    m_input_mode_configure_parser = NULL;
+    m_layout_parser = NULL;
+    m_key_coordinate_frame_parser = NULL;
+    m_modifier_decoration_parser = NULL;
+    m_label_properties_parser = NULL;
+    m_default_configure_parser = NULL;
+    m_autopopup_configure_parser = NULL;
+    m_magnifier_configure_parser = NULL;
+    m_nine_patch_file_list_parser = NULL;
+}
+
+BinResource* BinResource::get_instance() {
+    static BinResource instance;
+    return &instance;
+}
+
+void BinResource::init(const char *entry_filepath) {
+    SCLLOG_TIME_BEGIN();
+
+    char path[_POSIX_PATH_MAX] = {0};
+
+
+    snprintf(path, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), "sclresource.bin");
+
+    FileStorage storageAllData;
+    if (storageAllData.loadFile(path) <= 0) {
+        return;
+    }
+
+    const int _SIZE_WIDTH = 8;
+    const int OFFSET_WIDTH = 8;
+    int size_table[MAX_DATATYPE] = {0};
+    int offset_table[MAX_DATATYPE] = {0};
+    {
+        FileStorage headerStorage;
+        headerStorage.get_storage(storageAllData, 0, MAX_DATATYPE * (_SIZE_WIDTH + OFFSET_WIDTH));
+        for (int i = ALLDATA; i < MAX_DATATYPE; ++i) {
+            size_table[i] = headerStorage.get<sint_t>(_SIZE_WIDTH);
+            offset_table[i] = headerStorage.get<sint_t>(OFFSET_WIDTH);
+        }
+    }
+
+    for (int i = ALLDATA; i < MAX_DATATYPE; ++i) {
+        m_info[i].offset = offset_table[i];
+        m_info[i].size = size_table[i];
+    }
+
+    String_Bin_Parser stringBinParser(storageAllData, m_info[STRING].offset, m_info[STRING].size);
+    Metadata_Bin_Parser metadataBinParser(storageAllData, m_info[METADATA].offset, m_info[METADATA].size);
+
+    String_Provider stringProvider(&stringBinParser);
+    Metadata_Provider metadataProvider(&metadataBinParser);
+    ParserInfo_Provider parser_info_provider(&metadataProvider, &stringProvider);
+
+    if (m_input_mode_configure_parser == NULL) {
+        m_input_mode_configure_parser = BinInputModeConfigParser::get_instance();
+        m_input_mode_configure_parser->init(storageAllData, m_info[INPUT_MODE_CONFIGURE].offset, m_info[INPUT_MODE_CONFIGURE].size, &parser_info_provider);
+    }
+    if (m_default_configure_parser == NULL) {
+        m_default_configure_parser = BinDefaultConfigParser::get_instance();
+        m_default_configure_parser->init(storageAllData, m_info[DEFAULT_CONFIGURE].offset, m_info[DEFAULT_CONFIGURE].size, &parser_info_provider);
+    }
+   if (m_key_coordinate_frame_parser == NULL) {
+        m_key_coordinate_frame_parser = BinKeyCoordFrameParser::get_instance();
+        m_key_coordinate_frame_parser->init(storageAllData, m_info[KEY_COORDINATE_FRAME].offset, m_info[KEY_COORDINATE_FRAME].size, &parser_info_provider);
+    }
+
+   if (m_layout_parser == NULL) {
+        m_layout_parser = BinLayoutParser::get_instance();
+        m_layout_parser->init(storageAllData, m_info[LAYOUT].offset, m_info[LAYOUT].size, &parser_info_provider);
+    }
+    if (m_modifier_decoration_parser == NULL) {
+        m_modifier_decoration_parser = BinModifierDecorationParser::get_instance();
+        m_modifier_decoration_parser->init(storageAllData, m_info[MODIFIER_DECORATION].offset, m_info[MODIFIER_DECORATION].size, &parser_info_provider);
+    }
+    if (m_label_properties_parser == NULL) {
+        m_label_properties_parser = BinLabelPropertyParser::get_instance();
+        m_label_properties_parser->init(storageAllData, m_info[LABEL_PROPERTIES_FRAME].offset, m_info[LABEL_PROPERTIES_FRAME].size, &parser_info_provider);
+    }
+
+    if (m_autopopup_configure_parser == NULL) {
+        m_autopopup_configure_parser = BinAutoPopupConfigParser::get_instance();
+        m_autopopup_configure_parser->init(storageAllData, m_info[AUTOPOPUP_CONFIGURE].offset, m_info[AUTOPOPUP_CONFIGURE].size, &parser_info_provider);
+    }
+    if (m_magnifier_configure_parser == NULL) {
+        m_magnifier_configure_parser = BinMagnifierConfigParser::get_instance();
+        m_magnifier_configure_parser->init(storageAllData, m_info[MAGNIFIER_CONFIGURE].offset, m_info[MAGNIFIER_CONFIGURE].size, &parser_info_provider);
+    }
+
+    if (m_nine_patch_file_list_parser == NULL) {
+        m_nine_patch_file_list_parser = BinNinePatchFileParser::get_instance();
+        m_nine_patch_file_list_parser->init(storageAllData, m_info[NINE_PATCH].offset, m_info[NINE_PATCH].size, &parser_info_provider);
+    }
+
+    SCLLOG_TIME_END("Parsing binary XML files");
+}
+
+void BinResource::reload() {
+    // We do not support reload function at BinResource class yet
+}
+
+void BinResource::load(int layout_id) {
+    //m_layout_parser->load(layout_id);
+    m_key_coordinate_frame_parser->load(layout_id);
+}
+void BinResource::unload() {
+    //m_layout_parser->unload();
+    m_key_coordinate_frame_parser->unload();
+}
+bool BinResource::loaded(int layout_id) {
+    //return m_layout_parser->loaded(layout_id);
+    return m_key_coordinate_frame_parser->loaded(layout_id);
+}
+
+int BinResource::get_labelproperty_size() {
+    return m_label_properties_parser->get_size();
+}
+bool BinResource::get_nine_patch_info(const char *filename, SclNinePatchInfo *info) {
+    return m_nine_patch_file_list_parser->get_nine_patch_info(filename, info);
+}
+int BinResource::get_inputmode_id(const char *name) {
+    return m_input_mode_configure_parser->get_inputmode_id(name);
+}
+const char* BinResource::get_inputmode_name(int id) {
+    return m_input_mode_configure_parser->get_inputmode_name(id);
+}
+int BinResource::get_inputmode_size() {
+    return m_input_mode_configure_parser->get_inputmode_size();
+}
+PSclInputModeConfigure BinResource::get_input_mode_configure_table() {
+    return m_input_mode_configure_parser->get_input_mode_configure_table();
+}
+int BinResource::get_layout_id(const char *name) {
+    return m_layout_parser->get_layout_index(name);
+}
+int BinResource::get_layout_size() {
+    return m_layout_parser->get_layout_size();
+}
+int BinResource::get_modifier_decoration_id(const char *name) {
+    return m_modifier_decoration_parser->get_modifier_decoration_id(name);
+}
+PSclLayout BinResource::get_layout_table() {
+    return m_layout_parser->get_layout_table();
+}
+PSclLayoutKeyCoordinatePointerTable BinResource::get_key_coordinate_pointer_frame() {
+    return m_layout_parser->get_key_coordinate_pointer_frame();
+}
+PSclModifierDecoration BinResource::get_modifier_decoration_table() {
+    return m_modifier_decoration_parser->get_modifier_decoration_table();
+}
+
+PSclLabelPropertiesTable BinResource::get_label_properties_frame() {
+    return m_label_properties_parser->get_label_properties_frame();
+}
+
+PSclDefaultConfigure BinResource::get_default_configure() {
+    return m_default_configure_parser->get_default_configure();
+}
+
+PSclAutoPopupConfigure BinResource::get_autopopup_configure() {
+    return m_autopopup_configure_parser->get_autopopup_configure();
+}
+
+PSclMagnifierWndConfigure BinResource::get_magnifier_configure() {
+    return m_magnifier_configure_parser->get_magnifier_configure();
+}
diff --git a/scl/binary_xmlresource.h b/scl/binary_xmlresource.h
new file mode 100644 (file)
index 0000000..890111c
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012 - 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 __BIN_XMLRESOURCE__
+#define __BIN_XMLRESOURCE__
+
+#include <limits.h>
+#include <libxml/parser.h>
+#include "input_mode_configure_bin_parser.h"
+#include "layout_bin_parser.h"
+#include "key_coordinate_frame_bin_parser.h"
+#include "modifier_decoration_bin_parser.h"
+#include "label_properties_bin_parser.h"
+#include "default_configure_bin_parser.h"
+#include "autopopup_configure_bin_parser.h"
+#include "magnifier_configure_bin_parser.h"
+#include "nine_patch_file_list_bin_parser.h"
+#include "sclres.h"
+struct resource_info_t{
+    int offset;
+    int size;
+};
+
+
+enum{
+    ALLDATA = 0,
+    METADATA,
+    INPUT_MODE_CONFIGURE,
+    LAYOUT,
+    KEY_COORDINATE_FRAME,
+    LABEL_PROPERTIES_FRAME,
+    MODIFIER_DECORATION,
+    DEFAULT_CONFIGURE,
+    AUTOPOPUP_CONFIGURE,
+    MAGNIFIER_CONFIGURE,
+    NINE_PATCH,
+    STRING,
+    MAX_DATATYPE
+};
+namespace binary_xmlresource {
+class BinResource: public sclres::SclRes{
+    public:
+    ~BinResource();
+    static BinResource* get_instance();
+    void init(const char *entry_filepath);
+    void reload();
+
+    /* These functions are for dynamic (lazy) loading layouts */
+    void load(int layout_id);
+    void unload();
+    bool loaded(int layout_id);
+
+    public:
+    PSclInputModeConfigure get_input_mode_configure_table();
+    PSclLayout get_layout_table();
+    PSclLayoutKeyCoordinatePointerTable get_key_coordinate_pointer_frame();
+    PSclModifierDecoration get_modifier_decoration_table();
+    PSclLabelPropertiesTable get_label_properties_frame();
+    PSclDefaultConfigure get_default_configure();
+    PSclAutoPopupConfigure get_autopopup_configure();
+    PSclMagnifierWndConfigure get_magnifier_configure();
+
+    int get_inputmode_id(const char *name);
+    const char* get_inputmode_name(int id);
+    int get_inputmode_size();
+    int get_layout_id(const char* name);
+    int get_layout_size();
+    int get_labelproperty_size();
+    int get_modifier_decoration_id(const char *name);
+    bool get_nine_patch_info(const char *filename, SclNinePatchInfo *info);
+
+    const char* get_name() {
+        return "binary_xmlparser";
+    }
+
+    void destroy();
+    struct resource_info_t m_info[MAX_DATATYPE];
+    private:
+    BinResource();
+
+    private:
+    BinInputModeConfigParser *m_input_mode_configure_parser;
+    BinLayoutParser *m_layout_parser;
+    BinKeyCoordFrameParser *m_key_coordinate_frame_parser;
+    BinModifierDecorationParser *m_modifier_decoration_parser;
+    BinLabelPropertyParser *m_label_properties_parser;
+    BinDefaultConfigParser *m_default_configure_parser;
+    BinAutoPopupConfigParser *m_autopopup_configure_parser;
+    BinMagnifierConfigParser *m_magnifier_configure_parser;
+    BinNinePatchFileParser *m_nine_patch_file_list_parser;
+};
+}
+
+#endif
+
diff --git a/scl/default_configure_bin_parser.cpp b/scl/default_configure_bin_parser.cpp
new file mode 100644 (file)
index 0000000..5e89685
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2012 - 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 "default_configure_bin_parser.h"
+#include <assert.h>
+using namespace std;
+#include "put_record.h"
+
+BinDefaultConfigParser::BinDefaultConfigParser() {
+    memset((void*)&m_default_configure, 0x00, sizeof(SclDefaultConfigure));
+    parser_info_provider = NULL;
+}
+
+BinDefaultConfigParser::~BinDefaultConfigParser() {
+}
+
+BinDefaultConfigParser* BinDefaultConfigParser::get_instance() {
+    static BinDefaultConfigParser instance;
+    return &instance;
+}
+
+void BinDefaultConfigParser::init(const FileStorage& storage, int offset, int size,  IParserInfo_Provider* provider) {
+    m_storage.set_str_provider(provider);
+    m_storage.get_storage(storage, offset, size);
+    this->parser_info_provider = provider;
+    parsing_default_configure();
+}
+void
+BinDefaultConfigParser::decode_color(SclColor& color, int width) {
+    if (width <= 0) return;
+
+    color.r = m_storage.get<sint_t>(width);
+    color.g = m_storage.get<sint_t>(width);
+    color.b = m_storage.get<sint_t>(width);
+    color.a = m_storage.get<sint_t>(width);
+}
+
+void BinDefaultConfigParser::parsing_default_configure() {
+    PSclDefaultConfigure cur = &m_default_configure;
+
+    Default_configure_width record_width;
+    set_default_configure_width(*parser_info_provider, record_width);
+
+    // skip data_size
+    m_storage.advance(8);
+
+    //display_mode
+    cur->display_mode = (SCLDisplayMode)m_storage.get<sint_t>(record_width.display_mode);
+
+    //input_mode
+    m_storage.get_str(&(cur->input_mode), record_width.input_mode, m_string_collector);
+
+    //image_file_base_path
+    m_storage.get_str(&(cur->image_file_base_path), record_width.image_file_base_path, m_string_collector);
+
+    //target_screen_width
+    cur->target_screen_width = m_storage.get<sint_t>(record_width.target_screen_width);
+
+    //target_screen_height
+    cur->target_screen_height = m_storage.get<sint_t>(record_width.target_screen_height);
+
+    //auto_detect_landscape
+    cur->auto_detect_landscape = m_storage.get<sint_t>(record_width.auto_detect_landscape);
+
+    //use_magnifier_window
+    cur->use_magnifier_window = m_storage.get<sint_t>(record_width.use_magnifier_window);
+
+    //use_auto_popup
+    cur->use_auto_popup = m_storage.get<sint_t>(record_width.use_auto_popup);
+
+    //use_zoom_window
+    cur->use_zoom_window = m_storage.get<sint_t>(record_width.use_zoom_window);
+
+    //on_error_noti_send
+    cur->on_error_noti_send = m_storage.get<sint_t>(record_width.on_error_noti_send);
+
+    //use_word_deletion
+    cur->use_word_deletion = m_storage.get<sint_t>(record_width.use_word_deletion);
+
+    //sw_button_style
+    cur->sw_button_style = m_storage.get<sint_t>(record_width.sw_button_style);
+
+    //touch_offset_level
+    for (int i = 0; i < DISPLAYMODE_MAX; ++i) {
+        cur->touch_offset_level[i] = (SCLTouchOffsetLevel)m_storage.get<sint_t>(record_width.touch_offset_level);
+    }
+
+    //touch_offset
+    for (int i = 0; i < DISPLAYMODE_MAX; ++i) {
+        cur->touch_offset[i].x = m_storage.get<sint_t>(record_width.touch_offset);
+        cur->touch_offset[i].y = m_storage.get<sint_t>(record_width.touch_offset);
+    }
+
+    //default_sub_layout
+    m_storage.get_str(&(cur->default_sub_layout), record_width.default_sub_layout, m_string_collector);
+
+    //use_actual_dim_window
+    cur->use_actual_dim_window = m_storage.get<sint_t>(record_width.use_actual_dim_window);
+
+    //dim_color
+    decode_color(cur->dim_color, record_width.dim_color);
+
+#ifdef __SCL_TXT_DEBUG
+    put_default_configure(DECODE, m_default_configure);
+#endif
+}
+
+PSclDefaultConfigure BinDefaultConfigParser::get_default_configure() {
+    return &m_default_configure;
+}
+
diff --git a/scl/default_configure_bin_parser.h b/scl/default_configure_bin_parser.h
new file mode 100644 (file)
index 0000000..79944dc
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012 - 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 __DEFAULT_CONFIGURE_BIN_PARSER__H__
+#define __DEFAULT_CONFIGURE_BIN_PARSER__H__
+#include "sclres_type.h"
+#include "string_collector.h"
+#include "iparserinfo_provider.h"
+#include "file_storage_impl.h"
+#include "_auto_metadata.h"
+class BinDefaultConfigParser {
+public:
+    ~BinDefaultConfigParser();
+    static BinDefaultConfigParser *get_instance();
+    void init(const FileStorage& storage, int, int, IParserInfo_Provider*);
+
+    PSclDefaultConfigure get_default_configure();
+
+
+    //These private methods for parsing
+private:
+    BinDefaultConfigParser();
+    void parsing_default_configure();
+    void decode_color(SclColor&, int width);
+private:
+    SclDefaultConfigure m_default_configure;
+    StringCollector m_string_collector;
+    IParserInfo_Provider* parser_info_provider;
+    FileStorage m_storage;
+};
+
+
+#endif
diff --git a/scl/default_configure_parser.cpp b/scl/default_configure_parser.cpp
new file mode 100644 (file)
index 0000000..ef5496c
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2012 - 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 <assert.h>
+#include <string.h>
+#include <libxml/parser.h>
+#include "default_configure_parser.h"
+#include "xml_parser_utils.h"
+#include "simple_debug.h"
+using namespace std;
+
+class DefaultConfigureParserImpl {
+    public:
+        DefaultConfigureParserImpl() {
+            memset((void*)&m_default_configure, 0x00, sizeof(SclDefaultConfigure));
+        }
+
+        ~DefaultConfigureParserImpl() {
+            reset();
+        }
+
+        void reset() {
+            if (m_default_configure.input_mode) {
+                xmlFree(m_default_configure.input_mode);
+                m_default_configure.input_mode = NULL;
+            }
+
+            if (m_default_configure.input_mode) {
+                xmlFree(m_default_configure.input_mode);
+                m_default_configure.input_mode = NULL;
+            }
+
+            if (m_default_configure.image_file_base_path) {
+                xmlFree(m_default_configure.image_file_base_path);
+                m_default_configure.image_file_base_path = NULL;
+            }
+
+            if (m_default_configure.default_sub_layout) {
+                xmlFree(m_default_configure.default_sub_layout);
+                m_default_configure.default_sub_layout = NULL;
+            }
+            memset((void*)&m_default_configure, 0x00, sizeof(SclDefaultConfigure));
+        }
+
+        int reload_default_configure(const char* input_file) {
+            reset();
+            return parsing_default_configure(input_file);
+        }
+        int parsing_default_configure(const char* input_file) {
+            xmlDocPtr doc;
+            xmlNodePtr cur_node;
+
+            doc = xmlReadFile(input_file, NULL, 0);
+            if (doc == NULL) {
+                SCLLOG(SclLog::DEBUG, "Could not load file: %s.", input_file);
+                return -1;
+            }
+
+            cur_node = xmlDocGetRootElement(doc);
+            if (cur_node == NULL) {
+                SCLLOG(SclLog::DEBUG, "DefaultConfigParser: empty document.\n");
+                xmlFreeDoc(doc);
+                return -1;
+            }
+            if (0 != xmlStrcmp(cur_node->name, (const xmlChar*)"default_configure"))
+            {
+                SCLLOG(SclLog::DEBUG, "DefaultConfigParser: root name error: %s\n!", (char *)cur_node->name);
+                xmlFreeDoc(doc);
+                return -1;
+            }
+
+            cur_node = cur_node->xmlChildrenNode;
+
+            while (cur_node != NULL) {
+                if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"display")) {
+                    m_default_configure.display_mode = get_content_display_mode(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"input_mode")) {
+                    xmlChar* temp = xmlNodeGetContent(cur_node);
+                    m_default_configure.input_mode = (sclchar *)temp;
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"base_screen_width")) {
+                    m_default_configure.target_screen_width = get_content_int(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"base_screen_height")) {
+                    m_default_configure.target_screen_height = get_content_int(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"auto_detect_landscape")) {
+                    m_default_configure.auto_detect_landscape = get_content_bool(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"image_file_base_path")) {
+                    xmlChar* temp = xmlNodeGetContent(cur_node);
+                    m_default_configure.image_file_base_path = (sclchar *)temp;
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"use_magnifier")) {
+                    m_default_configure.use_magnifier_window = get_content_bool(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"use_autopopup")) {
+                    m_default_configure.use_auto_popup = get_content_bool(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"use_zoomwindow")) {
+                    m_default_configure.use_zoom_window = get_content_bool(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"use_error_sound")) {
+                    m_default_configure.on_error_noti_send = get_content_bool(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"use_word_deletion")) {
+                    m_default_configure.use_word_deletion = get_content_bool(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"touch_offset_level")) {
+                    // Let's skip this item since it does not seem to be useful anymore
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"touch_offset")) {
+                    // Let's skip this item since it does not seem to be useful anymore
+                    parsing_touch_offset(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"default_sub_layout")) {
+                    xmlChar* temp = xmlNodeGetContent(cur_node);
+                    m_default_configure.default_sub_layout = (sclchar *)temp;
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"dim_use_window_flag")) {
+                    m_default_configure.use_actual_dim_window = get_content_bool(cur_node);
+                } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"dim_color")) {
+                    parsing_dim_color(cur_node);
+                }
+                cur_node = cur_node->next;
+            }
+            xmlFreeDoc(doc);
+
+            return 0;
+        }
+
+        void parsing_touch_offset(const xmlNodePtr cur_node) {
+            assert(cur_node != NULL);
+
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"portrait")) {
+                    xmlNodePtr grandChildNode = child_node->xmlChildrenNode;
+                    while (grandChildNode != NULL) {
+                        if (0 == xmlStrcmp(grandChildNode->name, (const xmlChar*)"x")) {
+                            m_default_configure.touch_offset[DISPLAYMODE_PORTRAIT].x = get_content_int(grandChildNode);
+                        } else if (0 == xmlStrcmp(grandChildNode->name, (const xmlChar*)"y")) {
+                            m_default_configure.touch_offset[DISPLAYMODE_PORTRAIT].y = get_content_int(grandChildNode);
+                        }
+                        grandChildNode = grandChildNode->next;
+                    }
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"landscape")) {
+                    xmlNodePtr grandChildNode = child_node->xmlChildrenNode;
+                    while (grandChildNode != NULL) {
+                        if (0 == xmlStrcmp(grandChildNode->name, (const xmlChar*)"x")) {
+                            m_default_configure.touch_offset[DISPLAYMODE_LANDSCAPE].x = get_content_int(grandChildNode);
+                        } else if (0 == xmlStrcmp(grandChildNode->name, (const xmlChar*)"y")) {
+                            m_default_configure.touch_offset[DISPLAYMODE_LANDSCAPE].y = get_content_int(grandChildNode);
+                        }
+                        grandChildNode = grandChildNode->next;
+                    }
+                }
+
+                child_node = child_node->next;
+            }
+        }
+
+        void parsing_dim_color(const xmlNodePtr cur_node) {
+            assert(cur_node != NULL);
+
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"r")) {
+                    m_default_configure.dim_color.r = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"g")) {
+                    m_default_configure.dim_color.g = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"b")) {
+                    m_default_configure.dim_color.b = get_content_int(child_node);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"a")) {
+                    m_default_configure.dim_color.a = get_content_int(child_node);
+                }
+
+                child_node = child_node->next;
+            }
+        }
+
+        SCLDisplayMode get_content_display_mode(const xmlNodePtr cur_node) {
+            assert(cur_node != NULL);
+
+            SCLDisplayMode display_mode = DISPLAYMODE_PORTRAIT;
+
+            xmlChar* key = xmlNodeGetContent(cur_node);
+            if (key!= NULL) {
+                if (0 == strcmp("landscape", (const char*)key)) {
+                    display_mode = DISPLAYMODE_LANDSCAPE;
+                }
+                xmlFree(key);
+            }
+
+            return display_mode;
+        }
+        SclDefaultConfigure m_default_configure;
+};
+
+DefaultConfigParser*
+DefaultConfigParser::get_instance() {
+    static DefaultConfigParser instance;
+    return &instance;
+}
+DefaultConfigParser::DefaultConfigParser() {
+    m_impl = new DefaultConfigureParserImpl;
+}
+
+DefaultConfigParser::~DefaultConfigParser() {
+    if (m_impl) {
+        SCLLOG(SclLog::MESSAGE, "~DefaultConfigParser() has called");
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+
+int
+DefaultConfigParser::init(const char* file) {
+        return m_impl->parsing_default_configure(file);
+}
+
+int
+DefaultConfigParser::reload(const char* file) {
+    return m_impl->reload_default_configure(file);
+}
+
+PSclDefaultConfigure
+DefaultConfigParser::get_default_configure() {
+    return &m_impl->m_default_configure;
+}
diff --git a/scl/default_configure_parser.h b/scl/default_configure_parser.h
new file mode 100644 (file)
index 0000000..e977907
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 - 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 __DEFAULT_CONFIGURE_PARSER__H__
+#define __DEFAULT_CONFIGURE_PARSER__H__
+#include "sclres_type.h"
+
+typedef SclDefaultConfigure *PSclDefaultConfigure;
+
+class DefaultConfigureParserImpl;
+
+class DefaultConfigParser {
+    DefaultConfigureParserImpl *m_impl;
+public:
+    int init(const char* file);
+    int reload(const char* file);
+    PSclDefaultConfigure get_default_configure();
+public:
+    ~DefaultConfigParser();
+    static DefaultConfigParser *get_instance();
+private:
+    DefaultConfigParser();
+};
+
+
+#endif
diff --git a/scl/file_storage.cpp b/scl/file_storage.cpp
new file mode 100644 (file)
index 0000000..64d5702
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2012 - 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 "file_storage_impl.h"
+
+FileStorage::FileStorage(const IString_Provider* string_provider):
+    m_storage(NULL),
+    m_offset(0),
+    m_size(0),
+    m_string_provider(string_provider) {
+    }
+
+FileStorage::~FileStorage() {
+    if (m_storage) {
+        delete []m_storage;
+    }
+    m_storage = NULL;
+    m_size = 0;
+    m_offset = 0;
+}
+
+int FileStorage::
+get_offset() const {
+    return m_offset;
+}
+void FileStorage::
+set_str_provider(const IString_Provider* string_provider) {
+    this->m_string_provider = string_provider;
+}
+const char* FileStorage::
+get_str(int width) {
+    assert(m_string_provider);
+
+    if (width <= 0) return NULL;
+
+    int string_no = get<sint_t>(width);
+    return m_string_provider->get_string_by_id(string_no);
+}
+
+void FileStorage::
+get_str(char** p, int width, IStringCollector& collector) {
+    if (p == NULL) return;
+    const char* str = get_str(width);
+    if (str != NULL) {
+        int len = strlen(str) + 1;
+        *p = new char[len];
+        strncpy((*p), str, len);
+        collector.add(*p);
+    } else {
+        *p = NULL;
+    }
+}
+
+void FileStorage::
+advance(int bytes) {
+    m_offset += bytes;
+}
+
+const char* FileStorage::
+get_str() {
+    // the length of the string, not include '\0'
+    int len = get<sint_t>(1);
+    // the string stored in storage are end with '\0'
+    const char* str = m_storage + m_offset;
+    m_offset += len + 1;
+    return str;
+}
+
+int FileStorage::
+    loadFile(const char* file_name) {
+    if (file_name == NULL) return -1;
+
+    FILE* fp = fopen(file_name, "rb");
+    if (fp == NULL) {
+        return -1;
+    }
+
+    if (m_storage != NULL) {
+        delete[] m_storage;
+    }
+    m_storage = NULL;
+
+    if (0 != fseek(fp, 0L, SEEK_END)) {
+        fclose(fp);
+        return -1;
+    }
+
+    long size = ftell(fp);
+
+    if (size > 0) {
+        m_storage = new char[size];
+    }
+    if (m_storage == NULL) {
+        fclose(fp);
+        return -1;
+    }
+
+    if (0 != fseek(fp, 0L, SEEK_SET)) {
+        if (m_storage) {
+            delete []m_storage;
+        }
+        m_storage = NULL;
+        fclose(fp);
+        return -1;
+    }
+    if (size > 0 && 1 != fread(m_storage, size, 1, fp)) {
+        if (m_storage) {
+            delete []m_storage;
+        }
+        m_storage = NULL;
+        fclose(fp);
+        return -1;
+    }
+    fclose(fp);
+
+    m_size = size;
+    m_offset = 0;
+    return m_size;
+}
+int FileStorage::
+    loadFile(const char* file_name, int offset, int size) {
+    if (file_name == NULL) return -1;
+    if (offset < 0 || size <= 0) return -1;
+
+    FILE* fp = fopen(file_name, "rb");
+    if (fp == NULL) {
+        return -1;
+    }
+
+    if (m_storage != NULL) {
+        delete[] m_storage;
+    }
+    m_storage = NULL;
+
+    if (0 != fseek(fp, 0L, SEEK_END)) {
+        fclose(fp);
+        return -1;
+    }
+
+    int file_size = ftell(fp);
+    if (file_size < offset + size) {
+        fclose(fp);
+        return -1;
+    }
+    m_storage = new char[size];
+    if (m_storage == NULL) {
+        fclose(fp);
+        return -1;
+    }
+
+    int nbytes = 0;
+    if (fseek(fp, offset, 0) != -1) {
+        nbytes = fread(m_storage, size, 1, fp);
+    }
+    if (nbytes != 1) {
+        if (m_storage) {
+            delete []m_storage;
+        }
+        m_storage = NULL;
+        fclose(fp);
+        return -1;
+    }
+    fclose(fp);
+
+    m_size = size;
+    m_offset = 0;
+    return m_size;
+}
+int FileStorage::
+get_size() const {
+    return m_size;
+}
+int FileStorage::
+get_storage(const FileStorage& storage, int offset, int block_size) {
+    if (offset < 0 || block_size <= 0) return -1;
+    if (storage.get_size() < offset + block_size) return -1;
+
+    if (m_storage != NULL) {
+        delete[] m_storage;
+    }
+
+    m_storage = new char[block_size];
+    if (m_storage == NULL) {
+        return -1;
+    }
+
+    memcpy(m_storage, storage.m_storage + offset, block_size);
+
+    m_size = block_size;
+    m_offset = 0;
+    return 0;
+}
diff --git a/scl/file_storage.h b/scl/file_storage.h
new file mode 100644 (file)
index 0000000..56a5a60
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012 - 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 __FILE_STORAGE_H__
+#define __FILE_STORAGE_H__
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "istring_provider.h"
+#include "istring_collector.h"
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+typedef char int8;
+typedef short int16;
+typedef int int32;
+typedef long long int64;
+typedef float float32;
+typedef double float64;
+
+typedef int64 sint_t;
+typedef uint64 uint_t;
+typedef float64 float_t;
+using namespace std;
+class FileStorage{
+    public:
+        FileStorage(const IString_Provider* string_provider = NULL);
+    ~FileStorage();
+
+    int get_offset() const;
+    void set_str_provider(const IString_Provider*);
+    template <typename T>
+    T get(int width);
+
+    const char* get_str(int width);
+
+    void get_str(char** p, int width, IStringCollector& collector);
+
+    const char* get_str();
+
+    int loadFile(const char* file_name);
+    int loadFile(const char* file_name, int offset, int size);
+    /** brief get_storage from a field of another storage
+     */
+    int get_storage(const FileStorage&, int offset, int block_size);
+
+    void advance(int bytes);
+    int get_size() const;
+
+    private:
+    /** brief unify get_xx method name
+     */
+    template <typename T>
+    T get_primitive_data();
+
+    uint8 get_uint8();
+    uint16 get_uint16();
+    uint32 get_uint32();
+    uint64 get_uint64();
+    int8 get_int8();
+    int16 get_int16();
+    int32 get_int32();
+    int64 get_int64();
+    float32 get_float32();
+    float64 get_float64();
+
+    char* m_storage; /* memory that read from bin file */
+    int m_offset; /* current offset of the memory */
+    int m_size; /* the size of the memory */
+
+    /** brief Infact, the strings' ids are stored for structures
+    * m_string_provider can get the actual string by id
+    */
+    const IString_Provider* m_string_provider;
+};
+
+#endif
diff --git a/scl/file_storage_impl.h b/scl/file_storage_impl.h
new file mode 100644 (file)
index 0000000..ff4641c
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2012 - 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 __FILE_STORAGE_IMPL_H__
+#define __FILE_STORAGE_IMPL_H__
+#include "file_storage.h"
+///////////////////////////////////////
+inline uint8 FileStorage::
+get_uint8() {
+    uint8* p = (uint8*)(m_storage + m_offset);
+    m_offset += sizeof(uint8);
+    return *p;
+}
+inline uint16 FileStorage::
+get_uint16() {
+    uint16* p = (uint16*)(m_storage + m_offset);
+    m_offset += sizeof(uint16);
+    return *p;
+}
+inline uint32 FileStorage::
+get_uint32() {
+    uint32* p = (uint32*)(m_storage + m_offset);
+    m_offset += sizeof(uint32);
+    return *p;
+}
+inline uint64 FileStorage::
+get_uint64() {
+    uint64* p = (uint64*)(m_storage + m_offset);
+    m_offset += sizeof(uint64);
+    return *p;
+}
+// in put_methods,
+// inline put_intx(intx data) {
+//    put_uintx(data);
+// }
+// so below is ok
+inline int8 FileStorage::
+get_int8() {
+    return (int)get_uint8();
+}
+
+inline int16 FileStorage::
+get_int16() {
+    return (int)get_uint16();
+}
+inline int32 FileStorage::
+get_int32() {
+    return (int)get_uint32();
+}
+inline int64 FileStorage::
+get_int64() {
+    return (int)get_uint64();
+}
+//float32
+inline float32 FileStorage::
+get_float32() {
+    union{
+        float32 m;
+        uint32 n;
+    };
+
+    n = get_uint32();
+    return m;
+}
+//float64
+inline float64 FileStorage::
+get_float64() {
+    union{
+        float64 m;
+        uint64 n;
+    };
+
+    n = get_uint64();
+    return m;
+}
+
+//unify put_xx method name
+//the width is sizeof(T)
+template <>
+inline uint8 FileStorage::
+get_primitive_data<uint8>() {
+    return get_uint8();
+}
+template <>
+inline uint16 FileStorage::
+get_primitive_data<uint16>() {
+    return get_uint16();
+}
+
+template <>
+inline uint32 FileStorage::
+get_primitive_data<uint32>() {
+    return get_uint32();
+}
+template <>
+inline uint64 FileStorage::
+get_primitive_data<uint64>() {
+    return get_uint64();
+}
+template <>
+inline int8 FileStorage::
+get_primitive_data<int8>() {
+    return get_int8();
+}
+template <>
+inline int16 FileStorage::
+get_primitive_data<int16>() {
+    return get_int16();
+}
+
+template <>
+inline int32 FileStorage::
+get_primitive_data<int32>() {
+    return get_int32();
+}
+template <>
+inline int64 FileStorage::
+get_primitive_data<int64>() {
+    return get_int64();
+}
+template <>
+inline float32 FileStorage::
+get_primitive_data<float32>() {
+    return get_float32();
+}
+template <>
+inline float64 FileStorage::
+get_primitive_data<float64>() {
+    return get_float64();
+}
+//put sint_t value to storage
+//width is assigned by para "width"
+template <>
+inline sint_t FileStorage::
+get<sint_t>(int width) {
+    switch (width) {
+        case 0:
+            /*Nothing to put*/
+            break;
+        case 1:
+            return get_primitive_data<int8>();
+        case 2:
+            return get_primitive_data<int16>();
+        case 4:
+            return get_primitive_data<int32>();
+        case 8:
+            return get_primitive_data<int64>();
+        default:
+            break;
+    }
+    return -1;
+}
+template <>
+inline uint_t FileStorage::
+get<uint_t>(int width) {
+    switch (width) {
+        case 0:
+            /*Nothing to put*/
+            break;
+        case 1:
+            return get_primitive_data<uint8>();
+        case 2:
+            return get_primitive_data<uint16>();
+        case 4:
+            return get_primitive_data<uint32>();
+        case 8:
+            return get_primitive_data<uint64>();
+        default:
+            break;
+    }
+    return -1;
+}
+
+template <>
+inline float_t FileStorage::
+get<float_t>(int width) {
+    switch (width) {
+        case 0:
+            return 0;
+        case 4:
+            return (float_t)get_primitive_data<float32>();
+        case 8:
+            return (float_t)get_primitive_data<float64>();
+        default:
+            break;
+    }
+    return -1;
+}
+#endif
diff --git a/scl/imetadata_provider.h b/scl/imetadata_provider.h
new file mode 100644 (file)
index 0000000..4f30d7b
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 - 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 __IMETADATA_PROVIDER_H__
+#define __IMETADATA_PROVIDER_H__
+class IMetadata_Provider{
+    public:
+        virtual void set_current_metadata_record(const char* record_name) = 0;
+        virtual int get_width(const char* fieldName)const = 0;
+        virtual ~IMetadata_Provider() {}
+};
+#endif
diff --git a/scl/input_mode_configure_bin_parser.cpp b/scl/input_mode_configure_bin_parser.cpp
new file mode 100644 (file)
index 0000000..2635a46
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2012 - 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 "input_mode_configure_bin_parser.h"
+#include "simple_debug.h"
+#include "put_record.h"
+using namespace std;
+
+BinInputModeConfigParser::BinInputModeConfigParser() {
+    m_inputmode_size = 0;
+    memset(m_input_mode_configure_table, 0x00, sizeof(SclInputModeConfigure) * MAX_SCL_INPUT_MODE);
+    parser_info_provider = NULL;
+}
+
+BinInputModeConfigParser::~BinInputModeConfigParser() {
+}
+
+BinInputModeConfigParser*
+BinInputModeConfigParser::get_instance() {
+    static BinInputModeConfigParser instance;
+    return &instance;
+}
+
+void
+BinInputModeConfigParser::init(const FileStorage& storage, int offset, int size, IParserInfo_Provider* provider) {
+    m_storage.set_str_provider(parser_info_provider);
+    m_storage.get_storage(storage, offset, size);
+    this->parser_info_provider = provider;
+    parsing_input_mode_configure_table();
+}
+
+int
+BinInputModeConfigParser::get_inputmode_id(const char *name) {
+    if (name == NULL) return -1;
+
+    for (int i = 0; i < MAX_SCL_INPUT_MODE; ++i) {
+        if ( m_input_mode_configure_table[i].name ) {
+            if ( 0 == strcmp(m_input_mode_configure_table[i].name, name) ) {
+                return i;
+            }
+        }
+    }
+
+    return -1;
+}
+
+const char*
+BinInputModeConfigParser::get_inputmode_name(int id) {
+    if (id >= 0 && id < MAX_SCL_INPUT_MODE) {
+        return m_input_mode_configure_table[id].name;
+    }
+
+    return NULL;
+}
+
+int
+BinInputModeConfigParser::get_inputmode_size() {
+    return m_inputmode_size;
+}
+
+void
+BinInputModeConfigParser::parsing_input_mode_configure_table() {
+    // skip data_size
+    m_storage.advance(8);
+
+    //rec_num
+    m_inputmode_size = m_storage.get<sint_t>(4);
+
+    Input_mode_configure_width record_width;
+    set_input_mode_configure_width(*parser_info_provider, record_width);
+
+    PSclInputModeConfigure cur = m_input_mode_configure_table;
+
+    for (int i = 0; i < m_inputmode_size; ++i) {
+        //name
+        m_storage.get_str(&(cur->name), record_width.name, m_string_collector);
+        //layout_portrait
+        m_storage.get_str(&(cur->layouts[0]), record_width.layout_portrait, m_string_collector);
+        //layout_landscape
+        m_storage.get_str(&(cur->layouts[1]), record_width.layout_landscape, m_string_collector);
+        //use_virtual_window
+        cur->use_virtual_window = m_storage.get<sint_t>(record_width.use_virtual_window);
+        //use_dim_window
+        cur->use_dim_window = m_storage.get<sint_t>(record_width.use_dim_window);
+
+        cur->timeout = m_storage.get<sint_t>(record_width.timeout);
+
+        cur++;
+    }
+
+#ifdef __SCL_TXT_DEBUG
+    put_input_mode_configure_table(DECODE, m_input_mode_configure_table);
+#endif
+}
+
+PSclInputModeConfigure
+BinInputModeConfigParser::get_input_mode_configure_table() {
+    return m_input_mode_configure_table;
+}
+
diff --git a/scl/input_mode_configure_bin_parser.h b/scl/input_mode_configure_bin_parser.h
new file mode 100644 (file)
index 0000000..1c49988
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012 - 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 __INPUT_MODE_BIN_PARSER__H__
+#define __INPUT_MODE_BIN_PARSER__H__
+#include <libxml/parser.h>
+#include "sclres_type.h"
+#include "iparserinfo_provider.h"
+#include <vector>
+#include "file_storage_impl.h"
+#include "string_collector.h"
+#include "_auto_metadata.h"
+
+class BinInputModeConfigParser {
+    public:
+        ~BinInputModeConfigParser();
+        static BinInputModeConfigParser *get_instance();
+        void init(const FileStorage&, int, int, IParserInfo_Provider* provider);
+        PSclInputModeConfigure get_input_mode_configure_table();
+        int get_inputmode_id(const char *name);
+        const char* get_inputmode_name(int id);
+        int get_inputmode_size();
+
+        void decode_string(FileStorage &storage, char** p, int width);
+    private:
+        BinInputModeConfigParser();
+        void parsing_input_mode_configure_table();
+        void set_input_mode_configure_default_record(const PSclInputModeConfigure);
+
+        StringCollector m_string_collector;
+    private:
+        int m_inputmode_size;
+        SclInputModeConfigure m_input_mode_configure_table[MAX_SCL_INPUT_MODE];
+
+        FileStorage m_storage;
+        IParserInfo_Provider* parser_info_provider;
+};
+
+#endif
diff --git a/scl/input_mode_configure_parser.cpp b/scl/input_mode_configure_parser.cpp
new file mode 100644 (file)
index 0000000..19014c0
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2012 - 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 <string.h>
+#include <libxml/parser.h>
+
+#include "input_mode_configure_parser.h"
+#include "xml_parser_utils.h"
+#include "simple_debug.h"
+
+/** Example of input mode XML file :
+ * <?xml version="1.0"?>
+ * <input_mode_table>
+ *   <mode name="ENGLISH_QTY">
+ *       <keyset>PORTRAIT_QTY_DEFAULT</keyset>
+ *       <keyset>LANDSCAPE_QTY_DEFAULT</keyset>
+ *   </mode>
+ *   <mode name="PUNCTUATION_POPUP" dim_window="true">
+ *       <keyset>PORTRAIT_PUNCTUATION_POPUP</keyset>
+ *       <keyset>LANDSCAPE_PUNCTUATION_POPUP</keyset>
+ *   </mode>
+ * </input_mode_table>
+ */
+
+#define INPUT_MODE_CONFIGURE_TABLE_TAG "input_mode_table"
+
+#define INPUT_MODE_CONFIGURE_MODE_TAG "mode"
+#define INPUT_MODE_CONFIGURE_MODE_NAME_ATTRIBUTE "name"
+#define INPUT_MODE_CONFIGURE_MODE_DIM_WINDOW_ATTRIBUTE "dim_window"
+#define INPUT_MODE_CONFIGURE_MODE_VIRTUAL_WINDOW_ATTRIBUTE "virtual_window"
+
+#define INPUT_MODE_CONFIGURE_LAYOUT_TAG "layouts"
+#define INPUT_MODE_CONFIGURE_LAYOUT_PORTRAIT_TAG "portrait"
+#define INPUT_MODE_CONFIGURE_LAYOUT_LANDSCAPE_TAG "landscape"
+
+class InputModeConfigureParserImpl {
+    public:
+        InputModeConfigureParserImpl() {
+            m_inputmode_size = 0;
+            memset(m_input_mode_configure_table, 0x00, sizeof(SclInputModeConfigure) * MAX_SCL_INPUT_MODE);
+        }
+
+        ~InputModeConfigureParserImpl() {
+            reset();
+        }
+
+        void reset() {
+            for (int input_mode = 0; input_mode < MAX_SCL_INPUT_MODE; ++input_mode) {
+                SclInputModeConfigure& cur_rec = m_input_mode_configure_table[input_mode];
+                if (cur_rec.name) {
+                    xmlFree(cur_rec.name);
+                    cur_rec.name = NULL;
+                }
+                if (cur_rec.layouts[DISPLAYMODE_PORTRAIT]) {
+                    xmlFree(cur_rec.layouts[DISPLAYMODE_PORTRAIT]);
+                    cur_rec.layouts[DISPLAYMODE_PORTRAIT] = NULL;
+                }
+                if (cur_rec.layouts[DISPLAYMODE_LANDSCAPE]) {
+                    xmlFree(cur_rec.layouts[DISPLAYMODE_LANDSCAPE]);
+                    cur_rec.layouts[DISPLAYMODE_LANDSCAPE] = NULL;
+                }
+            }
+            m_inputmode_size = 0;
+            memset(m_input_mode_configure_table, 0x00, sizeof(SclInputModeConfigure) * MAX_SCL_INPUT_MODE);
+        }
+
+        int reload_input_mode_configure_table(const char* input_file) {
+            reset();
+            return parsing_input_mode_configure_table(input_file);
+        }
+        int parsing_input_mode_configure_table(const char* input_file) {
+            xmlDocPtr doc;
+            xmlNodePtr cur_node;
+
+
+            doc = xmlReadFile(input_file, NULL, 0);
+            if (doc == NULL) {
+                SCLLOG(SclLog::DEBUG, "Could not load file: %s.", input_file);
+                return -1;
+            }
+
+            cur_node = xmlDocGetRootElement(doc);
+            if (cur_node == NULL) {
+                SCLLOG(SclLog::DEBUG, "InputModeConfigParser: empty document.\n");
+                xmlFreeDoc(doc);
+                return -1;
+            }
+            if (0 != xmlStrcmp(cur_node->name, (const xmlChar*)INPUT_MODE_CONFIGURE_TABLE_TAG))
+            {
+                SCLLOG(SclLog::DEBUG, "InputModeConfigParser: root name error: %s\n!", (char *)cur_node->name);
+                xmlFreeDoc(doc);
+                return -1;
+            }
+
+            m_inputmode_size = 0;
+            cur_node = cur_node->xmlChildrenNode;
+
+            SclInputModeConfigure* cur_rec = m_input_mode_configure_table;
+            while (cur_node != NULL) {
+                if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)INPUT_MODE_CONFIGURE_MODE_TAG)) {
+                    parsing_mode_node(cur_node, cur_rec);
+                    m_inputmode_size++;
+                    cur_rec++;
+                    if (m_inputmode_size >= MAX_SCL_INPUT_MODE) {
+                        SCLLOG(SclLog::ERROR, "No Space for input mode record.");
+                        break;
+                    }
+                }
+                cur_node = cur_node->next;
+            }
+            xmlFreeDoc(doc);
+
+            return 0;
+        }
+
+        void set_input_mode_configure_default_record(const PSclInputModeConfigure cur_rec) {
+            cur_rec->name = NULL;
+            cur_rec->layouts[DISPLAYMODE_PORTRAIT] = NULL;
+            cur_rec->layouts[DISPLAYMODE_LANDSCAPE] = NULL;
+            cur_rec->use_virtual_window = FALSE;
+            cur_rec->use_dim_window = FALSE;
+        }
+
+        void parsing_mode_node(const xmlNodePtr cur_node, const PSclInputModeConfigure cur_rec) {
+            assert(cur_node != NULL);
+            assert(cur_rec != NULL);
+            set_input_mode_configure_default_record(cur_rec);
+
+            get_prop_bool(cur_node, INPUT_MODE_CONFIGURE_MODE_VIRTUAL_WINDOW_ATTRIBUTE, &(cur_rec->use_virtual_window));
+            get_prop_bool(cur_node, INPUT_MODE_CONFIGURE_MODE_DIM_WINDOW_ATTRIBUTE, &(cur_rec->use_dim_window));
+
+            xmlChar* temp = xmlGetProp(cur_node, (const xmlChar*)INPUT_MODE_CONFIGURE_MODE_NAME_ATTRIBUTE);
+            cur_rec->name = (sclchar *)temp;
+
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"text")) {
+                    child_node = child_node->next;
+                    continue;
+                }
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar *)INPUT_MODE_CONFIGURE_LAYOUT_TAG)) {
+                    parsing_layouts(child_node, cur_rec);
+                } else {
+                    SCLLOG(SclLog::WARNING, "input_mode_configure has no such node name: %s\n", (char *)child_node->name);
+                }
+
+                child_node = child_node->next;
+            }
+        }
+
+        void parsing_layouts(const xmlNodePtr cur_node, const PSclInputModeConfigure cur_rec) {
+            assert(cur_node != NULL);
+            assert(cur_rec != NULL);
+            assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)INPUT_MODE_CONFIGURE_LAYOUT_TAG) );
+
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+            while (child_node != NULL) {
+                if ( 0 == xmlStrcmp(child_node->name, (const xmlChar *)INPUT_MODE_CONFIGURE_LAYOUT_PORTRAIT_TAG) ) {
+                    xmlChar* temp = xmlNodeGetContent(child_node);
+                    cur_rec->layouts[DISPLAYMODE_PORTRAIT] = (sclchar*)temp;
+                } else if ( 0 == xmlStrcmp(child_node->name, (const xmlChar *)INPUT_MODE_CONFIGURE_LAYOUT_LANDSCAPE_TAG) ) {
+                    xmlChar* temp = xmlNodeGetContent(child_node);
+                    cur_rec->layouts[DISPLAYMODE_LANDSCAPE] = (sclchar*)temp;
+                }
+                child_node = child_node->next;
+            }
+        }
+
+        int m_inputmode_size;
+        SclInputModeConfigure m_input_mode_configure_table[MAX_SCL_INPUT_MODE];
+};
+
+InputModeConfigParser::InputModeConfigParser() {
+    m_impl = new InputModeConfigureParserImpl;
+}
+
+InputModeConfigParser::~InputModeConfigParser() {
+    if (m_impl) {
+        SCLLOG(SclLog::MESSAGE, "~InputModeConfigParser() has called");
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+
+InputModeConfigParser*
+InputModeConfigParser::get_instance() {
+    static InputModeConfigParser instance;
+    return &instance;
+}
+
+int
+InputModeConfigParser::init(const char* file) {
+    return m_impl->parsing_input_mode_configure_table(file);
+}
+
+int
+InputModeConfigParser::reload(const char* file) {
+    return m_impl->reload_input_mode_configure_table(file);
+}
+
+int
+InputModeConfigParser::get_inputmode_id(const char *name) {
+    if (name == NULL) {
+        SCLLOG(SclLog::DEBUG, "get_inputmode_id failed");
+        return -1;
+    }
+
+    PSclInputModeConfigure config_table = get_input_mode_configure_table();
+
+    if (config_table == NULL) {
+        SCLLOG(SclLog::DEBUG, "get_inputmode_id failed");
+        return -1;
+    }
+
+    for (int i = 0; i < get_inputmode_size(); ++i) {
+        if (config_table[i].name) {
+            if ( 0 == strcmp(config_table[i].name, name) ) {
+                return i;
+            }
+        }
+    }
+
+    SCLLOG(SclLog::DEBUG, "get_inputmode_id failed");
+    return -1;
+}
+
+const char*
+InputModeConfigParser::get_inputmode_name(int id) {
+    if (id >= 0 && id < MAX_SCL_INPUT_MODE) {
+        PSclInputModeConfigure config_table = get_input_mode_configure_table();
+        if (config_table) {
+            return config_table[id].name;
+        }
+    }
+
+    return NULL;
+}
+
+int
+InputModeConfigParser::get_inputmode_size() {
+    return m_impl->m_inputmode_size;
+}
+
+PSclInputModeConfigure
+InputModeConfigParser::get_input_mode_configure_table() {
+    return m_impl->m_input_mode_configure_table;
+}
+
diff --git a/scl/input_mode_configure_parser.h b/scl/input_mode_configure_parser.h
new file mode 100644 (file)
index 0000000..ad30dec
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 - 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 __INPUT_MODE_PARSER__H__
+#define __INPUT_MODE_PARSER__H__
+#include "sclres_type.h"
+
+class InputModeConfigureParserImpl;
+
+class InputModeConfigParser {
+    InputModeConfigureParserImpl *m_impl;
+    public:
+        int init(const char* file);
+        int reload(const char* file);
+        PSclInputModeConfigure get_input_mode_configure_table();
+        int get_inputmode_id(const char *name);
+        const char* get_inputmode_name(int id);
+        int get_inputmode_size();
+    public:
+        ~InputModeConfigParser();
+        static InputModeConfigParser *get_instance();
+    private:
+        InputModeConfigParser();
+};
+#endif
diff --git a/scl/iparserinfo_provider.h b/scl/iparserinfo_provider.h
new file mode 100644 (file)
index 0000000..acabba2
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012 - 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 __IPARSERINFO_PROVIDER_H__
+#define __IPARSERINFO_PROVIDER_H__
+#include <string>
+
+/***
+* 1. How to get field width, take "input mode configure" for example
+    1) set_current_metadata_record("input_mode_configure")
+    2) get_width("name");
+  2. How to get a string
+    1) parsing the binary file to get the string_id
+    2) use get_string_by_id(string_id);
+*/
+#include "istring_provider.h"
+class IParserInfo_Provider: public IString_Provider{
+    public:
+        virtual void set_current_metadata_record(const char* record_name) = 0;
+        virtual int get_width(const char* field_name) const = 0;
+        virtual const char* get_string_by_id(const int id) const = 0;
+        virtual ~IParserInfo_Provider() {}
+};
+#endif
diff --git a/scl/istring_collector.h b/scl/istring_collector.h
new file mode 100644 (file)
index 0000000..7c3ae39
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 - 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 __INTERFACE_STRING_COLLECTOR_H__
+#define __INTERFACE_STRING_COLLECTOR_H__
+
+/*Use this interface to collect all the new strings*/
+class IStringCollector{
+    public:
+        virtual void add(char* str) = 0;
+        virtual ~IStringCollector() {}
+};
+#endif
diff --git a/scl/istring_provider.h b/scl/istring_provider.h
new file mode 100644 (file)
index 0000000..f1ebae1
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 - 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 __ISTRING_PROVIDER_H__
+#define __ISTRING_PROVIDER_H__
+#include <string>
+
+class IString_Provider{
+    public:
+        virtual const char* get_string_by_id(const int id)const = 0;
+        virtual ~IString_Provider() {}
+};
+#endif
diff --git a/scl/key_coordinate_frame_bin_parser.cpp b/scl/key_coordinate_frame_bin_parser.cpp
new file mode 100644 (file)
index 0000000..f4d6f9e
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2012 - 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 "key_coordinate_frame_bin_parser.h"
+#include "sclutils.h"
+
+#include "string_bin_parser.h"
+#include "metadata_bin_parser.h"
+#include "parserinfo_provider.h"
+#include "string_provider.h"
+#include "metadata_provider.h"
+#include <algorithm>
+#include "put_record.h"
+#include <malloc.h>
+#include "binary_xmlresource.h"
+#include "simple_debug.h"
+using namespace binary_xmlresource;
+
+using namespace std;
+using namespace scl;
+
+BinKeyCoordFrameParser::BinKeyCoordFrameParser() {
+    memset(m_key_coordinate_pointer_frame, 0x00, sizeof(SclLayoutKeyCoordinatePointer) * MAX_SCL_LAYOUT * MAX_KEY);
+    parser_info_provider = NULL;
+}
+BinKeyCoordFrameParser::~BinKeyCoordFrameParser() {
+    for (int i = 0; i < MAX_SCL_LAYOUT; ++i) {
+        for (int j = 0; j < MAX_KEY; ++j) {
+            free(m_key_coordinate_pointer_frame[i][j]);
+            m_key_coordinate_pointer_frame[i][j] = NULL;
+        }
+    }
+}
+BinKeyCoordFrameParser* BinKeyCoordFrameParser::get_instance() {
+    static BinKeyCoordFrameParser instance;
+    return &instance;
+}
+
+void
+BinKeyCoordFrameParser::
+load(int layout_id)
+{
+    BinResource *bin_xmlres = BinResource::get_instance();
+
+    char path[_POSIX_PATH_MAX] = {0};
+
+    snprintf(path, _POSIX_PATH_MAX, "%s/%s", bin_xmlres->get_resource_directory(), "sclresource.bin");
+
+    FileStorage storage;
+    FileStorage alldata;
+    alldata.loadFile(path);
+
+    String_Bin_Parser stringBinParser(alldata, bin_xmlres->m_info[STRING].offset, bin_xmlres->m_info[STRING].size);
+    Metadata_Bin_Parser metadataBinParser(alldata, bin_xmlres->m_info[METADATA].offset, bin_xmlres->m_info[METADATA].size);
+
+    String_Provider stringProvider(&stringBinParser);
+    Metadata_Provider metadataProvider(&metadataBinParser);
+    ParserInfo_Provider provider(&metadataProvider, &stringProvider);
+    storage.set_str_provider(&provider);
+    this->parser_info_provider = &provider;
+    storage.get_storage(
+        alldata,
+        bin_xmlres->m_info[KEY_COORDINATE_FRAME].offset,
+        bin_xmlres->m_info[KEY_COORDINATE_FRAME].size);
+
+    // 4 byte (range[0-4,294,967,295))
+    const int DATA_SIZE_BYTES = 4;
+    // 1 byte (range[0-128))
+    const int REC_NUM_BYTES = 1;
+    const int KEY_NUM_BYTES = 1;
+    // 2 byte (range[0-65536))
+    const int KEY_COORDIANTE_REC_DATA_SIZE_BYTES = 2;
+
+    // skip data_size
+    storage.advance(DATA_SIZE_BYTES);
+
+    // rec_num
+    int layout_num = storage.get<uint_t>(REC_NUM_BYTES);
+    int *pKey_num_array = new int[layout_num];
+    memset(pKey_num_array, 0x00, layout_num * sizeof(int));
+    for (int i = 0; i < layout_num; ++i) {
+        pKey_num_array[i] = storage.get<uint_t>(KEY_NUM_BYTES);
+    }
+
+    // key_coordinate_rec_data_size
+    int key_coordinate_rec_data_size = storage.get<uint_t>(KEY_COORDIANTE_REC_DATA_SIZE_BYTES);
+    Key_coordinate_record_width record_width;
+    set_key_coordinate_record_width(parser_info_provider, record_width);
+
+    for (int i = 0; i < layout_num; ++i) {
+        if (layout_id == i) {
+            for (int j = 0; j < pKey_num_array[i]; ++j) {
+                SclLayoutKeyCoordinatePointer curPointer = (SclLayoutKeyCoordinatePointer)malloc(sizeof(SclLayoutKeyCoordinate));
+                if (curPointer == NULL) {
+                    SCLLOG(SclLog::ERROR, "Memory malloc error.\n");
+                    assert(0);
+                }
+                memset(curPointer, 0x00, sizeof(SclLayoutKeyCoordinate));
+                decode_key_coordinate_record(storage, curPointer, record_width);
+                m_key_coordinate_pointer_frame[i][j] = curPointer;
+            }
+            break;
+        } else {
+            storage.advance(pKey_num_array[i] * key_coordinate_rec_data_size);
+        }
+    }
+
+    delete []pKey_num_array;
+}
+
+bool
+BinKeyCoordFrameParser::
+loaded(int layout_id)
+{
+    bool ret = TRUE;
+    if (layout_id >= 0 && layout_id < MAX_SCL_LAYOUT) {
+        if (m_key_coordinate_pointer_frame[layout_id][0] == NULL) {
+            ret = FALSE;
+        }
+    }
+    return ret;
+}
+
+void
+BinKeyCoordFrameParser::
+unload()
+{
+    for (int i = 0; i < MAX_SCL_LAYOUT; ++i) {
+        for (int j = 0; j < MAX_KEY; ++j) {
+            free(m_key_coordinate_pointer_frame[i][j]);
+            m_key_coordinate_pointer_frame[i][j] = NULL;
+        }
+    }
+}
+void
+BinKeyCoordFrameParser::init(const FileStorage& storage, int offset, int size, IParserInfo_Provider* provider) {
+    m_storage.set_str_provider(parser_info_provider);
+    m_storage.get_storage(storage, offset, size);
+    this->parser_info_provider = provider;
+}
+
+PSclLayoutKeyCoordinatePointerTable
+BinKeyCoordFrameParser::get_key_coordinate_pointer_frame() {
+    return m_key_coordinate_pointer_frame;
+}
+
+void
+BinKeyCoordFrameParser::decode_key_coordinate_record(FileStorage& storage, const PSclLayoutKeyCoordinate cur, const Key_coordinate_record_width& record_width) {
+    cur->valid = (sclboolean)true;
+    //x
+    cur->x = storage.get<sint_t>(record_width.x);
+    //y
+    cur->y = storage.get<sint_t>(record_width.y);
+
+    //width
+    cur->width = storage.get<sint_t>(record_width.width);
+    //height
+    cur->height = storage.get<sint_t>(record_width.height);
+
+    //add_hit_left
+    cur->add_hit_left = storage.get<sint_t>(record_width.add_hit_left);
+    //add_hit_right
+    cur->add_hit_right = storage.get<sint_t>(record_width.add_hit_right);
+    //add_hit_top
+    cur->add_hit_top = storage.get<sint_t>(record_width.add_hit_top);
+    //add_hit_bottom
+    cur->add_hit_bottom = storage.get<sint_t>(record_width.add_hit_bottom);
+    //popup_relative_x
+    cur->popup_relative_x = storage.get<sint_t>(record_width.popup_relative_x);
+    //popup_relative_y
+    cur->popup_relative_y = storage.get<sint_t>(record_width.popup_relative_y);
+    //extract_offset_x
+    cur->extract_offset_x = storage.get<sint_t>(record_width.extract_offset_x);
+    //extract_offset_y
+    cur->extract_offset_y = storage.get<sint_t>(record_width.extract_offset_y);
+
+    storage.get_str(&(cur->sub_layout), record_width.sub_layout, m_string_collector);
+
+    //magnifier_offset_x
+    cur->magnifier_offset_x = storage.get<sint_t>(record_width.magnifier_offset_x);
+    //magnifier_offset_y
+    cur->magnifier_offset_y = storage.get<sint_t>(record_width.magnifier_offset_y);
+
+    storage.get_str(&(cur->custom_id), record_width.custom_id, m_string_collector);
+
+    //button_type
+    cur->button_type = (SCLButtonType)storage.get<sint_t>(record_width.button_type);
+    //key_type
+    cur->key_type = (SCLKeyType)storage.get<sint_t>(record_width.key_type);
+    //popup_type
+    cur->popup_type = (SCLPopupType)storage.get<sint_t>(record_width.popup_type);
+
+    cur->use_magnifier = storage.get<sint_t>(record_width.use_magnifier);
+    cur->use_long_key_magnifier = storage.get<sint_t>(record_width.use_long_key_magnifier);
+
+    //popup_input_mode
+    for (int i = 0; i < SCL_DRAG_STATE_MAX; ++i) {
+        storage.get_str(&(cur->popup_input_mode[i]), record_width.popup_input_mode, m_string_collector);
+    }
+
+    storage.get_str(&(cur->sound_style), record_width.sound_style, m_string_collector);
+    storage.get_str(&(cur->vibe_style), record_width.vibe_style, m_string_collector);
+    cur->is_side_button = storage.get<sint_t>(record_width.is_side_button);
+
+    //label_count
+    cur->label_count = storage.get<sint_t>(record_width.label_count);
+
+    //label
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_LABEL_FOR_ONE; ++j) {
+            storage.get_str(&(cur->label[i][j]), record_width.label, m_string_collector);
+        }
+    }
+
+    storage.get_str(&(cur->label_type), record_width.label_type, m_string_collector);
+
+    //label_image_path
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            storage.get_str(&(cur->image_label_path[i][j]), record_width.image_label_path, m_string_collector);
+        }
+    }
+
+    storage.get_str(&(cur->image_label_type), record_width.image_label_type, m_string_collector);
+
+    //bg_image_path
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            storage.get_str(&(cur->bg_image_path[i][j]), record_width.bg_image_path, m_string_collector);
+        }
+    }
+
+    //key_value_count
+    cur->key_value_count = storage.get<sint_t>(record_width.key_value_count);
+
+    //key_value
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_MULTITAP_CHAR; ++j) {
+            storage.get_str(&(cur->key_value[i][j]), record_width.key_value, m_string_collector);
+        }
+    }
+    //key_event
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_LABEL_FOR_ONE; ++j) {
+            cur->key_event[i][j] = storage.get<sint_t>(record_width.key_event);
+        }
+    }
+
+    //long_key_type
+    cur->long_key_type = (SCLKeyType)storage.get<sint_t>(record_width.long_key_type);
+
+    //long_key_value
+    storage.get_str(&(cur->long_key_value), record_width.long_key_value, m_string_collector);
+
+    //long_key_event
+    cur->long_key_event = storage.get<sint_t>(record_width.long_key_event);
+
+    cur->use_repeat_key = storage.get<sint_t>(record_width.use_repeat_key);
+
+    //autopopup_keys
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_AUTOPOPUP_STRING; ++j) {
+            storage.get_str(&(cur->autopopup_key_labels[i][j]), record_width.autopopup_key_labels, m_string_collector);
+            storage.get_str(&(cur->autopopup_key_values[i][j]), record_width.autopopup_key_values, m_string_collector);
+            cur->autopopup_key_events[i][j] = storage.get<sint_t>(record_width.autopopup_key_events);
+        }
+    }
+
+    cur->dont_close_popup = storage.get<sint_t>(record_width.dont_close_popup);
+
+    //extra_option
+    cur->extra_option = storage.get<sint_t>(record_width.extra_option);
+
+    //multitouch_type
+    cur->multitouch_type = storage.get<sint_t>(record_width.multitouch_type);
+
+    // modifier_decorator
+    storage.get_str(&(cur->modifier_decorator), record_width.modifier_decorator, m_string_collector);
+
+    //magnifier_label
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_LABEL_FOR_ONE; ++j) {
+            storage.get_str(&(cur->magnifier_label[i][j]), record_width.magnifier_label, m_string_collector);
+        }
+    }
+
+    // hint_string
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_MULTITAP_CHAR; ++j) {
+            storage.get_str(&(cur->hint_string[i][j]), record_width.hint_string, m_string_collector);
+        }
+    }
+}
+
diff --git a/scl/key_coordinate_frame_bin_parser.h b/scl/key_coordinate_frame_bin_parser.h
new file mode 100644 (file)
index 0000000..2204995
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 - 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 __KEY_COORDINATE_FRAME_BIN_PARSER__H__
+#define __KEY_COORDINATE_FRAME_BIN_PARSER__H__
+#include "sclres_type.h"
+#include "iparserinfo_provider.h"
+#include <vector>
+#include "string_collector.h"
+#include "file_storage_impl.h"
+#include "_auto_metadata.h"
+class BinKeyCoordFrameParser {
+    public:
+        static BinKeyCoordFrameParser *get_instance();
+    void init(const FileStorage& storage, int, int, IParserInfo_Provider*);
+    ~BinKeyCoordFrameParser();
+
+    PSclLayoutKeyCoordinatePointerTable get_key_coordinate_pointer_frame();
+    void load(int);
+    bool loaded(int);
+    void unload();
+    private:
+    BinKeyCoordFrameParser();
+    void parsing_key_coordinate_frame();
+    void decode_key_coordinate_record(FileStorage& storage, const PSclLayoutKeyCoordinate cur, const Key_coordinate_record_width&);
+
+    private:
+        SclLayoutKeyCoordinate* m_key_coordinate_pointer_frame[MAX_SCL_LAYOUT][MAX_KEY];
+
+        IParserInfo_Provider *parser_info_provider;
+        StringCollector m_string_collector;
+        FileStorage m_storage;
+};
+
+
+#endif
diff --git a/scl/label_properties_bin_parser.cpp b/scl/label_properties_bin_parser.cpp
new file mode 100644 (file)
index 0000000..9db7bb0
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2012 - 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 "label_properties_bin_parser.h"
+#include "simple_debug.h"
+#include "put_record.h"
+
+BinLabelPropertyParser::BinLabelPropertyParser() {
+    m_size = 0;
+    memset(m_label_properties_frame, 0, sizeof(SclLabelProperties) * MAX_SCL_LABEL_PROPERTIES * MAX_SIZE_OF_LABEL_FOR_ONE);
+    parser_info_provider = NULL;
+}
+
+BinLabelPropertyParser::~BinLabelPropertyParser() {
+    m_size = 0;
+}
+
+BinLabelPropertyParser* BinLabelPropertyParser::get_instance() {
+    static BinLabelPropertyParser instance;
+    return &instance;
+}
+void BinLabelPropertyParser::init(const FileStorage& storage, int offset, int size, IParserInfo_Provider* provider) {
+    m_storage.set_str_provider(parser_info_provider);
+    m_storage.get_storage(storage, offset, size);
+    this->parser_info_provider = provider;
+    parsing_label_properties_frame();
+}
+int
+BinLabelPropertyParser::get_size() {
+    return m_size;
+}
+
+//recompute_layout will change the table
+PSclLabelPropertiesTable BinLabelPropertyParser::get_label_properties_frame() {
+    return m_label_properties_frame;
+}
+
+void BinLabelPropertyParser::parsing_label_properties_frame() {
+    // skip data_size
+    m_storage.advance(8);
+
+    m_size = m_storage.get<sint_t>(4);
+    int maxj = m_storage.get<sint_t>(4);
+
+    if (parser_info_provider == NULL) {
+        SCLLOG(SclLog::ERROR, "Error parser_info_provider is NULL\n");
+        return;
+    }
+
+    Label_properties_record_width record_width;
+    set_label_properties_record_width(*parser_info_provider, record_width);
+    for (int i = 0; i < m_size; ++i) {
+        for (int j = 0; j < maxj; ++j) {
+            SclLabelProperties &cur = m_label_properties_frame[i][j];
+            decode_label_properties_record(&cur, record_width);
+        }
+    }
+#ifdef __SCL_TXT_DEBUG
+    put_label_properties_frame(DECODE, m_label_properties_frame);
+#endif
+}
+
+void
+BinLabelPropertyParser::decode_color(SclColor& color, int width) {
+    if (width <= 0) return;
+
+    color.r = m_storage.get<sint_t>(width);
+    color.g = m_storage.get<sint_t>(width);
+    color.b = m_storage.get<sint_t>(width);
+    color.a = m_storage.get<sint_t>(width);
+}
+void
+BinLabelPropertyParser::decode_label_properties_record(const PSclLabelProperties cur, const Label_properties_record_width& record_width) {
+    cur->valid = (sclboolean)true;
+
+    //label_name
+    m_storage.get_str(&(cur->label_type), record_width.label_type, m_string_collector);
+    //font_name
+    m_storage.get_str(&(cur->font_name), record_width.font_name, m_string_collector);
+
+    //font_size
+    cur->font_size = m_storage.get<sint_t>(record_width.font_size);
+    //font color
+        for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+            for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+                decode_color(cur->font_color[i][j], record_width.font_color);
+            }
+        }
+
+    //alignment
+    cur->alignment = (SCLLabelAlignment)m_storage.get<sint_t>(record_width.alignment);
+
+    //padding_x
+    cur->padding_x = m_storage.get<sint_t>(record_width.padding_x);
+
+    //padding_y
+    cur->padding_y = m_storage.get<sint_t>(record_width.padding_y);
+
+    //inner_width
+    cur->inner_width = m_storage.get<sint_t>(record_width.inner_width);
+
+    //inner_height
+    cur->inner_height = m_storage.get<sint_t>(record_width.inner_height);
+
+    //shadow_distance
+    cur->shadow_distance = m_storage.get<sint_t>(record_width.shadow_distance);
+
+    //shadow_direction
+    cur->shadow_direction = (SCLShadowDirection)m_storage.get<sint_t>(record_width.shadow_direction);
+
+    //shadow_color
+        for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+            for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+                decode_color(cur->shadow_color[i][j], record_width.shadow_color);
+            }
+        }
+}
diff --git a/scl/label_properties_bin_parser.h b/scl/label_properties_bin_parser.h
new file mode 100644 (file)
index 0000000..694d268
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012 - 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 __BinLabelPropertyParser__H__
+#define __BinLabelPropertyParser__H__
+#include "sclres_type.h"
+#include "iparserinfo_provider.h"
+#include <vector>
+#include "string_collector.h"
+#include "file_storage_impl.h"
+#include "_auto_metadata.h"
+
+class BinLabelPropertyParser {
+    public:
+        ~BinLabelPropertyParser();
+        static BinLabelPropertyParser *get_instance();
+    void init(const FileStorage& storage, int, int, IParserInfo_Provider*);
+    PSclLabelPropertiesTable get_label_properties_frame();
+    int get_size();
+
+    private:
+    BinLabelPropertyParser();
+    void parsing_label_properties_frame();
+    void decode_label_properties_record(const PSclLabelProperties cur, const Label_properties_record_width&);
+
+    void decode_color(SclColor& color, int width);
+
+    private:
+        SclLabelProperties m_label_properties_frame[MAX_SCL_LABEL_PROPERTIES][MAX_SIZE_OF_LABEL_FOR_ONE];
+        int m_size;
+        IParserInfo_Provider *parser_info_provider;
+        FileStorage m_storage;
+        StringCollector m_string_collector;
+};
+
+
+#endif
diff --git a/scl/label_properties_parser.cpp b/scl/label_properties_parser.cpp
new file mode 100644 (file)
index 0000000..e2c28c6
--- /dev/null
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2012 - 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 <memory.h>
+#include <sstream>
+#include <libxml/parser.h>
+#include "label_properties_parser.h"
+#include "xml_parser_utils.h"
+#include "simple_debug.h"
+#include "put_record.h"
+
+using namespace std;
+
+static int
+match_alignment(const char* key) {
+  assert(key != NULL);
+
+    typedef struct _match_table_t {
+        int value;
+        const char* key;
+    }Match_table_t;
+  static Match_table_t table[] = {
+        {LABEL_ALIGN_LEFT_TOP,          "left_top"      },
+        {LABEL_ALIGN_CENTER_TOP,        "center_top"    },
+        {LABEL_ALIGN_RIGHT_TOP,         "right_top"     },
+
+        {LABEL_ALIGN_LEFT_MIDDLE,       "left_middle"   },
+        {LABEL_ALIGN_CENTER_MIDDLE,     "center_middle" },
+        {LABEL_ALIGN_RIGHT_MIDDLE,      "right_middle"  },
+
+        {LABEL_ALIGN_LEFT_BOTTOM,       "left_bottom"   },
+        {LABEL_ALIGN_CENTER_BOTTOM,     "center_bottom" },
+        {LABEL_ALIGN_RIGHT_BOTTOM,      "right_bottom"  }
+    };
+
+    int value = LABEL_ALIGN_LEFT_TOP;
+
+    for (size_t i = 0; i < sizeof(table)/sizeof(Match_table_t); ++i) {
+        if (0 == strcmp(key, table[i].key))
+        {
+            value = table[i].value;
+            break;
+        }
+    }
+    return value;
+}
+static int
+match_shadow_direction(const char* key) {
+  assert(key != NULL);
+
+    typedef struct _match_table_t {
+        int value;
+        const char* key;
+    }Match_table_t;
+  static Match_table_t table[] = {
+        {SHADOW_DIRECTION_NONE,             "shadow_direction_none"},
+
+        {SHADOW_DIRECTION_LEFT_TOP,         "shadow_direction_left_top"},
+        {SHADOW_DIRECTION_CENTER_TOP,       "shadow_direction_center_top"},
+        {SHADOW_DIRECTION_RIGHT_TOP,        "shadow_direction_right_top"},
+
+        {SHADOW_DIRECTION_LEFT_MIDDLE,      "shadow_direction_left_middle"},
+        {SHADOW_DIRECTION_CENTER_MIDDLE,    "shadow_direction_center_middle"},
+        {SHADOW_DIRECTION_RIGHT_MIDDLE,     "shadow_direction_right_middle"},
+
+        {SHADOW_DIRECTION_LEFT_BOTTOM,     "shadow_direction_left_bottom"},
+        {SHADOW_DIRECTION_CENTER_BOTTOM,     "shadow_direction_center_bottom"},
+        {SHADOW_DIRECTION_RIGHT_BOTTOM,     "shadow_direction_right_bottom"}
+    };
+
+    int value = SHADOW_DIRECTION_NONE;
+
+    for (size_t i = 0; i < sizeof(table)/sizeof(Match_table_t); ++i) {
+        if (0 == strcmp(key, table[i].key))
+        {
+            value = table[i].value;
+            break;
+        }
+    }
+    return value;
+}
+class LabelPropertiesParserImpl {
+    public:
+        LabelPropertiesParserImpl() {
+            m_size = 0;
+            memset(m_label_properties_frame, 0, sizeof(SclLabelProperties) * MAX_SCL_LABEL_PROPERTIES * MAX_SIZE_OF_LABEL_FOR_ONE);
+        }
+
+        ~LabelPropertiesParserImpl() {
+            reset();
+        }
+
+        void reset()
+        {
+            for (int i = 0; i < MAX_SCL_LABEL_PROPERTIES && i < m_size; ++i) {
+                for (int j = 0; j < MAX_SIZE_OF_LABEL_FOR_ONE; ++j) {
+                    if (m_label_properties_frame[i][j].font_name)
+                        xmlFree(m_label_properties_frame[i][j].font_name);
+                    m_label_properties_frame[i][j].font_name = NULL;
+                    if (m_label_properties_frame[i][j].label_type)
+                        xmlFree(m_label_properties_frame[i][j].label_type);
+                    m_label_properties_frame[i][j].label_type = NULL;
+                }
+            }
+            m_size = 0;
+            memset(m_label_properties_frame, 0, sizeof(SclLabelProperties) * MAX_SCL_LABEL_PROPERTIES * MAX_SIZE_OF_LABEL_FOR_ONE);
+        }
+
+        int reload_label_properties_frame(const char* input_file) {
+            reset();
+            return parsing_label_properties_frame(input_file);
+        }
+
+        int parsing_label_properties_frame(const char* input_file) {
+            xmlDocPtr doc;
+            xmlNodePtr cur_node;
+
+            doc = xmlReadFile(input_file, NULL, 0);
+            if (doc == NULL) {
+                SCLLOG(SclLog::DEBUG, "Could not load file: %s.", input_file);
+                return -1;
+            }
+
+            cur_node = xmlDocGetRootElement(doc);
+            if (cur_node == NULL) {
+                SCLLOG(SclLog::DEBUG, "Label_Properties_Parser: empty document.\n");
+                xmlFreeDoc(doc);
+                return -1;
+            }
+            if (0 != xmlStrcmp(cur_node->name, (const xmlChar*)"label_properties_frame"))
+            {
+                SCLLOG(SclLog::DEBUG, "Label_Properties_Parser: root name error: %s\n!", (char *)cur_node->name);
+                xmlFreeDoc(doc);
+                return -1;
+            }
+
+            cur_node = cur_node->xmlChildrenNode;
+
+            assert(m_size == 0);
+            PSclLabelPropertiesTable curTable = m_label_properties_frame;
+            while (cur_node != NULL) {
+                if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"label_properties_table")) {
+                    parsing_label_properties_table(cur_node, curTable);
+                    xmlChar* key = xmlGetProp(cur_node, (const xmlChar*)"label_type");
+                    PSclLabelProperties cur_rec = (PSclLabelProperties)curTable;
+                    cur_rec->label_type = (sclchar *)key;
+                    m_size++;
+                    curTable++;
+                    if (m_size >= MAX_SCL_LABEL_PROPERTIES) {
+                        SCLLOG(SclLog::ERROR, "No Space for label properties record.");
+                        break;
+                    }
+                }
+
+                cur_node = cur_node->next;
+            }
+            xmlFreeDoc(doc);
+
+            return 0;
+        }
+        void parsing_label_properties_table(const xmlNodePtr cur_node, const PSclLabelPropertiesTable curTable) {
+            assert(cur_node != NULL);
+            assert(curTable != NULL);
+
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+            PSclLabelProperties cur_rec = (PSclLabelProperties)curTable;
+            while (NULL != child_node) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"label_properties")) {
+                    parsing_label_properties_record(child_node, cur_rec);
+                    cur_rec++;
+                }
+
+                child_node = child_node->next;
+            }
+        }
+        void parsing_label_properties_record(const xmlNodePtr cur_node, const PSclLabelProperties cur_rec) {
+            assert(cur_node != NULL);
+            assert(cur_rec != NULL);
+
+            set_label_properties_default_record(cur_rec);
+
+            xmlChar* key = xmlGetProp(cur_node, (const xmlChar*)"font_name");
+            if (NULL != key) {
+                cur_rec->font_name = (sclchar*)key;
+            }
+
+            get_prop_number(cur_node, "font_size", &(cur_rec->font_size));
+
+            key = xmlGetProp(cur_node, (const xmlChar*)"label_alignment");
+            if (NULL != key) {
+                cur_rec->alignment = (SCLLabelAlignment)match_alignment((const char*)key);
+                xmlFree(key);
+            }
+
+            get_prop_number(cur_node, "padding_X", &(cur_rec->padding_x));
+            get_prop_number(cur_node, "padding_Y", &(cur_rec->padding_y));
+            get_prop_number(cur_node, "inner_width", &(cur_rec->inner_width));
+            get_prop_number(cur_node, "inner_height", &(cur_rec->inner_height));
+
+            get_prop_number(cur_node, "shadow_distance", &(cur_rec->shadow_distance));
+            key = xmlGetProp(cur_node, (const xmlChar*)"shadow_direction");
+            if (NULL != key) {
+                cur_rec->shadow_direction = (SCLShadowDirection)match_shadow_direction((const char*)key);
+                xmlFree(key);
+            }
+
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"font_color_record")) {
+                    parsing_font_color_record(child_node, cur_rec);
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"shadow_color_record")) {
+                    parsing_shadow_color_record(child_node, cur_rec);
+                }
+
+                child_node = child_node->next;
+            }
+        }
+
+        void set_label_properties_default_record(const PSclLabelProperties cur_rec) {
+        cur_rec->valid = true;
+        cur_rec->font_name = NULL;
+        cur_rec->font_size = 0;
+        for (int shift_state = 0; shift_state < SCL_SHIFT_STATE_MAX; ++shift_state) {
+            for (int button_state = 0; button_state < SCL_BUTTON_STATE_MAX; ++button_state) {
+                cur_rec->font_color[shift_state][button_state].r = 0;
+                cur_rec->font_color[shift_state][button_state].g = 0;
+                cur_rec->font_color[shift_state][button_state].b = 0;
+            }
+        }
+
+        cur_rec->alignment = LABEL_ALIGN_LEFT_TOP;
+        cur_rec->padding_x = 0;
+        cur_rec->padding_y = 0;
+        cur_rec->inner_width = 0;
+        cur_rec->inner_height = 0;
+        cur_rec->shadow_distance = 0;
+
+        cur_rec->shadow_direction = SHADOW_DIRECTION_NONE;
+
+        for (int shift_state = 0; shift_state < SCL_SHIFT_STATE_MAX; ++shift_state) {
+            for (int button_state = 0; button_state < SCL_BUTTON_STATE_MAX; ++button_state) {
+                cur_rec->shadow_color[shift_state][button_state].r = 0;
+                cur_rec->shadow_color[shift_state][button_state].g = 0;
+                cur_rec->shadow_color[shift_state][button_state].b = 0;
+            }
+        }
+    }
+
+    void parsing_font_color_record(const xmlNodePtr cur_node, const PSclLabelProperties cur_rec) {
+        assert(cur_node != NULL);
+        assert(cur_rec != NULL);
+        assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"font_color_record"));
+        xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+        while (child_node != NULL) {
+            if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"color")) {
+                SclColor font_color = {0x00, 0x00, 0x00, 0xFF};
+                parsing_rgb(child_node, font_color);
+
+                int shift_state = get_shift_state_prop(child_node);
+                int button_state = get_button_state_prop(child_node);
+
+                for (int shift_loop = 0;shift_loop < SCL_SHIFT_STATE_MAX;shift_loop++) {
+                    for (int button_loop = 0;button_loop < SCL_BUTTON_STATE_MAX;button_loop++) {
+                        if ((shift_state == shift_loop || shift_state == -1) &&
+                                (button_state == button_loop || button_state == -1)) {
+                            cur_rec->font_color[shift_loop][button_loop] = font_color;
+                        }
+                    }
+                }
+            }
+            child_node = child_node->next;
+        }
+    }
+
+    void parsing_shadow_color_record(const xmlNodePtr cur_node, const PSclLabelProperties cur_rec) {
+        assert(cur_node != NULL);
+        assert(cur_rec != NULL);
+        assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"shadow_color_record"));
+        xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+        while (child_node != NULL) {
+            if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"color")) {
+                int shift_state = get_shift_state_prop(child_node);
+                int button_state = get_button_state_prop(child_node);
+                if (shift_state != -1 && button_state != -1) {
+                    parsing_rgb(child_node, cur_rec->shadow_color[shift_state][button_state]);
+                }
+            }
+            child_node = child_node->next;
+        }
+    }
+
+    void parsing_rgb(const xmlNodePtr cur_node, SclColor& cur_color) {
+        assert(cur_node != NULL);
+
+        assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"color"));
+        xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+        if (child_node) {
+            /* FIXME : A hardcoded routine for parsing 0xRRGGBBAA style string */
+            xmlChar* key = xmlNodeGetContent(child_node);
+            if (key) {
+                if (xmlStrlen(key) == 10) {
+                    int r, g, b, a;
+                    r = g = b = 0;
+                    a = 0xff;
+
+                    char temp_string[5] = {"0xFF"};
+
+                    temp_string[2] = key[2];
+                    temp_string[3] = key[3];
+                    stringstream convertor_r(temp_string);
+                    convertor_r >> hex >> r;
+                    if (convertor_r.fail() == true) {
+                        SCLLOG(SclLog::ERROR, "parsing_rgb() [r] has failed.");
+                        r = 0;
+                    }
+
+                    temp_string[2] = key[4];
+                    temp_string[3] = key[5];
+                    stringstream convertor_g(temp_string);
+                    convertor_g >> hex >> g;
+                    if (convertor_g.fail() == true) {
+                        SCLLOG(SclLog::ERROR, "parsing_rgb() [g] has failed.");
+                        g = 0;
+                    }
+
+                    temp_string[2] = key[6];
+                    temp_string[3] = key[7];
+                    stringstream convertor_b(temp_string);
+                    convertor_b >> hex >> b;
+                    if (convertor_b.fail() == true) {
+                        SCLLOG(SclLog::ERROR, "parsing_rgb() [b] has failed.");
+                        b = 0;
+                    }
+
+                    temp_string[2] = key[8];
+                    temp_string[3] = key[9];
+                    stringstream convertor_a(temp_string);
+                    convertor_a >> hex >> a;
+                    if (convertor_a.fail() == true) {
+                        SCLLOG(SclLog::ERROR, "parsing_rgb() [a] has failed.");
+                        a = 0;
+                    }
+
+                    cur_color.r = r;
+                    cur_color.g = g;
+                    cur_color.b = b;
+                    cur_color.a = a;
+                }
+            }
+            xmlFree(key);
+        }
+    }
+
+    int get_shift_state_prop(const xmlNodePtr cur_node) {
+        assert(cur_node != NULL);
+
+        int shift_state = -1;
+
+        if (equal_prop(cur_node, "shift", "on")) {
+            shift_state = SCL_SHIFT_STATE_ON;
+        } else if (equal_prop(cur_node, "shift", "off")) {
+            shift_state = SCL_SHIFT_STATE_OFF;
+
+        } else if (equal_prop(cur_node, "shift", "loc")) {
+            shift_state = SCL_SHIFT_STATE_LOCK;
+        }
+        return shift_state;
+    }
+
+    int get_button_state_prop(const xmlNodePtr cur_node) {
+        assert(cur_node != NULL);
+        int button_state = -1;
+
+        if (equal_prop(cur_node, "button", "pressed")) {
+            button_state = BUTTON_STATE_PRESSED;
+        } else if (equal_prop(cur_node, "button", "normal")) {
+            button_state = BUTTON_STATE_NORMAL;
+        } else if (equal_prop(cur_node, "button", "disabled")) {
+            button_state = BUTTON_STATE_DISABLED;
+        } else if (equal_prop(cur_node, "button", "toggled")) {
+            button_state = BUTTON_STATE_TOGGLED;
+        }
+        return button_state;
+    }
+
+    SclLabelProperties m_label_properties_frame[MAX_SCL_LABEL_PROPERTIES][MAX_SIZE_OF_LABEL_FOR_ONE];
+    int m_size;
+};
+
+LabelPropertyParser::LabelPropertyParser() {
+    m_impl = new LabelPropertiesParserImpl;
+}
+
+LabelPropertyParser::~LabelPropertyParser() {
+    if (m_impl) {
+        SCLLOG(SclLog::MESSAGE, "~LabelPropertyParser() has called");
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+
+LabelPropertyParser*
+LabelPropertyParser::get_instance() {
+    static LabelPropertyParser instance;
+    return &instance;
+}
+
+int
+LabelPropertyParser::init(const char* file) {
+    return m_impl->parsing_label_properties_frame(file);
+}
+
+int
+LabelPropertyParser::reload(const char* file) {
+    return m_impl->reload_label_properties_frame(file);
+}
+
+int
+LabelPropertyParser::get_size() {
+    return m_impl->m_size;
+}
+
+//recompute_layout will change the table
+PSclLabelPropertiesTable
+LabelPropertyParser::get_label_properties_frame() {
+    return m_impl->m_label_properties_frame;
+}
diff --git a/scl/label_properties_parser.h b/scl/label_properties_parser.h
new file mode 100644 (file)
index 0000000..b6a7594
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012 - 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 __LabelPropertyParser__H__
+#define __LabelPropertyParser__H__
+#include "sclres_type.h"
+class LabelPropertiesParserImpl;
+
+class LabelPropertyParser {
+    LabelPropertiesParserImpl *m_impl;
+    public:
+    int init(const char* file);
+    int reload(const char* file);
+    PSclLabelPropertiesTable get_label_properties_frame();
+    int get_size();
+    public:
+    ~LabelPropertyParser();
+    static LabelPropertyParser *get_instance();
+    private:
+    LabelPropertyParser();
+};
+
+
+#endif
diff --git a/scl/layout_bin_parser.cpp b/scl/layout_bin_parser.cpp
new file mode 100644 (file)
index 0000000..bb923f4
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2012 - 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 "layout_bin_parser.h"
+#include "default_configure_bin_parser.h"
+#include "key_coordinate_frame_bin_parser.h"
+#include "sclutils.h"
+
+#include "put_record.h"
+#include <algorithm>
+using namespace std;
+using namespace scl;
+
+BinLayoutParser::
+BinLayoutParser() {
+    m_layout_size = 0;
+    memset(m_layout_table, 0x00, sizeof(SclLayout) * MAX_SCL_LAYOUT);
+    parser_info_provider = NULL;
+}
+BinLayoutParser::
+~BinLayoutParser() {
+}
+BinLayoutParser* BinLayoutParser::
+get_instance() {
+    static BinLayoutParser instance;
+    return &instance;
+}
+void BinLayoutParser::
+init(const FileStorage& storage, int offset, int size, IParserInfo_Provider* provider) {
+    m_storage.set_str_provider(provider);
+    m_storage.get_storage(storage, offset, size);
+    this->parser_info_provider = provider;
+    parsing_layout_table();
+}
+
+int BinLayoutParser::
+get_layout_index(const char *name) {
+    int ret = NOT_USED;
+    if (name) {
+        for (int loop = 0;loop < MAX_SCL_LAYOUT && ret == NOT_USED;loop++) {
+            if (m_layout_table[loop].name) {
+                if (strcmp(m_layout_table[loop].name, name) == 0) {
+                    ret = loop;
+                    break;
+                }
+            }
+        }
+    }
+    return ret;
+}
+
+PSclLayout BinLayoutParser::
+get_layout_table() {
+    return m_layout_table;
+}
+int BinLayoutParser::
+get_layout_size() {
+    return m_layout_size;
+}
+
+
+PSclLayoutKeyCoordinatePointerTable BinLayoutParser::
+get_key_coordinate_pointer_frame() {
+    BinKeyCoordFrameParser *key_coordinate_frame_bin_parser = BinKeyCoordFrameParser::get_instance();
+    return key_coordinate_frame_bin_parser->get_key_coordinate_pointer_frame();
+}
+
+void BinLayoutParser::
+parsing_layout_table() {
+    // 4 byte (range[0-4,294,967,295))
+    const int DATA_SIZE_BYTES = 4;
+    // 1 byte (range[0-128))
+    const int REC_NUM_BYTES = 1;
+    // 2 byte (range[0-65536))
+    const int LAYOUT_REC_DATA_SIZE_BYTES = 2;
+
+    /*open binary file*/
+    Layout_width record_width;
+    set_layout_width(*parser_info_provider, record_width);
+
+    // skip data size
+    m_storage.advance(DATA_SIZE_BYTES);
+
+    // rec_num
+    m_layout_size = m_storage.get<sint_t>(REC_NUM_BYTES);
+
+    // layout_rec_data_size
+    m_storage.advance(LAYOUT_REC_DATA_SIZE_BYTES);
+
+    for (int i = 0; i < m_layout_size; ++i) {
+        SclLayout& cur = m_layout_table[i];
+        decode_layout_record(cur, record_width);
+    }
+#ifdef __SCL_TXT_DEBUG
+    put_layout_table(DECODE, m_layout_table);
+#endif
+}
+
+void
+BinLayoutParser::
+decode_color(SclColor& color, int width) {
+    if (width <= 0) return;
+
+    color.r = m_storage.get<sint_t>(width);
+    color.g = m_storage.get<sint_t>(width);
+    color.b = m_storage.get<sint_t>(width);
+    color.a = m_storage.get<sint_t>(width);
+}
+void BinLayoutParser::
+decode_layout_record(SclLayout& cur, const Layout_width& record_width) {
+    //name
+    m_storage.get_str(&(cur.name), record_width.name, m_string_collector);
+    //display mode
+    cur.display_mode = (SCLDisplayMode)m_storage.get<sint_t>(record_width.display_mode);
+    //style
+    cur.style = (SCLLayoutStyle)m_storage.get<sint_t>(record_width.style);
+    //width
+    cur.width = m_storage.get<sint_t>(record_width.width);
+    //height
+    cur.height = m_storage.get<sint_t>(record_width.height);
+    //use_sw_button
+    cur.use_sw_button = m_storage.get<sint_t>(record_width.use_sw_button);
+
+    //use_magnifier_window
+    cur.use_magnifier_window = m_storage.get<sint_t>(record_width.use_magnifier_window);
+
+    //extract_background
+    cur.extract_background = m_storage.get<sint_t>(record_width.extract_background);
+
+    //key_width
+    cur.key_width = m_storage.get<sint_t>(record_width.key_width);
+    //key_height
+    cur.key_height = m_storage.get<sint_t>(record_width.key_height);
+    //key_spacing
+    cur.key_spacing = m_storage.get<sint_t>(record_width.key_spacing);
+    //row_spacing
+    cur.row_spacing = m_storage.get<sint_t>(record_width.row_spacing);
+    //use_sw_background
+    cur.use_sw_background = m_storage.get<sint_t>(record_width.use_sw_background);
+
+    decode_color(cur.bg_color, record_width.bg_color);
+    //bg_line_width
+    cur.bg_line_width = m_storage.get<float_t>(record_width.bg_line_width);
+
+    decode_color(cur.bg_line_color, record_width.bg_line_color);
+
+    //add_grab_left
+    cur.add_grab_left = m_storage.get<sint_t>(record_width.add_grab_left);
+
+    //add_grab_right
+    cur.add_grab_right = m_storage.get<sint_t>(record_width.add_grab_right);
+    //add_grab_top
+    cur.add_grab_top = m_storage.get<sint_t>(record_width.add_grab_top);
+    //add_grab_bottom
+    cur.add_grab_bottom = m_storage.get<sint_t>(record_width.add_grab_bottom);
+    //image_path
+    for (int i = 0; i < SCL_BUTTON_STATE_MAX; ++i) {
+        m_storage.get_str(&(cur.image_path[i]), record_width.image_path, m_string_collector);
+    }
+
+    //key_background_image
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            m_storage.get_str(&(cur.key_background_image[i][j]), record_width.key_background_image, m_string_collector);
+        }
+    }
+
+    //sound_style
+    m_storage.get_str(&(cur.sound_style), record_width.sound_style, m_string_collector);
+
+    //vibe_style
+    m_storage.get_str(&(cur.vibe_style), record_width.vibe_style, m_string_collector);
+
+    //label_type
+    m_storage.get_str(&(cur.label_type), record_width.label_type, m_string_collector);
+
+    //modifier_decorator
+    m_storage.get_str(&(cur.modifier_decorator), record_width.modifier_decorator, m_string_collector);
+}
+
+
diff --git a/scl/layout_bin_parser.h b/scl/layout_bin_parser.h
new file mode 100644 (file)
index 0000000..4903b8a
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012 - 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 __LAYOUT_BIN_PARSER__H__
+#define __LAYOUT_BIN_PARSER__H__
+#include "sclres_type.h"
+#include "iparserinfo_provider.h"
+#include <vector>
+#include "string_collector.h"
+#include "file_storage_impl.h"
+#include "_auto_metadata.h"
+class BinLayoutParser {
+    public:
+        static BinLayoutParser *get_instance();
+    void init(const FileStorage& storage, int, int, IParserInfo_Provider*);
+
+    int get_layout_index(const char *name);
+    int get_layout_size();
+    PSclLayout get_layout_table();
+    PSclLayoutKeyCoordinatePointerTable get_key_coordinate_pointer_frame();
+
+    ~BinLayoutParser();
+    private:
+    BinLayoutParser();
+    void parsing_layout_table();
+    void decode_layout_record(SclLayout& cur, const Layout_width&);
+    void decode_color(SclColor&, int width);
+
+    private:
+        int m_layout_size;
+        SclLayout m_layout_table[MAX_SCL_LAYOUT];
+
+        FileStorage m_storage;
+        IParserInfo_Provider *parser_info_provider;
+        StringCollector m_string_collector;
+};
+
+
+#endif
diff --git a/scl/layout_parser.cpp b/scl/layout_parser.cpp
new file mode 100644 (file)
index 0000000..836e433
--- /dev/null
@@ -0,0 +1,1605 @@
+/*
+ * Copyright (c) 2012 - 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 <algorithm>
+#include <vector>
+#include <malloc.h>
+#include <string.h>
+#include <libxml/parser.h>
+#include <glib.h>
+
+#include "scldebug.h"
+#include "layout_parser.h"
+#include "default_configure_parser.h" /* use data in default_configure.xml */
+#include "xml_parser_utils.h"
+#include "layout_parser_helper.h"
+#include "put_record.h"
+#include "simple_debug.h"
+#include <dlog.h>
+
+using namespace std;
+
+#define LAYOUT_TAG "layout"
+#define LAYOUT_NAME_ATTRIBUTE "name"
+#define LAYOUT_DIRECTION_ATTRIBUTE "direction"
+#define LAYOUT_DIRECTION_ATTRIBUTE_PORTRAIT_VALUE "portrait"
+#define LAYOUT_DIRECTION_ATTRIBUTE_LANDSCAPE_VALUE "landscape"
+#define LAYOUT_STYLE_ATTRIBUTE "style"
+#define LAYOUT_STYLE_ATTRIBUTE_BASE_VALUE "base"
+#define LAYOUT_STYLE_ATTRIBUTE_POPUP_VALUE "popup"
+#define LAYOUT_STYLE_ATTRIBUTE_POPUP_GRAB_VALUE "popup_grab"
+#define LAYOUT_WIDTH_ATTRIBUTE "width"
+#define LAYOUT_HEIGHT_ATTRIBUTE "height"
+#define LAYOUT_MAGNIFIER_ATTRIBUTE "magnifier"
+#define LAYOUT_PART_BACKGROUND_ATTRIBUTE "part_background"
+#define LAYOUT_SW_BUTTON_ATTRIBUTE "sw_button"
+#define LAYOUT_SW_BACKGROUND_ATTRIBUTE "sw_background"
+#define LAYOUT_KEY_WIDTH_ATTRIBUTE "key_width"
+#define LAYOUT_KEY_HEIGHT_ATTRIBUTE "key_height"
+#define LAYOUT_KEY_SPACING_ATTRIBUTE "key_spacing"
+#define LAYOUT_ROW_SPACING_ATTRIBUTE "row_spacing"
+#define LAYOUT_KEY_ADD_HIT_LEFT_ATTRIBUTE "hit_left"
+#define LAYOUT_KEY_ADD_HIT_RIGHT_ATTRIBUTE "hit_right"
+#define LAYOUT_KEY_ADD_HIT_TOP_ATTRIBUTE "hit_top"
+#define LAYOUT_KEY_ADD_HIT_BOTTOM_ATTRIBUTE "hit_bottom"
+#define LAYOUT_VIBE_STYLE_ATTRIBUTE "vibe_style"
+#define LAYOUT_SOUND_STYLE_ATTRIBUTE "sound_style"
+#define LAYOUT_LABEL_TYPE_ATTRIBUTE "label_type"
+#define LAYOUT_MODIFIER_DECORATION_ATTRIBUTE "modifier_decoration"
+
+#define LAYOUT_ADD_GRAB_TAG "grab_area"
+#define LAYOUT_ADD_GRAB_LEFT_TAG "left"
+#define LAYOUT_ADD_GRAB_RIGHT_TAG "right"
+#define LAYOUT_ADD_GRAB_TOP_TAG "top"
+#define LAYOUT_ADD_GRAB_BOTTOM_TAG "bottom"
+
+#define LAYOUT_KEY_BACKGROUND_REC_TAG "rec"
+#define LAYOUT_KEY_BACKGROUND_REC_BUTTON_ATTRIBUTE "button"
+#define LAYOUT_KEY_BACKGROUND_REC_BUTTON_ATTRIBUTE_NORMAL_VALUE "normal"
+#define LAYOUT_KEY_BACKGROUND_REC_BUTTON_ATTRIBUTE_PRESSED_VALUE "pressed"
+#define LAYOUT_KEY_BACKGROUND_REC_BUTTON_ATTRIBUTE_DISABLED_VALUE "disabled"
+
+#define LAYOUT_KEY_BACKGROUND_TAG "background_image"
+#define LAYOUT_KEY_BACKGROUND_REC_TAG "rec"
+#define LAYOUT_KEY_BACKGROUND_REC_BUTTON_ATTRIBUTE "button"
+#define LAYOUT_KEY_BACKGROUND_REC_BUTTON_ATTRIBUTE_NORMAL_VALUE "normal"
+#define LAYOUT_KEY_BACKGROUND_REC_BUTTON_ATTRIBUTE_PRESSED_VALUE "pressed"
+#define LAYOUT_KEY_BACKGROUND_REC_BUTTON_ATTRIBUTE_DISABLED_VALUE "disabled"
+
+#define LAYOUT_BACKGROUND_TAG "image_path"
+#define LAYOUT_BACKGROUND_NORMAL_TAG "button_normal"
+#define LAYOUT_BACKGROUND_PRESSED_TAG "button_pressed"
+#define LAYOUT_BACKGROUND_DISABLED_TAG "button_disabled"
+#define LAYOUT_BACKGROUND_TOGGLED_TAG "button_toggled"
+
+#define LAYOUT_SW_BACKGROUND_TAG "background_color"
+
+#define LAYOUT_ROW_TAG "row"
+#define LAYOUT_ROW_SUBLAYOUT_ID_ATTRIBUTE "sub_layout"
+#define LAYOUT_ROW_X_ATTRIBUTE "x"
+#define LAYOUT_ROW_Y_ATTRIBUTE "y"
+#define LAYOUT_ROW_KEY_WIDTH_ATTRIBUTE LAYOUT_KEY_WIDTH_ATTRIBUTE
+#define LAYOUT_ROW_KEY_HEIGHT_ATTRIBUTE LAYOUT_KEY_HEIGHT_ATTRIBUTE
+#define LAYOUT_ROW_KEY_SPACING_ATTRIBUTE LAYOUT_KEY_SPACING_ATTRIBUTE
+
+#define LAYOUT_ROW_KEY_TAG "key"
+#define LAYOUT_ROW_KEY_CUSTOMID_ATTRIBUTE "custom_id"
+#define LAYOUT_ROW_KEY_BUTTON_TYPE_ATTRIBUTE "button_type"
+#define LAYOUT_ROW_KEY_KEY_TYPE_ATTRIBUTE "key_type"
+#define LAYOUT_ROW_KEY_POPUP_TYPE_ATTRIBUTE "popup_type"
+#define LAYOUT_ROW_KEY_MAGNIFIER_ATTRIBUTE "use_magnifier"
+#define LAYOUT_ROW_KEY_LONGKEY_MAGNIFIER_ATTRIBUTE "longkey_magnifier"
+#define LAYOUT_ROW_KEY_VIBE_STYLE_ATTRIBUTE LAYOUT_VIBE_STYLE_ATTRIBUTE
+#define LAYOUT_ROW_KEY_SOUND_STYLE_ATTRIBUTE LAYOUT_SOUND_STYLE_ATTRIBUTE
+#define LAYOUT_ROW_KEY_SIDE_BUTTON_ATTRIBUTE "is_side_button"
+
+#define LAYOUT_ROW_KEY_X_ATTRIBUTE "x"
+#define LAYOUT_ROW_KEY_Y_ATTRIBUTE "y"
+#define LAYOUT_ROW_KEY_KEY_WIDTH_ATTRIBUTE "width"
+#define LAYOUT_ROW_KEY_KEY_HEIGHT_ATTRIBUTE "height"
+#define LAYOUT_ROW_KEY_ADD_HIT_LEFT_ATTRIBUTE "hit_left"
+#define LAYOUT_ROW_KEY_ADD_HIT_RIGHT_ATTRIBUTE "hit_right"
+#define LAYOUT_ROW_KEY_ADD_HIT_TOP_ATTRIBUTE "hit_top"
+#define LAYOUT_ROW_KEY_ADD_HIT_BOTTOM_ATTRIBUTE "hit_bottom"
+#define LAYOUT_ROW_KEY_POPUP_POS_X_ATTRIBUTE "popup_offset_x"
+#define LAYOUT_ROW_KEY_POPUP_POS_Y_ATTRIBUTE "popup_offset_y"
+#define LAYOUT_ROW_KEY_POPUP_IMAGE_X_ATTRIBUTE "popup_image_x"
+#define LAYOUT_ROW_KEY_POPUP_IMAGE_Y_ATTRIBUTE "popup_image_y"
+#define LAYOUT_ROW_KEY_SUBLAYOUT_ID_ATTRIBUTE "sub_layout"
+
+#define LAYOUT_ROW_KEY_LABEL_TYPE_ATTRIBUTE "label_type"
+#define LAYOUT_ROW_KEY_IMAGE_LABEL_TYPE_ATTRIBUTE "image_label_type"
+#define LAYOUT_ROW_KEY_LONGKEY_TYPE_ATTRIBUTE "long_key_type"
+#define LAYOUT_ROW_KEY_LONGKEY_VALUE_ATTRIBUTE "long_key_value"
+#define LAYOUT_ROW_KEY_LONGKEY_EVENT_ATTRIBUTE "long_key_event"
+#define LAYOUT_ROW_KEY_USE_REPEAT_KEY_ATTRIBUTE "use_repeat_key"
+#define LAYOUT_ROW_KEY_DONOT_CLOSE_POPUP_ATTRIBUTE "donot_close_popup"
+#define LAYOUT_ROW_KEY_EXTRA_OPTION_ATTRIBUTE "extra_option"
+#define LAYOUT_ROW_KEY_MULTITOUCH_TYPE_ATTRIBUTE "multitouch_type"
+#define LAYOUT_ROW_KEY_MODIFIER_DECORATION_ID_ATTRIBUTE "modifier_decoration_id"
+
+#define LAYOUT_ROW_KEY_KEY_SPACING_ATTRIBUTE "key_spacing"
+
+#define LAYOUT_ROW_KEY_LABEL_TAG "label"
+#define LAYOUT_ROW_KEY_IMAGE_LABEL_TAG "image_label"
+#define LAYOUT_ROW_KEY_BACKGROUND_IMAGE_TAG "background_image"
+#define LAYOUT_ROW_KEY_KEY_VALUE_TAG "key_value"
+#define LAYOUT_ROW_KEY_KEY_EVENT_TAG "key_event"
+
+#define LAYOUT_ROW_KEY_POPUP_INPUTMODE_RECORD_TAG "popup_input_mode_record"
+#define LAYOUT_ROW_KEY_POPUP_INPUTMODE_RECORD_INPUTMODE_TAG "popup_input_mode"
+
+#define LAYOUT_ROW_KEY_AUTOPOPUP_KEYS_TAG "auto_popup_keys"
+#define LAYOUT_ROW_KEY_AUTOPOPUP_KEYS_SHIFTMODE_ATTRIBUTE "shift_state"
+#define LAYOUT_ROW_KEY_MAGNIFIER_LABEL_TAG "magnifier_label"
+
+#define LAYOUT_ROW_KEY_HINT_STRING_TAG "hint_string"
+
+#define LAYOUT_SUB_LAYOUT_DEFAULT_STRING "DEFAULT"
+
+class LayoutParserImpl {
+    public:
+        typedef struct {
+            int row_x;
+            int row_y;
+
+            sclshort key_width;
+            sclshort key_height;
+            sclshort key_spacing;
+            sclshort row_spacing;
+
+            sclshort add_hit_left;
+            sclshort add_hit_right;
+            sclshort add_hit_top;
+            sclshort add_hit_bottom;
+
+            sclchar *sub_layout;
+            sclchar *vibe_style;
+            sclchar *sound_style;
+            sclchar *label_type;
+            sclchar *bg_image_path[SCL_SHIFT_STATE_MAX][SCL_BUTTON_STATE_MAX];
+        } Row;
+        LayoutParserImpl();
+        ~LayoutParserImpl();
+
+        void reset();
+
+        void load(int layout_id);
+        void unload();
+        bool loaded(int layout_id);
+        void set_directory(const string &dir);
+        int get_layout_index(const char *name);
+        int get_layout_size();
+        PSclLayout get_layout_table();
+        PSclLayoutKeyCoordinatePointerTable get_key_coordinate_pointer_frame();
+        int get_drag_state_prop(const xmlNodePtr cur_node);
+        int get_shift_state_prop(const xmlNodePtr cur_node);
+        int get_button_state_prop(const xmlNodePtr cur_node);
+        int get_multitouch_type_prop(const xmlNodePtr cur_node);
+        int get_extra_option_prop(const xmlNodePtr cur_node);
+
+        int parsing_layout_table(const vector<string> &layout_file_name);
+        int reload_layout_table(const vector<string> &layout_file_name);
+
+        void parsing_layout_node(const xmlNodePtr cur_node, const PSclLayout cur_rec_layout, int layout_no);
+        void loading_coordinate_resources(const xmlNodePtr cur_node, const PSclLayout cur_rec_layout, int layout_no);
+        void parsing_background(const xmlNodePtr cur_node, const PSclLayout);
+        void parsing_key_background(const xmlNodePtr cur_node, const PSclLayout);
+        void parsing_grab_area(const xmlNodePtr cur_node, const PSclLayout cur_rec_layout);
+        void parsing_sw_background_color(const xmlNodePtr cur_node, const PSclLayout);
+
+        void set_default_layout_value(const PSclLayout);
+        void set_default_row_value(Row*, const PSclLayout cur_rec_layout, const int row_y);
+        void set_default_key_coordinate_value(const PSclLayoutKeyCoordinate cur_rec_coordinate, const Row*);
+
+        void parsing_layout_row_node(const xmlNodePtr cur_node, const PSclLayout cur_rec_layout,
+            int *row_y, int *sub_layout_height, SclLayoutKeyCoordinatePointer **cur_key, int layout_no);
+        void parsing_key_coordinate_record_node(const xmlNodePtr cur_node, Row* row,
+            SclLayoutKeyCoordinatePointer *cur_key, int layout_no);
+
+        void parsing_label_record_node(const xmlNodePtr cur_node, const PSclLayoutKeyCoordinate cur_rec);
+        void parsing_label_image_record_node(const xmlNodePtr cur_node, const PSclLayoutKeyCoordinate cur_rec);
+        void parsing_background_image_record_node(const xmlNodePtr cur_node, const PSclLayoutKeyCoordinate cur_rec);
+        void parsing_popup_input_mode_record_node(const xmlNodePtr cur_node, const PSclLayoutKeyCoordinate cur_rec);
+        void parsing_key_value_record_node(const xmlNodePtr cur_node, const PSclLayoutKeyCoordinate cur_rec);
+        void parsing_key_event_record_node(const xmlNodePtr cur_node, const PSclLayoutKeyCoordinate cur_rec);
+        void parsing_auto_popup_keys_record_node(const xmlNodePtr cur_node, const PSclLayoutKeyCoordinate cur_rec);
+        void parsing_magnifier_label_record_node(const xmlNodePtr cur_node, const PSclLayoutKeyCoordinate cur_rec);
+        void parsing_hint_string_record_node(const xmlNodePtr cur_node, const PSclLayoutKeyCoordinate cur_rec);
+
+        void add_layout_string(xmlChar*);
+        void release_layout_strings();
+
+        void add_key_string(xmlChar*);
+        void release_key_strings();
+
+        void add_upper_string(gchar*);
+        void release_upper_strings();
+
+    private:
+        int m_layout_size;
+        int m_num_keys[MAX_SCL_LAYOUT];
+        SclLayout m_layout_table[MAX_SCL_LAYOUT];
+        vector<string> m_file_names;
+        SclLayoutKeyCoordinate* m_key_coordinate_pointer_frame[MAX_SCL_LAYOUT][MAX_KEY];
+
+        std::vector<xmlChar*> m_vec_layout_strings;
+        std::vector<xmlChar*> m_vec_key_strings;
+        std::vector<gchar*> m_vec_upper_strings;
+        std::string m_dir;
+};
+
+
+LayoutParserImpl::LayoutParserImpl() {
+    m_layout_size = 0;
+    for (int i = 0; i < MAX_SCL_LAYOUT; ++i) {
+        m_num_keys[i] = 0;
+    }
+    memset(m_layout_table, 0x00, sizeof(SclLayout) * MAX_SCL_LAYOUT);
+    memset(m_key_coordinate_pointer_frame, 0x00, sizeof(SclLayoutKeyCoordinatePointer) * MAX_SCL_LAYOUT * MAX_KEY);
+}
+
+LayoutParserImpl::~LayoutParserImpl() {
+    reset();
+}
+
+void LayoutParserImpl::reset() {
+    m_layout_size = 0;
+    for (int i = 0; i < MAX_SCL_LAYOUT; ++i) {
+        m_num_keys[i] = 0;
+        for (int j = 0; j < MAX_KEY; ++j) {
+            free(m_key_coordinate_pointer_frame[i][j]);
+            m_key_coordinate_pointer_frame[i][j] = NULL;
+        }
+    }
+
+    memset(m_layout_table, 0x00, sizeof(SclLayout) * MAX_SCL_LAYOUT);
+    memset(m_key_coordinate_pointer_frame, 0x00, sizeof(SclLayoutKeyCoordinatePointer) * MAX_SCL_LAYOUT * MAX_KEY);
+
+    release_layout_strings();
+    release_key_strings();
+    release_upper_strings();
+}
+
+void
+LayoutParserImpl::load(int layout_id) {
+    if (layout_id >= 0 && layout_id < MAX_SCL_LAYOUT) {
+        xmlDocPtr doc;
+        xmlNodePtr cur_node;
+
+        string input_file = m_dir + "/" + m_file_names[layout_id];
+        doc = xmlReadFile(input_file.c_str(), NULL, 0);
+        if (doc == NULL) {
+            SCLLOG(SclLog::ERROR, "Could not load file: %s.", input_file.c_str());
+            LOGE("Could not load file: %s.", input_file.c_str());
+            return;
+        }
+
+        cur_node = xmlDocGetRootElement(doc);
+        if (cur_node == NULL) {
+            SCLLOG(SclLog::ERROR, "LayoutParserImpl: empty document.\n");
+            LOGE("LayoutParserImpl: empty document.");
+            xmlFreeDoc(doc);
+            return;
+        }
+        if (0 != xmlStrcmp(cur_node->name, (const xmlChar*)LAYOUT_TAG))
+        {
+            SCLLOG(SclLog::ERROR, "LayoutParserImpl: root name error: %s\n!", (char *)cur_node->name);
+            LOGE("LayoutParserImpl: root name error: %s!", (char *)cur_node->name);
+            xmlFreeDoc(doc);
+            return;
+        }
+
+        PSclLayout cur_rec_layout = m_layout_table + layout_id;
+
+        cur_rec_layout->name = (sclchar*)m_file_names[layout_id].c_str();
+
+        parsing_layout_node(cur_node, cur_rec_layout, layout_id);
+        loading_coordinate_resources(cur_node, cur_rec_layout, layout_id);
+
+        xmlFreeDoc(doc);
+    }
+}
+
+void LayoutParserImpl::unload() {
+    for (int i = 0; i < MAX_SCL_LAYOUT; ++i) {
+        for (int j = 0; j < MAX_KEY; ++j) {
+            if (m_key_coordinate_pointer_frame[i][j]) {
+                free(m_key_coordinate_pointer_frame[i][j]);
+                m_key_coordinate_pointer_frame[i][j] = NULL;
+            }
+        }
+    }
+
+    release_layout_strings();
+    release_key_strings();
+    release_upper_strings();
+}
+
+bool
+LayoutParserImpl::loaded(int layout_id) {
+    bool ret = TRUE;
+
+    if (layout_id >= 0 && layout_id < MAX_SCL_LAYOUT) {
+        if (m_key_coordinate_pointer_frame[layout_id][0] == NULL) {
+            ret = FALSE;
+        }
+    }
+
+    return ret;
+}
+
+void
+LayoutParserImpl::set_directory(const string& dir) {
+    m_dir = dir;
+}
+
+void
+LayoutParserImpl::add_layout_string(xmlChar* newstr) {
+    if (newstr) {
+        m_vec_layout_strings.push_back(newstr);
+    }
+}
+
+void
+LayoutParserImpl::release_layout_strings() {
+    for (size_t loop = 0; loop < m_vec_layout_strings.size(); loop++) {
+        if (m_vec_layout_strings[loop]) {
+            xmlFree(m_vec_layout_strings[loop]);
+        }
+    }
+    m_vec_layout_strings.clear();
+}
+
+void
+LayoutParserImpl::add_key_string(xmlChar* newstr) {
+    if (newstr) {
+        m_vec_key_strings.push_back(newstr);
+    }
+}
+
+void
+LayoutParserImpl::release_key_strings() {
+    for (size_t loop = 0; loop < m_vec_key_strings.size(); loop++) {
+        if (m_vec_key_strings[loop]) {
+            xmlFree(m_vec_key_strings[loop]);
+        }
+    }
+    m_vec_key_strings.clear();
+}
+
+void
+LayoutParserImpl::add_upper_string(gchar* newstr) {
+    if (newstr) {
+        m_vec_upper_strings.push_back(newstr);
+    }
+}
+
+void
+LayoutParserImpl::release_upper_strings() {
+    for (size_t loop = 0; loop < m_vec_upper_strings.size(); loop++) {
+        if (m_vec_upper_strings[loop]) {
+            g_free(m_vec_upper_strings[loop]);
+        }
+    }
+    m_vec_upper_strings.clear();
+}
+
+int
+LayoutParserImpl::get_layout_index(const char *name) {
+    if (name) {
+        string strName = (string)name;
+        vector<string>::iterator it;
+        // make sure that the m_file_names are sorted.
+        it = lower_bound(m_file_names.begin(), m_file_names.end(), strName);
+        if (it != m_file_names.end() && *it == strName) {
+            return it - m_file_names.begin();
+        }
+    }
+    return NOT_USED;
+}
+
+PSclLayout
+LayoutParserImpl::get_layout_table() {
+    return m_layout_table;
+}
+
+int
+LayoutParserImpl::get_layout_size() {
+    return m_layout_size;
+}
+
+PSclLayoutKeyCoordinatePointerTable
+LayoutParserImpl::get_key_coordinate_pointer_frame() {
+    return m_key_coordinate_pointer_frame;
+}
+
+int
+LayoutParserImpl::reload_layout_table(const vector<string> &vec_file) {
+    reset();
+    return parsing_layout_table(vec_file);
+}
+
+int
+LayoutParserImpl::parsing_layout_table(const vector<string> &vec_file) {
+    m_file_names = vec_file;
+    m_layout_size = vec_file.size();
+
+    return 0;
+}
+
+void
+LayoutParserImpl::parsing_background(
+        const xmlNodePtr cur_node,
+        PSclLayout cur_layout) {
+    assert(cur_node != NULL);
+    assert(cur_layout != NULL);
+
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_BACKGROUND_NORMAL_TAG)) {
+            xmlChar *key = xmlNodeGetContent(child_node);
+            cur_layout->image_path[BUTTON_STATE_NORMAL] = (char *)key;
+            add_layout_string(key);
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_BACKGROUND_PRESSED_TAG)) {
+            xmlChar *key = xmlNodeGetContent(child_node);
+            cur_layout->image_path[BUTTON_STATE_PRESSED] = (char *)key;
+            add_layout_string(key);
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_BACKGROUND_DISABLED_TAG )) {
+            xmlChar *key = xmlNodeGetContent(child_node);
+            cur_layout->image_path[BUTTON_STATE_DISABLED] = (char *)key;
+            add_layout_string(key);
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_BACKGROUND_TOGGLED_TAG )) {
+            xmlChar *key = xmlNodeGetContent(child_node);
+            cur_layout->image_path[BUTTON_STATE_TOGGLED] = (char *)key;
+            add_layout_string(key);
+        }
+
+        child_node = child_node->next;
+    }
+}
+
+void
+LayoutParserImpl::parsing_sw_background_color(
+    const xmlNodePtr cur_node,
+    PSclLayout cur_layout) {
+    assert(cur_node != NULL);
+    assert(cur_layout != NULL);
+
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"r")) {
+            cur_layout->bg_color.r = get_content_int(child_node);
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"g")) {
+            cur_layout->bg_color.g = get_content_int(child_node);
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"b")) {
+            cur_layout->bg_color.b = get_content_int(child_node);
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"a")) {
+            cur_layout->bg_color.a = get_content_int(child_node);
+        }
+
+        child_node = child_node->next;
+    }
+}
+
+void
+LayoutParserImpl::parsing_key_background(
+        const xmlNodePtr cur_node,
+        PSclLayout cur_layout) {
+    assert(cur_node != NULL);
+    assert(cur_layout != NULL);
+
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"rec")) {
+            int shift_state = get_shift_state_prop(child_node);
+            int button_state = get_button_state_prop(child_node);
+            for (int shift_loop = 0;shift_loop < SCL_SHIFT_STATE_MAX;shift_loop++) {
+                for (int button_loop = 0;button_loop < SCL_BUTTON_STATE_MAX;button_loop++) {
+                    if ((shift_state == shift_loop || shift_state == -1) &&
+                        (button_state == button_loop || button_state == -1)) {
+                            xmlChar* key = xmlNodeGetContent(child_node);
+                            cur_layout->key_background_image[shift_loop][button_loop] = (sclchar*)key;
+                            add_layout_string(key);
+                    }
+                }
+            }
+        }
+
+        child_node = child_node->next;
+    }
+}
+
+
+void
+LayoutParserImpl::set_default_layout_value(const PSclLayout cur_layout) {
+    DefaultConfigParser *default_configure_parser = DefaultConfigParser::get_instance();
+    assert(default_configure_parser);
+    const PSclDefaultConfigure sclres_default_configure = default_configure_parser->get_default_configure();
+
+    assert(cur_layout != NULL);
+    cur_layout->valid = 1;
+    cur_layout->style = LAYOUT_STYLE_BASE;
+    cur_layout->name = NULL;
+
+    if (sclres_default_configure) {
+        cur_layout->width = sclres_default_configure->target_screen_width;
+        cur_layout->height = sclres_default_configure->target_screen_height;
+    }
+
+    cur_layout->key_width = 0;
+    cur_layout->key_height = 0;
+    cur_layout->key_spacing = 0;
+    cur_layout->row_spacing = 0;
+
+    cur_layout->image_path[BUTTON_STATE_NORMAL]      = NULL;
+    cur_layout->image_path[BUTTON_STATE_PRESSED]     = NULL;
+    cur_layout->image_path[BUTTON_STATE_DISABLED]    = NULL;
+    cur_layout->image_path[BUTTON_STATE_TOGGLED]     = NULL;
+
+    cur_layout->use_sw_button = false;
+    cur_layout->use_magnifier_window = false;
+
+    cur_layout->display_mode = DISPLAYMODE_PORTRAIT;
+    cur_layout->use_sw_background = false;
+    memset (&(cur_layout->bg_color), 0, sizeof(SclColor));
+    cur_layout->bg_line_width = 0.0;
+    memset (&(cur_layout->bg_line_color), 0, sizeof(SclColor));
+
+    memset (cur_layout->key_background_image, 0, sizeof(cur_layout->key_background_image));
+    cur_layout->sound_style = NULL;
+    cur_layout->vibe_style = NULL;
+    cur_layout->label_type = NULL;
+    cur_layout->modifier_decorator = NULL;
+
+    cur_layout->add_grab_left = NOT_USED;
+    cur_layout->add_grab_right = NOT_USED;
+    cur_layout->add_grab_top = NOT_USED;
+    cur_layout->add_grab_bottom = NOT_USED;
+}
+
+void
+LayoutParserImpl::set_default_row_value(
+        Row* row,
+        const PSclLayout cur_rec_layout,
+        int row_y) {
+    if (row) {
+        row->row_x = 0;
+        row->row_y = row_y;
+        row->key_width = cur_rec_layout->key_width;
+        row->key_height = cur_rec_layout->key_height;
+        row->key_spacing = cur_rec_layout->key_spacing;
+        row->row_spacing = cur_rec_layout->row_spacing;
+        row->add_hit_left = cur_rec_layout->add_hit_left;
+        row->add_hit_right = cur_rec_layout->add_hit_right;
+        row->add_hit_top = cur_rec_layout->add_hit_top;
+        row->add_hit_bottom = cur_rec_layout->add_hit_bottom;
+        row->sub_layout = NULL;
+        row->label_type = cur_rec_layout->label_type;
+        row->vibe_style = cur_rec_layout->vibe_style;
+        row->sound_style = cur_rec_layout->sound_style;
+        for (int shift_state = 0; shift_state < SCL_SHIFT_STATE_MAX; shift_state++) {
+            for (int button_state = 0; button_state < SCL_BUTTON_STATE_MAX; ++button_state) {
+                row->bg_image_path[shift_state][button_state] = cur_rec_layout->key_background_image[shift_state][button_state];
+            }
+        }
+    }
+}
+
+void
+LayoutParserImpl::set_default_key_coordinate_value(
+        const PSclLayoutKeyCoordinate cur_rec_coordinate,
+        const Row* row) {
+    assert(row != NULL);
+    assert(cur_rec_coordinate != NULL);
+
+    int loop;
+
+    if (row && cur_rec_coordinate) {
+        cur_rec_coordinate->valid = FALSE;
+        cur_rec_coordinate->custom_id = NULL;
+        cur_rec_coordinate->button_type = BUTTON_TYPE_NORMAL;
+        cur_rec_coordinate->key_type = KEY_TYPE_CHAR;
+        cur_rec_coordinate->popup_type = POPUP_TYPE_NONE;
+        cur_rec_coordinate->use_magnifier = (sclboolean)true;
+        cur_rec_coordinate->use_long_key_magnifier = (sclboolean)false;
+        //cur_rec_coordinate->enabled =(sclboolean) TRUE;
+        for (loop = 0;loop < SCL_DRAG_STATE_MAX;loop++) {
+            cur_rec_coordinate->popup_input_mode[loop] = NULL;
+        }
+        cur_rec_coordinate->sound_style = row->sound_style;
+        cur_rec_coordinate->vibe_style = row->vibe_style;
+        cur_rec_coordinate->is_side_button = false;
+
+        cur_rec_coordinate->x = row->row_x;
+        cur_rec_coordinate->y = row->row_y;
+        cur_rec_coordinate->width = row->key_width;
+        cur_rec_coordinate->height = row->key_height;
+
+        cur_rec_coordinate->add_hit_left = row->add_hit_left;
+        cur_rec_coordinate->add_hit_right = row->add_hit_right;
+        cur_rec_coordinate->add_hit_top = row->add_hit_top;
+        cur_rec_coordinate->add_hit_bottom = row->add_hit_bottom;
+
+        cur_rec_coordinate->label_type = row->label_type;
+        cur_rec_coordinate->image_label_type = NULL;
+
+        cur_rec_coordinate->label_count = 0;
+        for (int shift_state = 0; shift_state < SCL_SHIFT_STATE_MAX; shift_state++) {
+            for (int label_for_one = 0; label_for_one < MAX_SIZE_OF_LABEL_FOR_ONE; ++label_for_one) {
+                cur_rec_coordinate->label[shift_state][label_for_one] = NULL;
+            }
+        }
+        for (int shift_state = 0; shift_state < SCL_SHIFT_STATE_MAX; shift_state++) {
+            for (int button_state = 0; button_state < SCL_BUTTON_STATE_MAX; ++button_state) {
+                cur_rec_coordinate->image_label_path[shift_state][button_state] = NULL;
+            }
+        }
+        for (int shift_state = 0; shift_state < SCL_SHIFT_STATE_MAX; shift_state++) {
+            for (int button_state = 0; button_state < SCL_BUTTON_STATE_MAX; ++button_state) {
+                //cur_rec_coordinate->bg_image_path[shift_state]![button_state] = NULL;
+                cur_rec_coordinate->bg_image_path[shift_state][button_state] = row->bg_image_path[shift_state][button_state];
+            }
+        }
+        cur_rec_coordinate->key_value_count = 0;
+        for (int shift_state = 0; shift_state < SCL_SHIFT_STATE_MAX; shift_state++) {
+            for (int multitap_state = 0; multitap_state < MAX_SIZE_OF_MULTITAP_CHAR; ++multitap_state) {
+                cur_rec_coordinate->key_value[shift_state][multitap_state] = NULL;
+            }
+        }
+        for (int shift_state = 0; shift_state < SCL_SHIFT_STATE_MAX; shift_state++) {
+            for (int multitap_state = 0; multitap_state < MAX_SIZE_OF_MULTITAP_CHAR; ++multitap_state) {
+                cur_rec_coordinate->key_event[shift_state][multitap_state] = 0;
+            }
+        }
+        /* assume the long_key_type is the same with key_type, by default */
+        cur_rec_coordinate->long_key_type = cur_rec_coordinate->key_type;
+        cur_rec_coordinate->long_key_value = NULL;
+        cur_rec_coordinate->long_key_event = 0;
+
+        cur_rec_coordinate->use_repeat_key = false;
+        for (int shift_state = 0; shift_state < SCL_SHIFT_STATE_MAX; shift_state++) {
+            for (int autopopup_state = 0; autopopup_state < MAX_SIZE_OF_AUTOPOPUP_STRING; ++autopopup_state) {
+                cur_rec_coordinate->autopopup_key_labels[shift_state][autopopup_state] = NULL;
+                cur_rec_coordinate->autopopup_key_events[shift_state][autopopup_state] = 0;
+                cur_rec_coordinate->autopopup_key_values[shift_state][autopopup_state] = NULL;
+            }
+        }
+        cur_rec_coordinate->dont_close_popup = false;
+        cur_rec_coordinate->extra_option = NOT_USED;
+        cur_rec_coordinate->multitouch_type = SCL_MULTI_TOUCH_TYPE_EXCLUSIVE;
+        cur_rec_coordinate->modifier_decorator = NULL;
+        for (int shift_state = 0; shift_state < SCL_SHIFT_STATE_MAX; shift_state++) {
+            for (int multitap_state = 0; multitap_state < MAX_SIZE_OF_MULTITAP_CHAR; ++multitap_state) {
+                cur_rec_coordinate->hint_string[shift_state][multitap_state] = NULL;
+            }
+        }
+        cur_rec_coordinate->sub_layout = row->sub_layout;
+    }
+}
+
+void
+LayoutParserImpl::parsing_grab_area(
+        const xmlNodePtr cur_node,
+        const PSclLayout cur_rec_layout) {
+    assert(cur_node != NULL);
+
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ADD_GRAB_LEFT_TAG)) {
+            cur_rec_layout->add_grab_left = get_content_int(child_node);
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ADD_GRAB_RIGHT_TAG)) {
+            cur_rec_layout->add_grab_right = get_content_int(child_node);
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ADD_GRAB_TOP_TAG)) {
+            cur_rec_layout->add_grab_top = get_content_int(child_node);
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ADD_GRAB_BOTTOM_TAG)) {
+            cur_rec_layout->add_grab_bottom = get_content_int(child_node);
+        }
+        child_node = child_node->next;
+    }
+}
+
+void
+LayoutParserImpl::parsing_layout_node(
+        const xmlNodePtr cur_node,
+        const PSclLayout cur_rec_layout,
+        int layout_no) {
+    assert(cur_node != NULL);
+    assert(cur_rec_layout != NULL);
+
+    set_default_layout_value(cur_rec_layout);
+
+    xmlChar* key;
+
+    if (equal_prop(cur_node, LAYOUT_DIRECTION_ATTRIBUTE,
+        LAYOUT_DIRECTION_ATTRIBUTE_LANDSCAPE_VALUE)) {
+        cur_rec_layout->display_mode = DISPLAYMODE_LANDSCAPE;
+    }
+
+    if (equal_prop(cur_node, LAYOUT_STYLE_ATTRIBUTE,
+        LAYOUT_STYLE_ATTRIBUTE_POPUP_VALUE)) {
+            cur_rec_layout->style = LAYOUT_STYLE_POPUP;
+    } else if (equal_prop(cur_node, LAYOUT_STYLE_ATTRIBUTE,
+        LAYOUT_STYLE_ATTRIBUTE_POPUP_GRAB_VALUE)) {
+            cur_rec_layout->style = LAYOUT_STYLE_POPUP_GRAB;
+    }
+
+    get_prop_number(cur_node, LAYOUT_WIDTH_ATTRIBUTE, &(cur_rec_layout->width));
+    get_prop_number(cur_node, LAYOUT_HEIGHT_ATTRIBUTE, &(cur_rec_layout->height));
+    get_prop_bool(cur_node, LAYOUT_MAGNIFIER_ATTRIBUTE, &(cur_rec_layout->use_magnifier_window));
+
+    get_prop_bool(cur_node, LAYOUT_PART_BACKGROUND_ATTRIBUTE, &(cur_rec_layout->extract_background));
+    get_prop_bool(cur_node, LAYOUT_SW_BUTTON_ATTRIBUTE, &(cur_rec_layout->use_sw_button));
+    get_prop_bool(cur_node, LAYOUT_SW_BACKGROUND_ATTRIBUTE, &(cur_rec_layout->use_sw_background));
+
+    get_prop_number(cur_node, LAYOUT_KEY_WIDTH_ATTRIBUTE, &(cur_rec_layout->key_width));
+    get_prop_number(cur_node, LAYOUT_KEY_HEIGHT_ATTRIBUTE, &(cur_rec_layout->key_height));
+    get_prop_number(cur_node, LAYOUT_KEY_SPACING_ATTRIBUTE, &(cur_rec_layout->key_spacing));
+    get_prop_number(cur_node, LAYOUT_ROW_SPACING_ATTRIBUTE, &(cur_rec_layout->row_spacing));
+
+    get_prop_number(cur_node, LAYOUT_KEY_ADD_HIT_LEFT_ATTRIBUTE, &(cur_rec_layout->add_hit_left));
+    get_prop_number(cur_node, LAYOUT_KEY_ADD_HIT_RIGHT_ATTRIBUTE, &(cur_rec_layout->add_hit_right));
+    get_prop_number(cur_node, LAYOUT_KEY_ADD_HIT_TOP_ATTRIBUTE, &(cur_rec_layout->add_hit_top));
+    get_prop_number(cur_node, LAYOUT_KEY_ADD_HIT_BOTTOM_ATTRIBUTE, &(cur_rec_layout->add_hit_bottom));
+
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_VIBE_STYLE_ATTRIBUTE);
+    if (key) {
+        cur_rec_layout->vibe_style = (sclchar*)key;
+        add_layout_string(key);
+    }
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_SOUND_STYLE_ATTRIBUTE);
+    if (key) {
+        cur_rec_layout->sound_style = (sclchar*)key;
+        add_layout_string(key);
+    }
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_LABEL_TYPE_ATTRIBUTE);
+    if (key) {
+        cur_rec_layout->label_type = (sclchar*)key;
+        add_layout_string(key);
+    }
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_MODIFIER_DECORATION_ATTRIBUTE);
+    if (key) {
+        cur_rec_layout->modifier_decorator = (sclchar*)key;
+        add_layout_string(key);
+    }
+
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+    while (child_node != NULL) {
+        /* row node: layout coordinate resources is no need to parsing at this time */
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_BACKGROUND_TAG)) {
+            parsing_background(child_node, cur_rec_layout);
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_SW_BACKGROUND_TAG)) {
+            parsing_sw_background_color(child_node, cur_rec_layout);
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_KEY_BACKGROUND_TAG)) {
+            parsing_key_background(child_node, cur_rec_layout);
+        } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)LAYOUT_ADD_GRAB_TAG)) {
+            parsing_grab_area(child_node, cur_rec_layout);
+        }
+
+        child_node = child_node->next;
+    }
+}
+
+void
+LayoutParserImpl::loading_coordinate_resources(
+        const xmlNodePtr cur_node,
+        const PSclLayout cur_rec_layout,
+        int layout_no) {
+    assert(cur_node != NULL);
+
+    int row_y = 0;
+    int sub_layout_height = 0;
+
+    SclLayoutKeyCoordinatePointer *cur_key = NULL;
+
+    if (scl_check_arrindex(layout_no, MAX_SCL_LAYOUT)) {
+        m_num_keys[layout_no] = 0;
+        cur_key = &m_key_coordinate_pointer_frame[layout_no][0];
+    }
+    if (cur_key && *cur_key == NULL) {
+        xmlNodePtr child_node = cur_node->xmlChildrenNode;
+        while (child_node != NULL) {
+            if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_TAG)) {
+                parsing_layout_row_node(child_node, cur_rec_layout, &row_y, &sub_layout_height, &cur_key, layout_no);
+            }
+
+            child_node = child_node->next;
+        }
+    }
+}
+
+void
+LayoutParserImpl::parsing_layout_row_node(
+        const xmlNodePtr cur_node,
+        const PSclLayout cur_rec_layout,
+        int *row_y, int *sub_layout_height,
+        SclLayoutKeyCoordinatePointer **cur_key,
+        int layout_no) {
+    assert(cur_node != NULL);
+
+    Row row = {0};
+    if (row_y) {
+        set_default_row_value(&row, cur_rec_layout, *row_y);
+    }
+
+    get_prop_number(cur_node, LAYOUT_ROW_X_ATTRIBUTE, &(row.row_x));
+    get_prop_number(cur_node, LAYOUT_ROW_Y_ATTRIBUTE, &(row.row_y));
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_WIDTH_ATTRIBUTE, &(row.key_width));
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_HEIGHT_ATTRIBUTE, &(row.key_height));
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_SPACING_ATTRIBUTE, &(row.key_spacing));
+
+    xmlChar *key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_SUBLAYOUT_ID_ATTRIBUTE);
+    if (key) {
+        row.sub_layout = (sclchar*)key;
+        add_key_string(key);
+    }
+
+    if (row.sub_layout == NULL) {
+        if (row_y) {
+            /* If there's a stored sub_layout_height value, add it to current row's y position */
+            if (sub_layout_height) {
+                row.row_y += *sub_layout_height;
+                *sub_layout_height = 0;
+            }
+            *row_y = row.row_y + row.key_height + row.row_spacing;
+        }
+    }
+    /* Store the current row's height for later use when this sublayout is "DEFAULT" */
+    static const char default_sub_layout_string[] = LAYOUT_SUB_LAYOUT_DEFAULT_STRING;
+    if (row.sub_layout && strncmp(row.sub_layout, default_sub_layout_string, sizeof(default_sub_layout_string)) == 0) {
+        if (sub_layout_height) {
+            *sub_layout_height = row.key_height + row.row_spacing;
+        }
+    }
+
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_KEY_TAG)) {
+            if (scl_check_arrindex_unsigned(layout_no, MAX_SCL_LAYOUT) && m_num_keys[layout_no] < MAX_KEY) {
+                parsing_key_coordinate_record_node(child_node, &row, *cur_key, layout_no);
+                (*cur_key)++;
+                m_num_keys[layout_no]++;
+            } else {
+                SCLLOG(SclLog::ERROR, "The number of keys exceeded %d (%d)\n", MAX_KEY, layout_no);
+                return;
+            }
+        }
+        child_node = child_node->next;
+    }
+}
+
+int
+LayoutParserImpl::get_drag_state_prop(const xmlNodePtr cur_node) {
+    assert(cur_node != NULL);
+    typedef struct _Match_Struct {
+        int value;
+        const char* key;
+    }Match_Struct;
+    static Match_Struct table[] = {
+        {SCL_DRAG_STATE_NONE,       "drag_state_none"       },
+        {SCL_DRAG_STATE_LEFT,       "drag_state_left"       },
+        {SCL_DRAG_STATE_RIGHT,      "drag_state_right"      },
+        {SCL_DRAG_STATE_UP,         "drag_state_up"         },
+        {SCL_DRAG_STATE_DOWN,       "drag_state_down"       },
+        {SCL_DRAG_STATE_INVALID,    "drag_state_invalid"    },
+        {SCL_DRAG_STATE_RETURN,     "drag_state_return"     }
+    };
+
+    xmlChar* key = xmlGetProp(cur_node, (const xmlChar*)"drag_state");
+    if (key == NULL) return SCL_DRAG_STATE_NONE;
+
+    int drag_state = SCL_DRAG_STATE_NONE;
+
+    for (size_t i = 0; i < sizeof(table)/sizeof(Match_Struct); ++i) {
+        if (0 == strcmp((const char*)key, table[i].key))
+        {
+            drag_state = table[i].value;
+            break;
+        }
+    }
+
+    xmlFree(key);
+    return drag_state;
+}
+
+int
+LayoutParserImpl::get_shift_state_prop(const xmlNodePtr cur_node) {
+    assert(cur_node != NULL);
+
+    int shift_state = -1;
+
+    if (equal_prop(cur_node, "shift", "on")) {
+        shift_state = SCL_SHIFT_STATE_ON;
+    } else if (equal_prop(cur_node, "shift", "off")) {
+        shift_state = SCL_SHIFT_STATE_OFF;
+    } else if (equal_prop(cur_node, "shift", "loc")) {
+        shift_state = SCL_SHIFT_STATE_LOCK;
+    }
+    return shift_state;
+}
+int
+LayoutParserImpl::get_button_state_prop(const xmlNodePtr cur_node) {
+    assert(cur_node != NULL);
+    int button_state = -1;
+
+    if (equal_prop(cur_node, "button", "pressed")) {
+        button_state = BUTTON_STATE_PRESSED;
+    } else if (equal_prop(cur_node, "button", "normal")) {
+        button_state = BUTTON_STATE_NORMAL;
+    } else if (equal_prop(cur_node, "button", "disabled")) {
+        button_state = BUTTON_STATE_DISABLED;
+    } else if (equal_prop(cur_node, "button", "toggled")) {
+        button_state = BUTTON_STATE_TOGGLED;
+    }
+    return button_state;
+}
+
+int
+LayoutParserImpl::get_multitouch_type_prop(const xmlNodePtr cur_node) {
+    assert(cur_node != NULL);
+    typedef struct _Match_Struct {
+        int value;
+        const char* key;
+    }Match_Struct;
+    static Match_Struct table[] = {
+        {SCL_MULTI_TOUCH_TYPE_EXCLUSIVE,        "exclusive"         },
+        {SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS,  "settle_previous"   },
+        {SCL_MULTI_TOUCH_TYPE_COOPERATIVE,      "cooperative"       },
+        {SCL_MULTI_TOUCH_TYPE_GRAB_SUB_EVENTS,  "grab_sub_events"   },
+    };
+
+    xmlChar* key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_MULTITOUCH_TYPE_ATTRIBUTE);
+    if (key == NULL) return SCL_MULTI_TOUCH_TYPE_EXCLUSIVE;
+
+    int type = SCL_MULTI_TOUCH_TYPE_EXCLUSIVE;
+
+    for (size_t i = 0; i < sizeof(table)/sizeof(Match_Struct); ++i) {
+        if (0 == strcmp((const char*)key, table[i].key))
+        {
+            type = table[i].value;
+            break;
+        }
+    }
+
+    xmlFree(key);
+    return type;
+}
+
+int
+LayoutParserImpl::get_extra_option_prop(
+        const xmlNodePtr cur_node) {
+    assert(cur_node != NULL);
+    typedef struct _Match_Struct {
+        int value;
+        const char* key;
+    }Match_Struct;
+    static Match_Struct table[] = {
+        {DIRECTION_EXTRA_OPTION_4_DIRECTIONS,                        "4-directions"                 },
+        {DIRECTION_EXTRA_OPTION_8_DIRECTIONS,                        "8-directions"                 },
+        {DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_LONG,              "4-directions-long"            },
+        {DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG,              "8-directions-long"            },
+        {DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN,            "4-directions-return"          },
+        {DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN,            "8-directions-return"          },
+        {DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE,  "4-directions-return-curve"    },
+    };
+
+    xmlChar* key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_EXTRA_OPTION_ATTRIBUTE);
+    if (key == NULL) return 0;
+
+    int type = DIRECTION_EXTRA_OPTION_4_DIRECTIONS;
+
+    for (size_t i = 0; i < sizeof(table)/sizeof(Match_Struct); ++i) {
+        if (0 == strcmp((const char*)key, table[i].key))
+        {
+            type = table[i].value;
+            break;
+        }
+    }
+
+    xmlFree(key);
+    return type;
+}
+
+
+void
+LayoutParserImpl::parsing_label_record_node(
+        const xmlNodePtr cur_node,
+        const PSclLayoutKeyCoordinate cur_rec) {
+    assert(cur_node != NULL);
+    assert(cur_rec != NULL);
+    assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"label"));
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"rec")) {
+            int shift_state = get_shift_state_prop(child_node);
+
+            int label_for_one_state = 0;
+            get_prop_number(child_node, "multi", &label_for_one_state);
+            if (cur_rec->label_count < (label_for_one_state + 1)) {
+                cur_rec->label_count = (label_for_one_state + 1);
+            }
+
+            sclboolean auto_upper = FALSE;
+            get_prop_bool(child_node, "auto_upper", &auto_upper);
+
+            if (label_for_one_state >= 0 && label_for_one_state < MAX_SIZE_OF_LABEL_FOR_ONE) {
+                for (int shift_loop = 0;shift_loop < SCL_SHIFT_STATE_MAX;shift_loop++) {
+                    if ((shift_state == shift_loop || shift_state == -1)) {
+                        xmlChar* key = xmlNodeGetContent(child_node);
+                        if (key) {
+                            sclboolean upper_created = FALSE;
+                            if (auto_upper) {
+                                if (shift_loop != SCL_SHIFT_STATE_OFF) {
+                                    gchar *upper = g_utf8_strup(reinterpret_cast<gchar*>(key), -1);
+                                    xmlFree(key);
+                                    add_upper_string(upper);
+                                    upper_created = TRUE;
+                                    key = reinterpret_cast<xmlChar*>(upper);
+                                }
+                            }
+                            if (!upper_created) {
+                                add_key_string(key);
+                            }
+                            cur_rec->label[shift_loop][label_for_one_state] = (sclchar*)key;
+                            /* If current key_value is NULL, let's just consider this label is the default key_value */
+                            if (label_for_one_state == 0) {
+                                if (cur_rec->key_value[shift_loop][label_for_one_state] == NULL) {
+                                    cur_rec->key_value[shift_loop][label_for_one_state] = (sclchar*)key;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        child_node = child_node->next;
+    }
+}
+
+void
+LayoutParserImpl::parsing_magnifier_label_record_node(
+        const xmlNodePtr cur_node,
+        const PSclLayoutKeyCoordinate cur_rec) {
+    assert(cur_node != NULL);
+    assert(cur_rec != NULL);
+    assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"magnifier_label"));
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"rec")) {
+            int shift_state = get_shift_state_prop(child_node);
+
+            int label_for_one_state = 0;
+            get_prop_number(child_node, "multi", &label_for_one_state);
+
+            if (label_for_one_state >= 0 && label_for_one_state < MAX_SIZE_OF_LABEL_FOR_ONE) {
+                for (int shift_loop = 0;shift_loop < SCL_SHIFT_STATE_MAX;shift_loop++) {
+                    if ((shift_state == shift_loop || shift_state == -1)) {
+                        xmlChar* key = xmlNodeGetContent(child_node);
+                        if (key) {
+                            cur_rec->magnifier_label[shift_loop][label_for_one_state] = (sclchar*)key;
+                            add_key_string(key);
+                        }
+                    }
+                }
+            }
+        }
+        child_node = child_node->next;
+    }
+}
+
+void
+LayoutParserImpl::parsing_hint_string_record_node(
+    const xmlNodePtr cur_node,
+    const PSclLayoutKeyCoordinate cur_rec) {
+        assert(cur_node != NULL);
+        assert(cur_rec != NULL);
+        assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"hint_string"));
+        xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+        while (child_node != NULL) {
+            if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"rec")) {
+                int shift_state = get_shift_state_prop(child_node);
+                int multichar_state = 0;
+                get_prop_number(child_node, "multichar_state", &multichar_state);
+
+                if (multichar_state >= 0 && multichar_state < MAX_SIZE_OF_MULTITAP_CHAR) {
+                    for (int shift_loop = 0;shift_loop < SCL_SHIFT_STATE_MAX;shift_loop++) {
+                        if ((shift_state == shift_loop || shift_state == -1)) {
+                            xmlChar* key = xmlNodeGetContent(child_node);
+                            if (key) {
+                                cur_rec->hint_string[shift_loop][multichar_state] = (sclchar*)key;
+                                add_key_string(key);
+                            }
+                        }
+                    }
+                }
+            }
+            child_node = child_node->next;
+        }
+}
+
+void
+LayoutParserImpl::parsing_label_image_record_node(
+        const xmlNodePtr cur_node,
+        const PSclLayoutKeyCoordinate cur_rec) {
+    assert(cur_node != NULL);
+    assert(cur_rec != NULL);
+    assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"image_label"));
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"rec")) {
+            int shift_state = get_shift_state_prop(child_node);
+            int button_state = get_button_state_prop(child_node);
+            for (int shift_loop = 0;shift_loop < SCL_SHIFT_STATE_MAX;shift_loop++) {
+                for (int button_loop = 0;button_loop < SCL_BUTTON_STATE_MAX;button_loop++) {
+                    if ((shift_state == shift_loop || shift_state == -1) &&
+                        (button_state == button_loop || button_state == -1)) {
+                            xmlChar* key = xmlNodeGetContent(child_node);
+                            if (key) {
+                                cur_rec->image_label_path[shift_loop][button_loop] = (sclchar*)key;
+                                add_key_string(key);
+                            }
+                    }
+                }
+            }
+        }
+        child_node = child_node->next;
+    }
+}
+
+void
+LayoutParserImpl::parsing_background_image_record_node(
+        const xmlNodePtr cur_node,
+        const PSclLayoutKeyCoordinate cur_rec) {
+    assert(cur_node != NULL);
+    assert(cur_rec != NULL);
+    assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"background_image"));
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"rec")) {
+            int shift_state = get_shift_state_prop(child_node);
+            int button_state = get_button_state_prop(child_node);
+            for (int shift_loop = 0;shift_loop < SCL_SHIFT_STATE_MAX;shift_loop++) {
+                for (int button_loop = 0;button_loop < SCL_BUTTON_STATE_MAX;button_loop++) {
+                    if ((shift_state == shift_loop || shift_state == -1) &&
+                        (button_state == button_loop || button_state == -1)) {
+                            xmlChar* key = xmlNodeGetContent(child_node);
+                            if (key) {
+                                cur_rec->bg_image_path[shift_loop][button_loop] = (sclchar*)key;
+                                add_key_string(key);
+                            }
+                    }
+                }
+            }
+        }
+        child_node = child_node->next;
+    }
+}
+
+void
+LayoutParserImpl::parsing_key_value_record_node(
+        const xmlNodePtr cur_node,
+        const PSclLayoutKeyCoordinate cur_rec) {
+    assert(cur_node != NULL);
+    assert(cur_rec != NULL);
+    assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"key_value"));
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"rec")) {
+            int shift_state = get_shift_state_prop(child_node);
+            int multichar_state = 0;
+            get_prop_number(child_node, "multichar_state", &multichar_state);
+
+            sclboolean auto_upper = FALSE;
+            get_prop_bool(child_node, "auto_upper", &auto_upper);
+
+            if (multichar_state >= 0 && multichar_state < MAX_SIZE_OF_MULTITAP_CHAR) {
+                for (int shift_loop = 0;shift_loop < SCL_SHIFT_STATE_MAX;shift_loop++) {
+                    if ((shift_state == shift_loop || shift_state == -1)) {
+                        xmlChar* key = xmlNodeGetContent(child_node);
+                        if (key) {
+                            sclboolean upper_created = FALSE;
+                            if (auto_upper) {
+                                if (shift_loop != SCL_SHIFT_STATE_OFF) {
+                                    gchar *upper = g_utf8_strup(reinterpret_cast<gchar*>(key), -1);
+                                    xmlFree(key);
+                                    add_upper_string(upper);
+                                    upper_created = TRUE;
+                                    key = reinterpret_cast<xmlChar*>(upper);
+                                }
+                            }
+                            if (!upper_created) {
+                                add_key_string(key);
+                            }
+                            cur_rec->key_value[shift_loop][multichar_state] = (sclchar*)key;
+                        }
+                    }
+                }
+            }
+        }
+        child_node = child_node->next;
+    }
+}
+
+void
+LayoutParserImpl::parsing_key_event_record_node(
+        const xmlNodePtr cur_node,
+        const PSclLayoutKeyCoordinate cur_rec) {
+    assert(cur_node != NULL);
+    assert(cur_rec != NULL);
+    assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"key_event"));
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"rec")) {
+            int shift_state = get_shift_state_prop(child_node);
+            int multichar_state = 0;
+            get_prop_number(child_node, "multichar_state", &multichar_state);
+
+            if (multichar_state >= 0 && multichar_state < MAX_SIZE_OF_MULTITAP_CHAR) {
+                for (int shift_loop = 0;shift_loop < SCL_SHIFT_STATE_MAX;shift_loop++) {
+                    if ((shift_state == shift_loop || shift_state == -1)) {
+                        cur_rec->key_event[shift_loop][multichar_state] = (sclulong)get_content_dex_string_int(child_node);
+                    }
+                }
+            }
+        }
+        child_node = child_node->next;
+    }
+}
+
+void
+LayoutParserImpl::parsing_auto_popup_keys_record_node(
+        const xmlNodePtr cur_node,
+        const PSclLayoutKeyCoordinate cur_rec) {
+    assert(cur_node != NULL);
+    assert(cur_rec != NULL);
+    assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"auto_popup_keys"));
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+    while (child_node != NULL) {
+        int shift_state = get_shift_state_prop(child_node);
+        int autopopup_state = 0;
+        get_prop_number(child_node, "autopopup", &autopopup_state);
+
+        sclboolean auto_upper = FALSE;
+        get_prop_bool(child_node, "auto_upper", &auto_upper);
+
+        if (autopopup_state >= 0 && autopopup_state < MAX_SIZE_OF_AUTOPOPUP_STRING) {
+            for (int shift_loop = 0;shift_loop < SCL_SHIFT_STATE_MAX;shift_loop++) {
+                if ((shift_state == shift_loop || shift_state == -1)) {
+                    xmlChar* key = xmlNodeGetContent(child_node);
+                    sclboolean need_free = TRUE;
+                    if (key) {
+                        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"label")) {
+                            sclboolean upper_created = FALSE;
+                            if (auto_upper) {
+                                if (shift_loop != SCL_SHIFT_STATE_OFF) {
+                                    gchar *upper = g_utf8_strup(reinterpret_cast<gchar*>(key), -1);
+                                    xmlFree(key);
+                                    add_upper_string(upper);
+                                    upper_created = TRUE;
+                                    key = reinterpret_cast<xmlChar*>(upper);
+                                    need_free = FALSE;
+                                }
+                            }
+                            if (!upper_created) {
+                                add_key_string(key);
+                                need_free = FALSE;
+                            }
+                            cur_rec->autopopup_key_labels[shift_loop][autopopup_state] = (sclchar*)key;
+                            /* If current key_value is NULL, let's just consider this label is the default key_value */
+                            if (cur_rec->autopopup_key_values[shift_loop][autopopup_state] == NULL) {
+                                cur_rec->autopopup_key_values[shift_loop][autopopup_state] = (sclchar*)key;
+                            }
+                        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"value")) {
+                            cur_rec->autopopup_key_values[shift_loop][autopopup_state] = (sclchar*)key;
+                            add_key_string(key);
+                            need_free = FALSE;
+                        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"event")) {
+                            cur_rec->autopopup_key_events[shift_loop][autopopup_state] = (sclulong)atoi((sclchar*)key);
+                            add_key_string(key);
+                            need_free = FALSE;
+                        }
+                        if (need_free) {
+                            xmlFree(key);
+                        }
+                    }
+                }
+            }
+        }
+        child_node = child_node->next;
+    }
+}
+
+void
+LayoutParserImpl::parsing_key_coordinate_record_node(
+        const xmlNodePtr cur_node, Row *row,
+        SclLayoutKeyCoordinatePointer *cur_rec_coordinate,
+        int layout_no) {
+    assert(cur_node != NULL);
+    assert(cur_rec_coordinate != NULL);
+
+    if (scl_check_arrindex_unsigned(layout_no, MAX_SCL_LAYOUT) && m_num_keys[layout_no] >= MAX_KEY) {
+        SCLLOG(SclLog::ERROR, "The number of keys exceeded %d (%d)\n", MAX_KEY, layout_no);
+        return;
+    }
+    *cur_rec_coordinate = (SclLayoutKeyCoordinatePointer)malloc(sizeof(SclLayoutKeyCoordinate));
+    if (*cur_rec_coordinate == NULL) {
+        SCLLOG(SclLog::ERROR, "LayoutParserImpl: memory malloc eror.\n");
+        return;
+    }
+    memset(*cur_rec_coordinate, 0x00, sizeof(SclLayoutKeyCoordinate));
+
+    set_default_key_coordinate_value(*cur_rec_coordinate, row);
+
+    xmlChar *key;
+
+    int key_spacing = 0;
+
+    if (row) {
+        key_spacing = row->key_spacing;
+    }
+
+    (*cur_rec_coordinate)->valid = TRUE;
+
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_CUSTOMID_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->custom_id = (sclchar*)key;
+        add_key_string(key);
+    }
+
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_BUTTON_TYPE_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->button_type = (SCLButtonType)ButtonTypeHelper::Int((const char*)key);
+        xmlFree(key);
+    }
+
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_KEY_TYPE_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->key_type = (SCLKeyType)KeyTypeHelper::Int((const char*)key);
+        xmlFree(key);
+    }
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_POPUP_TYPE_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->popup_type = (SCLPopupType)PopupTypeHelper::Int((const char*)key);
+        xmlFree(key);
+    }
+
+    get_prop_bool(cur_node, LAYOUT_ROW_KEY_MAGNIFIER_ATTRIBUTE, &((*cur_rec_coordinate)->use_magnifier));
+    get_prop_bool(cur_node, LAYOUT_ROW_KEY_LONGKEY_MAGNIFIER_ATTRIBUTE,
+        &((*cur_rec_coordinate)->use_long_key_magnifier));
+
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_VIBE_STYLE_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->vibe_style = (sclchar*)key;
+        add_key_string(key);
+    }
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_SOUND_STYLE_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->sound_style = (sclchar*)key;
+        add_key_string(key);
+    }
+
+    get_prop_bool(cur_node, LAYOUT_ROW_KEY_SIDE_BUTTON_ATTRIBUTE, &((*cur_rec_coordinate)->is_side_button));
+
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_X_ATTRIBUTE, &((*cur_rec_coordinate)->x));
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_Y_ATTRIBUTE, &((*cur_rec_coordinate)->y));
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_KEY_WIDTH_ATTRIBUTE, &((*cur_rec_coordinate)->width));
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_KEY_HEIGHT_ATTRIBUTE, &((*cur_rec_coordinate)->height));
+
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_ADD_HIT_LEFT_ATTRIBUTE, &((*cur_rec_coordinate)->add_hit_left));
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_ADD_HIT_RIGHT_ATTRIBUTE, &((*cur_rec_coordinate)->add_hit_right));
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_ADD_HIT_TOP_ATTRIBUTE, &((*cur_rec_coordinate)->add_hit_top));
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_ADD_HIT_BOTTOM_ATTRIBUTE, &((*cur_rec_coordinate)->add_hit_bottom));
+
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_POPUP_POS_X_ATTRIBUTE, &((*cur_rec_coordinate)->popup_relative_x));
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_POPUP_POS_Y_ATTRIBUTE, &((*cur_rec_coordinate)->popup_relative_y));
+
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_POPUP_IMAGE_X_ATTRIBUTE, &((*cur_rec_coordinate)->extract_offset_x));
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_POPUP_IMAGE_Y_ATTRIBUTE, &((*cur_rec_coordinate)->extract_offset_y));
+
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_LONGKEY_TYPE_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->long_key_type = (SCLKeyType)KeyTypeHelper::Int((const char*)key);
+        xmlFree(key);
+    } else {
+        /* assume the long_key_type is the same with key_type, by default */
+        (*cur_rec_coordinate)->long_key_type = (*cur_rec_coordinate)->key_type;
+    }
+
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_LONGKEY_VALUE_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->long_key_value = (sclchar*)key;
+        add_key_string(key);
+    }
+
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_LONGKEY_EVENT_ATTRIBUTE, &((*cur_rec_coordinate)->long_key_event));
+
+    get_prop_bool(cur_node, LAYOUT_ROW_KEY_USE_REPEAT_KEY_ATTRIBUTE, &((*cur_rec_coordinate)->use_repeat_key));
+    get_prop_bool(cur_node, LAYOUT_ROW_KEY_DONOT_CLOSE_POPUP_ATTRIBUTE, &((*cur_rec_coordinate)->dont_close_popup));
+
+    (*cur_rec_coordinate)->extra_option = get_extra_option_prop(cur_node);
+    (*cur_rec_coordinate)->multitouch_type = get_multitouch_type_prop(cur_node);
+
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_SUBLAYOUT_ID_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->sub_layout = (sclchar*)key;
+        add_key_string(key);
+    }
+
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_LABEL_TYPE_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->label_type = (sclchar*)key;
+        add_key_string(key);
+    }
+
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_IMAGE_LABEL_TYPE_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->image_label_type = (sclchar*)key;
+        add_key_string(key);
+    }
+
+    key = xmlGetProp(cur_node, (const xmlChar*)LAYOUT_ROW_KEY_MODIFIER_DECORATION_ID_ATTRIBUTE);
+    if (key) {
+        (*cur_rec_coordinate)->modifier_decorator = (sclchar*)key;
+        add_key_string(key);
+    }
+
+    get_prop_number(cur_node, LAYOUT_ROW_KEY_KEY_SPACING_ATTRIBUTE, &key_spacing);
+
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_KEY_LABEL_TAG)) {
+            parsing_label_record_node(child_node, (*cur_rec_coordinate));
+            (*cur_rec_coordinate)->valid = TRUE;
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_KEY_IMAGE_LABEL_TAG)) {
+            parsing_label_image_record_node(child_node, (*cur_rec_coordinate));
+            (*cur_rec_coordinate)->valid = TRUE;
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_KEY_BACKGROUND_IMAGE_TAG)) {
+            parsing_background_image_record_node(child_node, (*cur_rec_coordinate));
+            (*cur_rec_coordinate)->valid = TRUE;
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_KEY_KEY_VALUE_TAG)) {
+            parsing_key_value_record_node(child_node, (*cur_rec_coordinate));
+            (*cur_rec_coordinate)->valid = TRUE;
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_KEY_KEY_EVENT_TAG)) {
+            parsing_key_event_record_node(child_node, (*cur_rec_coordinate));
+            (*cur_rec_coordinate)->valid = TRUE;
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_KEY_AUTOPOPUP_KEYS_TAG)) {
+            parsing_auto_popup_keys_record_node(child_node, (*cur_rec_coordinate));
+            (*cur_rec_coordinate)->valid = TRUE;
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_KEY_POPUP_INPUTMODE_RECORD_TAG)) {
+            parsing_popup_input_mode_record_node(child_node, (*cur_rec_coordinate));
+            (*cur_rec_coordinate)->valid = TRUE;
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_KEY_MAGNIFIER_LABEL_TAG)) {
+            parsing_magnifier_label_record_node(child_node, (*cur_rec_coordinate));
+            (*cur_rec_coordinate)->valid = TRUE;
+        } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_KEY_HINT_STRING_TAG)) {
+            parsing_hint_string_record_node(child_node, (*cur_rec_coordinate));
+            (*cur_rec_coordinate)->valid = TRUE;
+        }
+
+        child_node = child_node->next;
+    }
+
+    if (row) {
+        row->row_x = (*cur_rec_coordinate)->x + (*cur_rec_coordinate)->width + key_spacing;
+    }
+}
+
+void
+LayoutParserImpl::parsing_popup_input_mode_record_node(
+        const xmlNodePtr cur_node,
+        const PSclLayoutKeyCoordinate cur_rec) {
+    assert(cur_node != NULL);
+    assert(cur_rec != NULL);
+    assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)LAYOUT_ROW_KEY_POPUP_INPUTMODE_RECORD_TAG));
+    xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+    while (child_node != NULL) {
+        if (0 == xmlStrcmp(child_node->name, (const xmlChar*)LAYOUT_ROW_KEY_POPUP_INPUTMODE_RECORD_INPUTMODE_TAG)) {
+            int drag_state = get_drag_state_prop(child_node);
+            assert(drag_state >=0);
+            assert(drag_state < SCL_DRAG_STATE_MAX);
+            xmlChar* key = xmlNodeGetContent(child_node);
+
+            if (key) {
+                cur_rec->popup_input_mode[drag_state] = (sclchar*)key;
+                add_key_string(key);
+            }
+        }
+        child_node = child_node->next;
+    }
+}
+
+LayoutParser::LayoutParser() {
+    m_impl = new LayoutParserImpl;
+}
+LayoutParser::~LayoutParser() {
+    SCLLOG(SclLog::MESSAGE, "~LayoutParser() has called");
+    delete m_impl;
+    m_impl = NULL;
+}
+
+LayoutParser*
+LayoutParser::get_instance() {
+    static LayoutParser instance;
+    return &instance;
+}
+
+int
+LayoutParser::init(const char* dir, const vector<string> &vec_file) {
+    int ret = -1;
+    if (dir) {
+        m_impl->set_directory(dir);
+        ret = m_impl->parsing_layout_table(vec_file);
+    }
+
+    return ret;
+}
+
+int
+LayoutParser::reload(const char* dir, const vector<string> &vec_file) {
+    int ret = -1;
+    if (dir) {
+        m_impl->set_directory(dir);
+        m_impl->unload();
+        ret = m_impl->reload_layout_table(vec_file);
+    }
+
+    return ret;
+}
+
+void
+LayoutParser::load(int layout_id) {
+    m_impl->load(layout_id);
+}
+
+bool
+LayoutParser::loaded(int layout_id) {
+    return m_impl->loaded(layout_id);
+}
+
+void
+LayoutParser::unload() {
+    m_impl->unload();
+}
+
+int
+LayoutParser::get_layout_index(const char *name) {
+    return m_impl->get_layout_index(name);
+}
+
+int
+LayoutParser::get_layout_size() {
+    return m_impl->get_layout_size();
+}
+
+PSclLayout
+LayoutParser::get_layout_table() {
+    return m_impl->get_layout_table();
+}
+
+PSclLayoutKeyCoordinatePointerTable
+LayoutParser::get_key_coordinate_pointer_frame() {
+    return m_impl->get_key_coordinate_pointer_frame();
+}
diff --git a/scl/layout_parser.h b/scl/layout_parser.h
new file mode 100644 (file)
index 0000000..7d067aa
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 - 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 __LAYOUT_PARSER__H__
+#define __LAYOUT_PARSER__H__
+
+#include "sclres_type.h"
+#include <vector>
+
+class LayoutParserImpl;
+
+class LayoutParser {
+    LayoutParserImpl *m_impl;
+    public:
+    ~LayoutParser();
+    static LayoutParser *get_instance();
+    int init(const char *dir,
+        const std::vector<std::string> &vec_layout_file_name);
+    int reload(const char *dir,
+        const std::vector<std::string> &vec_layout_file_name);
+
+    void load(int layout_id);
+    void unload();
+    bool loaded(int layout_id);
+
+    int get_layout_index(const char *name);
+    int get_layout_size();
+    PSclLayout get_layout_table();
+    PSclLayoutKeyCoordinatePointerTable get_key_coordinate_pointer_frame();
+
+    private:
+    LayoutParser();
+};
+
+
+#endif
diff --git a/scl/layout_parser_helper.cpp b/scl/layout_parser_helper.cpp
new file mode 100644 (file)
index 0000000..4addf8d
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2012 - 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 "layout_parser_helper.h"
+#include <stdio.h>
+#include <string>
+#include <sstream>
+using namespace std;
+
+const string RotationHelper::pcPortrait = "portrait";
+const string RotationHelper::pcLandscape = "landscape";
+
+const string RotationHelper::toString(const int val) {
+    switch (val) {
+        case PORTRAIT:
+            return pcPortrait;
+        case LANDSCAPE:
+            return pcLandscape;
+        default:
+            return pcLandscape;
+    }
+}
+int RotationHelper::Int(const string str) {
+    if (str ==  pcPortrait) {
+        return PORTRAIT;
+    } else if (str ==  pcLandscape) {
+        return LANDSCAPE;
+    } else {
+        return PORTRAIT;
+    }
+}
+
+////////////////////////////////////////////////////////////
+const string PopStyleHelper::pcBase = "base";
+const string PopStyleHelper::pcPopup = "popup";
+const string PopStyleHelper::pcPopup_Grab = "popup_grab";
+const string PopStyleHelper::toString(const int val) {
+    switch (val) {
+        case BASE:
+            return pcBase;
+        case POPUP:
+            return pcPopup;
+        case POPUP_GRAB:
+            return pcPopup_Grab;
+        default:
+            return pcBase;
+    }
+}
+
+int PopStyleHelper::Int(const string str) {
+    if (str ==  pcBase) {
+        return BASE;
+    } else if (str ==  pcPopup) {
+        return POPUP;
+    } else if (str ==  pcPopup_Grab) {
+        return POPUP_GRAB;
+    } else {
+        return BASE;
+    }
+}
+
+///////////////////////////////////////////////////////
+
+const string ButtonTypeHelper::pcNormal = "normal";
+const string ButtonTypeHelper::pcGrab = "grab";
+const string ButtonTypeHelper::pcSelfish = "selfish";
+const string ButtonTypeHelper::pcDrag = "drag";
+const string ButtonTypeHelper::pcMultitap = "multitap";
+const string ButtonTypeHelper::pcRotation = "rotation";
+const string ButtonTypeHelper::pcDirection = "direction";
+const string ButtonTypeHelper::pcRelative_Direction = "relative_direction";
+const string ButtonTypeHelper::pcToggle = "toggle";
+const string ButtonTypeHelper::pcUiitem = "uiitem";
+
+const string ButtonTypeHelper::toString(const int val) {
+    switch (val) {
+        case NORMAL:
+            return pcNormal;
+        case GRAB:
+            return pcGrab;
+        case SELFISH:
+            return pcSelfish;
+        case DRAG:
+            return pcDrag;
+        case MULTITAP:
+            return pcMultitap;
+        case ROTATION:
+            return pcRotation;
+        case DIRECTION:
+            return pcDirection;
+        case RELATIVE_DIRECTION:
+            return pcRelative_Direction;
+        case UIITEM:
+            return pcUiitem;
+        default:
+            return pcNormal;
+    }
+}
+
+int ButtonTypeHelper::Int(const string str) {
+    if (str ==  pcNormal) {
+        return NORMAL;
+    } else if (str ==  pcGrab) {
+        return GRAB;
+    } else if (str ==  pcSelfish) {
+        return SELFISH;
+    } else if (str ==  pcDrag) {
+        return DRAG;
+    } else if (str ==  pcMultitap) {
+        return MULTITAP;
+    } else if (str ==  pcRotation) {
+        return ROTATION;
+    } else if (str ==  pcDirection) {
+        return DIRECTION;
+    } else if (str ==  pcRelative_Direction) {
+        return RELATIVE_DIRECTION;
+    } else if (str ==  pcToggle) {
+        return TOGGLE;
+    } else if (str ==  pcUiitem) {
+        return UIITEM;
+    } else {
+        return NORMAL;
+    }
+}
+////////////////////////////////////////////////////
+const string ShiftStateHelper::pcOn = "on";
+const string ShiftStateHelper::pcOff = "off";
+const string ShiftStateHelper::pcLoc = "loc";
+
+const string ShiftStateHelper::toString(const int val) {
+    switch (val) {
+        case ON:
+            return pcOn;
+        case OFF:
+            return pcOff;
+        case LOC:
+            return pcLoc;
+        default:
+            return pcOn;
+    }
+}
+
+int ShiftStateHelper::Int(const string str) {
+    if (str ==  pcOn) {
+        return ON;
+    } else if (str ==  pcOff) {
+        return OFF;
+    } else if (str ==  pcLoc) {
+        return LOC;
+    } else {
+        return ON;
+    }
+}
+/////////////////////////////////////////////////////////
+const string ButtonStateHelper::pcNormal = "normal";
+const string ButtonStateHelper::pcPressed = "pressed";
+const string ButtonStateHelper::pcDisabled = "disabled";
+const string ButtonStateHelper::toString(const int val) {
+    switch (val) {
+        case NORMAL:
+            return pcNormal;
+        case PRESSED:
+            return pcPressed;
+        case DISABLED:
+            return pcDisabled;
+        default:
+            return pcNormal;
+    }
+}
+int ButtonStateHelper::Int(const string str) {
+    if (str ==  pcNormal) {
+        return NORMAL;
+    } else if (str ==  pcPressed) {
+        return PRESSED;
+    } else if (str ==  pcDisabled) {
+        return DISABLED;
+    } else {
+        return NORMAL;
+    }
+}
+///////////////////////////////////////////////////
+const string KeyTypeHelper::pcNone = "none";
+const string KeyTypeHelper::pcChar = "char";
+const string KeyTypeHelper::pcControl = "control";
+const string KeyTypeHelper::pcModechange = "modechange";
+const string KeyTypeHelper::pcString = "string";
+const string KeyTypeHelper::pcUser = "user";
+const string KeyTypeHelper::toString(const int val) {
+    switch (val) {
+        case NONE:
+            return pcNone;
+        case CHAR:
+            return pcChar;
+        case CONTROL:
+            return pcControl;
+        case MODECHANGE:
+            return pcModechange;
+        case STRING:
+            return pcString;
+        case USER:
+            return pcUser;
+        default:
+            return pcNone;
+    }
+}
+
+int KeyTypeHelper::Int(const string str) {
+    if (str ==  pcNone) {
+        return NONE;
+    } else if (str ==  pcChar) {
+        return CHAR;
+    } else if (str ==  pcControl) {
+        return CONTROL;
+    } else if (str ==  pcModechange) {
+        return MODECHANGE;
+    } else if (str ==  pcString) {
+        return STRING;
+    } else if (str ==  pcUser) {
+        return USER;
+    } else {
+        return NONE;
+    }
+}
+/////////////////////////////////////////////////////////
+const string PopupTypeHelper::pcNone = "none";
+const string PopupTypeHelper::pcBtn_Release_Popup = "release_popup";
+const string PopupTypeHelper::pcBtn_Release_Popup_Once = "release_popup_once";
+const string PopupTypeHelper::pcBtn_Press_Popup_Drag = "press_popup_drag";
+const string PopupTypeHelper::pcLongpress_Popup = "longpress_popup";
+const string PopupTypeHelper::pcLongpress_Popup_Once = "longpress_popup_once";
+const string PopupTypeHelper::pcAuto_Popup = "auto_popup";
+
+const string PopupTypeHelper::toString(const int val) {
+    switch (val) {
+        case NONE:
+            return pcNone;
+        case BTN_RELEASE_POPUP:
+            return pcBtn_Release_Popup;
+        case BTN_RELEASE_POPUP_ONCE:
+            return pcBtn_Release_Popup_Once;
+        case BTN_PRESS_POPUP_DRAG:
+            return pcBtn_Press_Popup_Drag;
+        case LONGPRESS_POPUP:
+            return pcLongpress_Popup;
+        case LONGPRESS_POPUP_ONCE:
+            return pcLongpress_Popup_Once;
+        case AUTO_POPUP:
+            return pcAuto_Popup;
+        default:
+            return pcNone;
+    }
+}
+int PopupTypeHelper::Int(const string str) {
+    if (str ==  pcNone) {
+        return NONE;
+    } else if (str ==  pcBtn_Release_Popup) {
+        return BTN_RELEASE_POPUP;
+    } else if (str ==  pcBtn_Release_Popup_Once) {
+        return BTN_RELEASE_POPUP_ONCE;
+    } else if (str ==  pcBtn_Press_Popup_Drag) {
+        return BTN_PRESS_POPUP_DRAG;
+    } else if (str ==  pcLongpress_Popup) {
+        return LONGPRESS_POPUP;
+    } else if (str ==  pcLongpress_Popup_Once) {
+        return LONGPRESS_POPUP_ONCE;
+    } else if (str ==  pcAuto_Popup) {
+        return AUTO_POPUP;
+    } else {
+        return NONE;
+    }
+}
+////////////////////////////////////////////////////////
+const string DragStateHelper::pcNone = "none";
+const string DragStateHelper::pcLeft = "left";
+const string DragStateHelper::pcRight = "right";
+const string DragStateHelper::pcUp = "up";
+const string DragStateHelper::pcDown = "down";
+const string DragStateHelper::pcInvalid = "invalid";
+const string DragStateHelper::pcReturn = "return";
+
+const string DragStateHelper::toString(const int val) {
+    switch (val) {
+        case NONE:
+            return pcNone;
+        case LEFT:
+            return pcLeft;
+        case RIGHT:
+            return pcRight;
+        case UP:
+            return pcUp;
+        case DOWN:
+            return pcDown;
+        case INVALID:
+            return pcInvalid;
+        case RETURN:
+            return pcReturn;
+        default:
+            return pcNone;
+    }
+}
+
+int DragStateHelper::Int(const string str) {
+    if (str ==  pcNone) {
+        return NONE;
+    } else if (str ==  pcLeft) {
+        return LEFT;
+    } else if (str ==  pcRight) {
+        return RIGHT;
+    } else if (str ==  pcUp) {
+        return UP;
+    } else if (str ==  pcDown) {
+        return DOWN;
+    } else if (str ==  pcInvalid) {
+        return INVALID;
+    } else if (str ==  pcReturn) {
+        return RETURN;
+    } else {
+        return NONE;
+    }
+}
+/////////////////////////////////////////////////////////////
+const string ExtraOptionHelper::pcOption_4_directions = "4-directions";
+const string ExtraOptionHelper::pcOption_8_directions = "8-directions";
+const string ExtraOptionHelper::pcOption_4_directions_long = "4-directions-long";
+const string ExtraOptionHelper::pcOption_8_directions_long = "8-directions-long";
+const string ExtraOptionHelper::pcOption_4_directions_return = "4-directions-return";
+const string ExtraOptionHelper::pcOption_8_directions_return = "8-directions-return";
+const string ExtraOptionHelper::pcOption_4_directions_return_curve = "4-directions-return-curve";
+
+const string ExtraOptionHelper::toString(const int val) {
+    switch (val) {
+        case OPTION_4_DIRECTIONS:
+            return pcOption_4_directions;
+        case OPTION_8_DIRECTIONS:
+            return pcOption_8_directions;
+        case OPTION_4_DIRECTIONS_LONG:
+            return pcOption_4_directions_long;
+        case OPTION_8_DIRECTIONS_LONG:
+            return pcOption_8_directions_long;
+        case OPTION_4_DIRECTIONS_RETURN:
+            return pcOption_4_directions_return;
+        case OPTION_8_DIRECTIONS_RETURN:
+            return pcOption_8_directions_return;
+        case OPTION_4_DIRECTIONS_RETURN_CURVE:
+            return pcOption_4_directions_return_curve;
+        default:
+            return pcOption_4_directions;
+    }
+}
+int ExtraOptionHelper::Int(const string str) {
+    if (str ==  pcOption_4_directions) {
+        return OPTION_4_DIRECTIONS;
+    } else if (str ==  pcOption_8_directions) {
+        return OPTION_8_DIRECTIONS;
+    } else if (str ==  pcOption_4_directions_long) {
+        return OPTION_4_DIRECTIONS_LONG;
+    } else if (str ==  pcOption_8_directions_long) {
+        return OPTION_8_DIRECTIONS_LONG;
+    } else if (str ==  pcOption_4_directions_return) {
+        return OPTION_4_DIRECTIONS_RETURN;
+    } else if (str ==  pcOption_8_directions_return) {
+        return OPTION_8_DIRECTIONS_RETURN;
+    } else if (str ==  pcOption_4_directions_return_curve) {
+        return OPTION_4_DIRECTIONS_RETURN_CURVE;
+    } else {
+        return OPTION_4_DIRECTIONS;
+    }
+}
+/////////////////////////////////////////////////////////////////////////////
+const string MultitouchTypeHelper::pcExclusive = "exclusive";
+const string MultitouchTypeHelper::pcCooperative = "cooperative";
+const string MultitouchTypeHelper::pcGrab_Sub_Events = "grab_sub_events";
+
+const string MultitouchTypeHelper::toString(const int val) {
+    switch (val) {
+        case EXCLUSIVE:
+            return pcExclusive;
+        case COOPERATIVE:
+            return pcCooperative;
+        case GRAB_SUB_EVENTS:
+            return pcGrab_Sub_Events;
+        default:
+            return pcExclusive;
+    }
+}
+int MultitouchTypeHelper::Int(const string str) {
+    if (str ==  pcExclusive) {
+        return EXCLUSIVE;
+    } else if (str ==  pcCooperative) {
+        return COOPERATIVE;
+    } else if (str ==  pcGrab_Sub_Events) {
+        return GRAB_SUB_EVENTS;
+    } else {
+        return EXCLUSIVE;
+    }
+}
+////////////////////////////////////////////////////
+const string BOOLTypeHelper::pcTrue = "true";
+const string BOOLTypeHelper::pcFalse = "false";
+
+const string BOOLTypeHelper::toString(const bool val) {
+    if (val) return pcTrue;
+    return pcFalse;
+}
+int BOOLTypeHelper::Bool(const string str) {
+    if (str ==  pcFalse) {
+        return false;
+    } else if (str ==  pcTrue) {
+        return true;
+    } else {
+        return false;
+    }
+}
+/////////////////////////////////////////////////
+const string INTTypeHelper::dextoString(const int val) {
+    char temp[8] = {0};
+    snprintf(temp, sizeof(temp), "0x%x", val);
+    return string(temp);
+}
+const string INTTypeHelper::toString(const int val) {
+    char temp[8] = {0};
+    snprintf(temp, sizeof(temp), "%d", val);
+    return string(temp);
+}
+int INTTypeHelper::Int(const string str) {
+    int val = 0;
+    stringstream convertor(str);
+
+    convertor >> val;
+    if (convertor.fail() == true) {
+        val = 0;
+    }
+
+    return val;
+}
+int INTTypeHelper::dexInt(const string str) {
+    int val = 0;
+    stringstream convertor(str);
+
+    convertor >> hex >> val;
+    if (convertor.fail() == true) {
+        val = 0;
+    }
+    return val;
+}
diff --git a/scl/layout_parser_helper.h b/scl/layout_parser_helper.h
new file mode 100644 (file)
index 0000000..e928af3
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2012 - 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 __KEYSET_ATTR_HELPER__H__
+#define __KEYSET_ATTR_HELPER__H__
+#include <string>
+
+class RotationHelper{
+    public:
+        static const int PORTRAIT = 0;
+        static const int LANDSCAPE = 1;
+        static const int MAX = 2;
+        static const int DEFAULT = 0;
+
+        static const std::string pcPortrait;
+        static const std::string pcLandscape;
+        static const std::string toString(const int val);
+
+        static int Int(const std::string str);
+};
+class PopStyleHelper{
+    public:
+        static const int BASE = 0;
+        static const int POPUP = 1;
+        static const int POPUP_GRAB = 2;
+        static const int MAX = 3;
+        static const int DEFAULT = 0;
+
+        static const std::string pcBase;
+        static const std::string pcPopup;
+        static const std::string pcPopup_Grab;
+        static const std::string toString(const int val);
+        static int Int(const std::string str);
+};
+class ButtonTypeHelper{
+    public:
+        //button type
+        static const int NORMAL = 0;
+        static const int GRAB = 1;
+        static const int SELFISH = 2;
+        static const int DRAG = 3;
+        static const int MULTITAP = 4;
+        static const int ROTATION = 5;
+        static const int DIRECTION = 6;
+        static const int RELATIVE_DIRECTION = 7;
+        static const int TOGGLE = 8;
+        static const int UIITEM = 9;
+        static const int MAX = 10;
+        static const int DEFAULT = 0;
+
+        static const std::string pcNormal;
+        static const std::string pcGrab;
+        static const std::string pcSelfish;
+        static const std::string pcDrag;
+        static const std::string pcMultitap;
+        static const std::string pcRotation;
+        static const std::string pcDirection;
+        static const std::string pcRelative_Direction;
+        static const std::string pcToggle;
+        static const std::string pcUiitem;
+
+        static const std::string toString(const int val);
+
+        static int Int(const std::string str);
+};
+class ShiftStateHelper{
+    public:
+        static const int ON = 0;
+        static const int OFF = 1;
+        static const int LOC = 2;
+        static const int MAX = 3;
+        static const int DEFAULT = 0;
+
+        static const std::string pcOn;
+        static const std::string pcOff;
+        static const std::string pcLoc;
+
+        static const std::string toString(const int val);
+
+        static int Int(const std::string str);
+};
+class ButtonStateHelper{
+    public:
+        static const int NORMAL = 0;
+        static const int PRESSED = 1;
+        static const int DISABLED = 2;
+        static const int MAX = 3;
+        static const int DEFAULT = 0;
+
+        static const std::string pcNormal;
+        static const std::string pcPressed;
+        static const std::string pcDisabled ;
+        static const std::string toString(const int val);
+        static int Int(const std::string str);
+};
+class KeyTypeHelper{
+    public:
+        //key type
+        static const int NONE = 0;
+        static const int CHAR = 1;
+        static const int CONTROL = 2;
+        static const int MODECHANGE = 3;
+        static const int STRING = 4;
+        static const int USER = 5;
+        static const int MAX = 6;
+        static const int DEFAULT = 0;
+
+        static const std::string pcNone;
+        static const std::string pcChar;
+        static const std::string pcControl;
+        static const std::string pcModechange;
+        static const std::string pcString;
+        static const std::string pcUser;
+        static const std::string toString(const int val);
+
+        static int Int(const std::string str);
+};
+class PopupTypeHelper {
+    public:
+        //popup type
+        static const int NONE = 0;
+        static const int BTN_RELEASE_POPUP = 1;
+        static const int BTN_RELEASE_POPUP_ONCE = 2;
+        static const int BTN_PRESS_POPUP_DRAG = 3;
+        static const int LONGPRESS_POPUP = 4;
+        static const int LONGPRESS_POPUP_ONCE = 5;
+        static const int AUTO_POPUP = 6;
+        static const int MAX = 7;
+        static const int DEFAULT = 0;
+
+        static const std::string pcNone;
+        static const std::string pcBtn_Release_Popup;
+        static const std::string pcBtn_Release_Popup_Once;
+        static const std::string pcBtn_Press_Popup_Drag;
+        static const std::string pcLongpress_Popup;
+        static const std::string pcLongpress_Popup_Once;
+        static const std::string pcAuto_Popup;
+
+        static const std::string toString(const int val);
+        static int Int(const std::string str);
+};
+class DragStateHelper{
+    public:
+        //drag state
+        static const int NONE = 0;
+        static const int LEFT = 1;
+        static const int RIGHT = 2;
+        static const int UP = 3;
+        static const int DOWN = 4;
+        static const int INVALID = 5;
+        static const int RETURN = 6;
+        static const int MAX = 7;
+        static const int DEFAULT = 0;
+
+        static const std::string pcNone;
+        static const std::string pcLeft;
+        static const std::string pcRight;
+        static const std::string pcUp;
+        static const std::string pcDown;
+        static const std::string pcInvalid;
+        static const std::string pcReturn;
+
+        static const std::string toString(const int val);
+
+        static int Int(const std::string str);
+};
+class ExtraOptionHelper {
+    public:
+        //extra option
+        static const int OPTION_4_DIRECTIONS = 0;
+        static const int OPTION_8_DIRECTIONS = 1;
+        static const int OPTION_4_DIRECTIONS_LONG = 2;
+        static const int OPTION_8_DIRECTIONS_LONG = 3;
+        static const int OPTION_4_DIRECTIONS_RETURN = 4;
+        static const int OPTION_8_DIRECTIONS_RETURN = 5;
+        static const int OPTION_4_DIRECTIONS_RETURN_CURVE = 6;
+        static const int MAX = 7;
+        static const int DEFAULT = 0;
+
+        static const std::string pcOption_4_directions;
+        static const std::string pcOption_8_directions;
+        static const std::string pcOption_4_directions_long;
+        static const std::string pcOption_8_directions_long;
+        static const std::string pcOption_4_directions_return;
+        static const std::string pcOption_8_directions_return;
+        static const std::string pcOption_4_directions_return_curve;
+
+        static const std::string toString(const int val);
+        static int Int(const std::string str);
+};
+
+class MultitouchTypeHelper{
+    public:
+        //multitouch type
+        static const int EXCLUSIVE = 0;
+        static const int COOPERATIVE = 1;
+        static const int GRAB_SUB_EVENTS = 2;
+        static const int MAX = 3;
+        static const int DEFAULT = 0;
+
+        static const std::string pcExclusive;
+        static const std::string pcCooperative;
+        static const std::string pcGrab_Sub_Events;
+
+        static const std::string toString(const int val);
+        static int Int(const std::string str);
+};
+
+class BOOLTypeHelper{
+    public:
+        static const bool DEFAULT = false;
+        static const std::string pcTrue;
+        static const std::string pcFalse;
+
+        static const std::string toString(const bool val);
+        static int Bool(const std::string str);
+};
+class INTTypeHelper{
+    public:
+        static const int DEFAULT = 0;
+        static const std::string dextoString(const int val);
+        static const std::string toString(const int val);
+        static int Int(const std::string str);
+        static int dexInt(const std::string str);
+};
+
+#endif
diff --git a/scl/magnifier_configure_bin_parser.cpp b/scl/magnifier_configure_bin_parser.cpp
new file mode 100644 (file)
index 0000000..2000893
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012 - 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 "magnifier_configure_bin_parser.h"
+#include "file_storage.h"
+#include <assert.h>
+using namespace std;
+#include "put_record.h"
+
+BinMagnifierConfigParser::BinMagnifierConfigParser() {
+    memset((void*)&m_magnifier_configure, 0x00, sizeof(SclMagnifierWndConfigure));
+    parser_info_provider = NULL;
+}
+
+BinMagnifierConfigParser::~BinMagnifierConfigParser() {
+}
+
+BinMagnifierConfigParser* BinMagnifierConfigParser::get_instance() {
+    static BinMagnifierConfigParser instance;
+    return &instance;
+}
+
+void BinMagnifierConfigParser::init(const FileStorage& storage, int offset, int size, IParserInfo_Provider* provider) {
+    m_storage.set_str_provider(provider);
+    m_storage.get_storage(storage, offset, size);
+    this->parser_info_provider = provider;
+    parsing_magnifier_configure();
+}
+
+
+void BinMagnifierConfigParser::parsing_magnifier_configure() {
+    Magnifier_configure_width record_width;
+    set_magnifier_configure_width(*parser_info_provider, record_width);
+
+    PSclMagnifierWndConfigure cur = &m_magnifier_configure;
+
+    // skip data_size
+    m_storage.advance(8);
+
+    //style
+    cur->style = (SCLMagnifierStyle)m_storage.get<sint_t>(record_width.style);
+    //width
+    cur->width = m_storage.get<sint_t>(record_width.width);
+    //height
+    cur->height = m_storage.get<sint_t>(record_width.height);
+    //label_area_record.left
+    cur->label_area_rect.left = m_storage.get<sint_t>(record_width.label_area_rect);
+    //label_area_rect.right
+    cur->label_area_rect.right = m_storage.get<sint_t>(record_width.label_area_rect);
+
+    //label_area_record.top
+    cur->label_area_rect.top = m_storage.get<sint_t>(record_width.label_area_rect);
+    //label_area_rect.bottom
+    cur->label_area_rect.bottom = m_storage.get<sint_t>(record_width.label_area_rect);
+    //bg_image_path
+    m_storage.get_str(&(cur->bg_image_path), record_width.bg_image_path, m_string_collector);
+
+    //bg_shift_image_path
+    m_storage.get_str(&(cur->bg_shift_image_path), record_width.bg_shift_image_path, m_string_collector);
+
+    //bg_shift_lock_image_path
+    m_storage.get_str(&(cur->bg_shift_lock_image_path), record_width.bg_shift_lock_image_path, m_string_collector);
+
+    //bg_long_key_image_path
+    m_storage.get_str(&(cur->bg_long_key_image_path), record_width.bg_long_key_image_path, m_string_collector);
+    //use_actual_window
+    cur->use_actual_window = m_storage.get<sint_t>(record_width.use_actual_window);
+    //label_name
+    m_storage.get_str(&(cur->label_type), record_width.label_type, m_string_collector);
+    //padding_x
+    cur->padding_x = m_storage.get<sint_t>(record_width.padding_x);
+    //padding_y
+    cur->padding_y = m_storage.get<sint_t>(record_width.padding_y);
+    //show_shift_label
+    cur->show_shift_label = m_storage.get<sint_t>(record_width.show_shift_label);
+
+#ifdef __SCL_TXT_DEBUG
+    put_magnifier_wnd_configure(DECODE, m_magnifier_configure);
+#endif
+}
+
+PSclMagnifierWndConfigure BinMagnifierConfigParser::get_magnifier_configure() {
+    return &m_magnifier_configure;
+}
+
diff --git a/scl/magnifier_configure_bin_parser.h b/scl/magnifier_configure_bin_parser.h
new file mode 100644 (file)
index 0000000..db14108
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 - 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 __BinMagnifierConfigParser__H__
+#define __BinMagnifierConfigParser__H__
+#include "sclres_type.h"
+#include "string_collector.h"
+#include "iparserinfo_provider.h"
+#include "file_storage_impl.h"
+#include "_auto_metadata.h"
+
+class BinMagnifierConfigParser {
+public:
+    ~BinMagnifierConfigParser();
+    static BinMagnifierConfigParser *get_instance();
+    void init(const FileStorage& storage, int, int, IParserInfo_Provider*);
+
+    PSclMagnifierWndConfigure get_magnifier_configure();
+private:
+    BinMagnifierConfigParser();
+    void parsing_magnifier_configure();
+
+private:
+    SclMagnifierWndConfigure m_magnifier_configure;
+    StringCollector m_string_collector;
+    FileStorage m_storage;
+    IParserInfo_Provider* parser_info_provider;
+};
+
+
+#endif
diff --git a/scl/magnifier_configure_parser.cpp b/scl/magnifier_configure_parser.cpp
new file mode 100644 (file)
index 0000000..7397086
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2012 - 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 <string.h>
+#include <libxml/parser.h>
+
+#include "magnifier_configure_parser.h"
+#include <assert.h>
+#include "xml_parser_utils.h"
+#include "simple_debug.h"
+using namespace std;
+
+static SCLMagnifierStyle
+get_content_magnifier_style(const xmlNodePtr cur_node) {
+    assert(cur_node != NULL);
+
+    SCLMagnifierStyle style = MAGNIFIER_STYLE_LABEL_ONLY;
+
+    xmlChar* key = xmlNodeGetContent(cur_node);
+    if (key!= NULL) {
+        if (0 == strcmp("area_capture", (const char*)key)) {
+            style = MAGNIFIER_STYLE_SEL_AREA_CAPTURE;
+        }
+        xmlFree(key);
+    }
+
+    return style;
+}
+
+class MagnifierConfigureParserImpl {
+    public:
+    MagnifierConfigureParserImpl() {
+        memset((void*)&m_magnifier_configure, 0x00, sizeof(SclMagnifierWndConfigure));
+    }
+
+    ~MagnifierConfigureParserImpl() {
+        reset();
+    }
+
+    void reset() {
+        if (m_magnifier_configure.bg_image_path) {
+            xmlFree(m_magnifier_configure.bg_image_path);
+            m_magnifier_configure.bg_image_path = NULL;
+        }
+        if (m_magnifier_configure.bg_shift_image_path) {
+            xmlFree(m_magnifier_configure.bg_shift_image_path);
+            m_magnifier_configure.bg_shift_image_path = NULL;
+        }
+        if (m_magnifier_configure.bg_shift_lock_image_path) {
+            xmlFree(m_magnifier_configure.bg_shift_lock_image_path);
+            m_magnifier_configure.bg_shift_lock_image_path = NULL;
+        }
+        if (m_magnifier_configure.bg_long_key_image_path) {
+            xmlFree(m_magnifier_configure.bg_long_key_image_path);
+            m_magnifier_configure.bg_long_key_image_path = NULL;
+        }
+        if (m_magnifier_configure.label_type) {
+            xmlFree(m_magnifier_configure.label_type);
+            m_magnifier_configure.label_type = NULL;
+        }
+        for (int loop = 0; loop < MAX_WND_DECORATOR; loop++) {
+            if (m_magnifier_configure.decoration_image_path[loop]) {
+                xmlFree(m_magnifier_configure.decoration_image_path[loop]);
+                m_magnifier_configure.decoration_image_path[loop] = NULL;
+            }
+        }
+
+        memset((void*)&m_magnifier_configure, 0x00, sizeof(SclMagnifierWndConfigure));
+    }
+
+    int reload_magnifier_configure(const char* input_file) {
+        reset();
+        return parsing_magnifier_configure(input_file);
+    }
+
+    int parsing_magnifier_configure(const char* input_file) {
+        xmlDocPtr doc;
+        xmlNodePtr cur_node;
+
+        doc = xmlReadFile(input_file, NULL, 0);
+        if (doc == NULL) {
+            SCLLOG(SclLog::DEBUG, "Could not load file: %s.", input_file);
+            return -1;
+        }
+
+        cur_node = xmlDocGetRootElement(doc);
+        if (cur_node == NULL) {
+            SCLLOG(SclLog::DEBUG, "MagnifierConfigParser: empty document.\n");
+            xmlFreeDoc(doc);
+            return -1;
+        }
+        if (0 != xmlStrcmp(cur_node->name, (const xmlChar*)"magnifier_configure"))
+        {
+            SCLLOG(SclLog::DEBUG, "MagnifierConfigParser: root name error: %s\n!", (char *)cur_node->name);
+            xmlFreeDoc(doc);
+            return -1;
+        }
+
+        cur_node = cur_node->xmlChildrenNode;
+
+        while (cur_node != NULL) {
+            if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"magnifier_style")) {
+                m_magnifier_configure.style = get_content_magnifier_style(cur_node);
+            } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"width")) {
+                m_magnifier_configure.width = get_content_int(cur_node);
+            } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"height")) {
+                m_magnifier_configure.height = get_content_int(cur_node);
+            } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"label_area")) {
+                parsing_label_area(cur_node);
+            } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"background_image_path")) {
+                parsing_background_images(cur_node);
+            } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"use_window")) {
+                m_magnifier_configure.use_actual_window = get_content_bool(cur_node);
+            } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"label_type")) {
+                xmlChar* temp = xmlNodeGetContent(cur_node);
+                m_magnifier_configure.label_type = (sclchar*)temp;
+            } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"window_decorator")) {
+                get_prop_number(cur_node, "size", &(m_magnifier_configure.decoration_size));
+                parsing_window_decorator_image_path(cur_node);
+            } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"padding")) {
+                parsing_padding_values(cur_node);
+            } else if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"show_shift_label")) {
+                m_magnifier_configure.show_shift_label = get_content_bool(cur_node);
+            }
+            cur_node = cur_node->next;
+        }
+        xmlFreeDoc(doc);
+
+        return 0;
+    }
+
+    void parsing_label_area(const xmlNodePtr cur_node) {
+        assert(cur_node != NULL);
+
+        xmlNodePtr child_node = cur_node->xmlChildrenNode;
+        while (child_node != NULL) {
+            if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"left")) {
+                m_magnifier_configure.label_area_rect.left = get_content_int(child_node);
+            } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"top")) {
+                m_magnifier_configure.label_area_rect.top = get_content_int(child_node);
+            } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"right")) {
+                m_magnifier_configure.label_area_rect.right = get_content_int(child_node);
+            } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"bottom")) {
+                m_magnifier_configure.label_area_rect.bottom = get_content_int(child_node);
+            }
+
+            child_node = child_node->next;
+        }
+    }
+    void parsing_background_images(const xmlNodePtr cur_node) {
+        assert(cur_node != NULL);
+
+        xmlNodePtr child_node = cur_node->xmlChildrenNode;
+        while (child_node != NULL) {
+            if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"image")) {
+                if (equal_prop(child_node, "state", "normal")) {
+                    xmlChar* temp = xmlNodeGetContent(child_node);
+                    m_magnifier_configure.bg_image_path = (sclchar *)temp;
+                } else if (equal_prop(child_node, "state", "shift")) {
+                    xmlChar* temp = xmlNodeGetContent(child_node);
+                    m_magnifier_configure.bg_shift_image_path = (sclchar *)temp;
+                } else if (equal_prop(child_node, "state", "lock")) {
+                    xmlChar* temp = xmlNodeGetContent(child_node);
+                    m_magnifier_configure.bg_shift_lock_image_path = (sclchar *)temp;
+                } else if (equal_prop(child_node, "state", "longkey")) {
+                    xmlChar* temp = xmlNodeGetContent(child_node);
+                    m_magnifier_configure.bg_long_key_image_path = (sclchar *)temp;
+                }
+            }
+
+            child_node = child_node->next;
+        }
+    }
+    void parsing_window_decorator_image_path(const xmlNodePtr cur_node) {
+        assert(cur_node != NULL);
+        assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"window_decorator"));
+        xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+        while (child_node != NULL) {
+            if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"image")) {
+                if (equal_prop(child_node, "direction", "top_left")) {
+                    m_magnifier_configure.decoration_image_path[WND_DECORATOR_TOP_LEFT] = (sclchar *)xmlNodeGetContent(child_node);
+                } else if (equal_prop(child_node, "direction", "top_center")) {
+                    m_magnifier_configure.decoration_image_path[WND_DECORATOR_TOP_CENTER] = (sclchar *)xmlNodeGetContent(child_node);
+                } else if (equal_prop(child_node, "direction", "top_right")) {
+                    m_magnifier_configure.decoration_image_path[WND_DECORATOR_TOP_RIGHT] = (sclchar *)xmlNodeGetContent(child_node);
+                } else if (equal_prop(child_node, "direction", "middle_left")) {
+                    m_magnifier_configure.decoration_image_path[WND_DECORATOR_MIDDLE_LEFT] = (sclchar *)xmlNodeGetContent(child_node);
+                } else if (equal_prop(child_node, "direction", "middle_center")) {
+                    m_magnifier_configure.decoration_image_path[WND_DECORATOR_MIDDLE_CENTER] = (sclchar *)xmlNodeGetContent(child_node);
+                } else if (equal_prop(child_node, "direction", "middle_right")) {
+                    m_magnifier_configure.decoration_image_path[WND_DECORATOR_MIDDLE_RIGHT] = (sclchar *)xmlNodeGetContent(child_node);
+                } else if (equal_prop(child_node, "direction", "bottom_left")) {
+                    m_magnifier_configure.decoration_image_path[WND_DECORATOR_BOTTOM_LEFT] = (sclchar *)xmlNodeGetContent(child_node);
+                } else if (equal_prop(child_node, "direction", "bottom_center")) {
+                    m_magnifier_configure.decoration_image_path[WND_DECORATOR_BOTTOM_CENTER] = (sclchar *)xmlNodeGetContent(child_node);
+                } else if (equal_prop(child_node, "direction", "bottom_right")) {
+                    m_magnifier_configure.decoration_image_path[WND_DECORATOR_BOTTOM_RIGHT] = (sclchar *)xmlNodeGetContent(child_node);
+                }
+            }
+            child_node = child_node->next;
+        }
+    }
+    void parsing_padding_values(const xmlNodePtr cur_node) {
+        assert(cur_node != NULL);
+
+        xmlNodePtr child_node = cur_node->xmlChildrenNode;
+        while (child_node != NULL) {
+            if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"x")) {
+                m_magnifier_configure.padding_x = get_content_int(child_node);
+            } else if (0 == xmlStrcmp(child_node->name, (const xmlChar *)"y")) {
+                m_magnifier_configure.padding_y = get_content_int(child_node);
+            }
+
+            child_node = child_node->next;
+        }
+    }
+    SclMagnifierWndConfigure m_magnifier_configure;
+};
+
+MagnifierConfigParser::MagnifierConfigParser() {
+    m_impl = new MagnifierConfigureParserImpl;
+}
+
+MagnifierConfigParser::~MagnifierConfigParser() {
+    if (m_impl) {
+        SCLLOG(SclLog::MESSAGE, "~MagnifierConfigParser() has called");
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+
+MagnifierConfigParser*
+MagnifierConfigParser::get_instance() {
+    static MagnifierConfigParser instance;
+    return &instance;
+}
+
+int
+MagnifierConfigParser::init(const char* file) {
+    return m_impl->parsing_magnifier_configure(file);
+}
+
+int
+MagnifierConfigParser::reload(const char* file) {
+    return m_impl->reload_magnifier_configure(file);
+}
+
+PSclMagnifierWndConfigure
+MagnifierConfigParser::get_magnifier_configure() {
+    return &m_impl->m_magnifier_configure;
+}
diff --git a/scl/magnifier_configure_parser.h b/scl/magnifier_configure_parser.h
new file mode 100644 (file)
index 0000000..df00068
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 - 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 __MagnifierConfigParser__H__
+#define __MagnifierConfigParser__H__
+#include "sclres_type.h"
+
+typedef SclMagnifierWndConfigure *PSclMagnifierWndConfigure;
+
+class MagnifierConfigureParserImpl;
+
+class MagnifierConfigParser {
+    MagnifierConfigureParserImpl *m_impl;
+public:
+    int init(const char* file);
+    int reload(const char* file);
+    PSclMagnifierWndConfigure get_magnifier_configure();
+public:
+    ~MagnifierConfigParser();
+    static MagnifierConfigParser *get_instance();
+private:
+    MagnifierConfigParser();
+};
+
+
+#endif
diff --git a/scl/main_entry_parser.cpp b/scl/main_entry_parser.cpp
new file mode 100644 (file)
index 0000000..fd712bc
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012 - 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 <assert.h>
+#include <string.h>
+#include <libxml/parser.h>
+
+#include "main_entry_parser.h"
+#include "xml_parser_utils.h"
+#include "simple_debug.h"
+
+using namespace std;
+
+class MainEntryParserImpl {
+    public:
+        int parsing_main_entry(const char *input_file) {
+            xmlDocPtr doc;
+            xmlNodePtr cur_node;
+
+            doc = xmlReadFile(input_file, NULL, 0);
+            if (doc == NULL) {
+                return -1;
+            }
+
+            cur_node = xmlDocGetRootElement(doc);
+            if (cur_node == NULL) {
+                xmlFreeDoc(doc);
+                return -1;
+            }
+            if (0 != xmlStrcmp(cur_node->name, (const xmlChar*)"main-entry"))
+            {
+                xmlFreeDoc(doc);
+                return -1;
+            }
+
+            make_xml_files(cur_node);
+
+            xmlFreeDoc(doc);
+
+            return 0;
+        }
+        int reload_main_entry(const char *input_file) {
+            m_xml_files.reset();
+            return parsing_main_entry(input_file);
+        }
+        void make_xml_files(const xmlNodePtr p_node) {
+            assert(p_node != NULL);
+            xmlNodePtr node = p_node->xmlChildrenNode;
+            while (node != NULL) {
+                if (0 == xmlStrcmp(node->name, (const xmlChar *)"files")) {
+                    parsing_files_node(node);
+                }
+                node = node->next;
+            }
+        }
+
+        void parsing_files_node(const xmlNodePtr p_node) {
+            assert(p_node != NULL);
+            xmlNodePtr node = p_node->xmlChildrenNode;
+
+            while (node != NULL) {
+                if (0 == xmlStrcmp(node->name, (const xmlChar *)"input-mode-configure")) {
+                    m_xml_files.input_mode_configure = (char*)xmlNodeGetContent(node);
+                } else if (0 == xmlStrcmp(node->name, (const xmlChar *)"layout")) {
+                    m_xml_files.layout = (char*)xmlNodeGetContent(node);
+                } else if (0 == xmlStrcmp(node->name, (const xmlChar *)"key-label-property")) {
+                    m_xml_files.key_label_property = (char*)xmlNodeGetContent(node);
+                } else if (0 == xmlStrcmp(node->name, (const xmlChar *)"modifier-decoration")) {
+                    m_xml_files.modifier_decoration = (char*)xmlNodeGetContent(node);
+                } else if (0 == xmlStrcmp(node->name, (const xmlChar *)"default-configure")) {
+                    m_xml_files.default_configure = (char*)xmlNodeGetContent(node);
+                } else if (0 == xmlStrcmp(node->name, (const xmlChar *)"autopopup-configure")) {
+                    m_xml_files.autopopup_configure = (char*)xmlNodeGetContent(node);
+                } else if (0 == xmlStrcmp(node->name, (const xmlChar *)"magnifier-configure")) {
+                    m_xml_files.magnifier_configure = (char*)xmlNodeGetContent(node);
+                } else if (0 == xmlStrcmp(node->name, (const xmlChar *)"nine-patch-file-list")) {
+                    m_xml_files.nine_patch_file_list = (char*)xmlNodeGetContent(node);
+                }
+                node = node->next;
+            }
+        }
+        XMLFiles m_xml_files;
+};
+
+MainEntryParser::MainEntryParser() {
+    m_impl = new MainEntryParserImpl;
+}
+
+MainEntryParser::~MainEntryParser() {
+    if (m_impl) {
+        delete m_impl;
+    }
+}
+
+MainEntryParser*
+MainEntryParser::get_instance() {
+    static MainEntryParser instance;
+    return &instance;
+}
+
+int
+MainEntryParser::init(const char* path) {
+    return m_impl->parsing_main_entry(path);
+}
+
+int
+MainEntryParser::reload(const char* path) {
+    return m_impl->reload_main_entry(path);
+}
+
+XMLFiles&
+MainEntryParser::get_xml_files() {
+    return m_impl->m_xml_files;
+}
diff --git a/scl/main_entry_parser.h b/scl/main_entry_parser.h
new file mode 100644 (file)
index 0000000..80c11f5
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012 - 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 <libxml/parser.h>
+
+#ifndef __MainEntryParser__H__
+#define __MainEntryParser__H__
+class XMLFiles{
+    public:
+    char* input_mode_configure;
+    char* layout;
+    char* default_configure;
+    char* autopopup_configure;
+    char* magnifier_configure;
+    char* key_label_property;
+    char* modifier_decoration;
+    char* nine_patch_file_list;
+
+    public:
+    XMLFiles() {
+        input_mode_configure = NULL;
+        layout = NULL;
+        key_label_property = NULL;
+        modifier_decoration = NULL;
+        default_configure = NULL;
+        autopopup_configure = NULL;
+        magnifier_configure = NULL;
+        nine_patch_file_list = NULL;
+    }
+    ~XMLFiles() {
+        reset();
+    }
+    void reset() {
+        if (input_mode_configure)
+            xmlFree(input_mode_configure);
+        if (layout)
+            xmlFree(layout);
+        if (key_label_property)
+            xmlFree(key_label_property);
+        if (modifier_decoration)
+            xmlFree(modifier_decoration);
+        if (default_configure)
+            xmlFree(default_configure);
+        if (autopopup_configure)
+            xmlFree(autopopup_configure);
+        if (magnifier_configure)
+            xmlFree(magnifier_configure);
+        if (nine_patch_file_list)
+            xmlFree(nine_patch_file_list);
+
+        input_mode_configure = NULL;
+        layout = NULL;
+        key_label_property = NULL;
+        modifier_decoration = NULL;
+        default_configure = NULL;
+        autopopup_configure = NULL;
+        magnifier_configure = NULL;
+        nine_patch_file_list = NULL;
+    }
+};
+
+class MainEntryParserImpl;
+class MainEntryParser {
+    MainEntryParserImpl *m_impl;
+    public:
+    /* parsing xml file, path is assigned */
+    int init(const char* path);
+    int reload(const char* path);
+
+    XMLFiles& get_xml_files();
+    public:
+    ~MainEntryParser();
+    static MainEntryParser *get_instance();
+    private:
+    MainEntryParser();
+};
+
+#endif
diff --git a/scl/metadata.h b/scl/metadata.h
new file mode 100644 (file)
index 0000000..b5318af
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 - 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 __META_FIELD_H__
+#define __META_FIELD_H__
+//each field:
+//1. the name
+//2. the width of the field
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <vector>
+const int FIELD_SIZE_WIDTH = 2;
+class MetaData_Field{
+    public:
+        MetaData_Field():m_name(NULL), m_type(NULL), m_width(0) {
+        }
+        public:
+        const char* m_name;
+        const char* m_type;
+        int m_width;
+};
+
+const int RECORD_SIZE_WIDTH = 2;
+class MetaData_Record{
+    public:
+        MetaData_Record():m_name(NULL) {}
+        const char* m_name;
+        std::vector<MetaData_Field> vField;
+};
+
+class MetaData{
+    public:
+        MetaData():m_version(NULL) {}
+        const char* m_version;
+        std::vector<MetaData_Record> m_vec_metadata_record;
+};
+
+#endif
diff --git a/scl/metadata_bin_parser.cpp b/scl/metadata_bin_parser.cpp
new file mode 100644 (file)
index 0000000..a1117f2
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012 - 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 "metadata_bin_parser.h"
+Metadata_Bin_Parser::Metadata_Bin_Parser(const FileStorage& storage, int offset, int size) {
+    m_storage.get_storage(storage, offset, size);
+    parse();
+}
+Metadata_Bin_Parser::~Metadata_Bin_Parser() {
+}
+
+void
+Metadata_Bin_Parser::parse() {
+    // skip block_size
+    m_storage.advance(8);
+
+    metadata.m_version = m_storage.get_str();
+
+    unsigned short num = m_storage.get<sint_t>(RECORD_SIZE_WIDTH);
+    for (int i = 0; i < num; ++i) {
+        MetaData_Record temp;
+        decode_record(temp);
+        metadata.m_vec_metadata_record.push_back(temp);
+    }
+}
+void Metadata_Bin_Parser::decode_record(MetaData_Record& metadata_record) {
+    metadata_record.m_name = m_storage.get_str();
+    unsigned short field_num = 0;
+    field_num = m_storage.get<sint_t>(FIELD_NUM_WIDTH);
+    for (int i = 0; i < field_num; ++i) {
+        MetaData_Field temp;
+        temp.m_name = m_storage.get_str();
+        temp.m_type = m_storage.get_str();
+        temp.m_width = m_storage.get<sint_t>(FIELD_SIZE_WIDTH);
+        metadata_record.vField.push_back(temp);
+    }
+}
+
diff --git a/scl/metadata_bin_parser.h b/scl/metadata_bin_parser.h
new file mode 100644 (file)
index 0000000..219c34e
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012 - 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 __METADATA_BIN_PARSER_H__
+#define __METADATA_BIN_PARSER_H__
+#include "metadata.h"
+#include "file_storage_impl.h"
+#include "string_collector.h"
+class Metadata_Bin_Parser{
+    public:
+        static const int FIELD_NUM_WIDTH = 2;
+        Metadata_Bin_Parser(const FileStorage& storage, int, int);
+        ~Metadata_Bin_Parser();
+        const MetaData* get_metadata()const {
+            return &metadata;
+        }
+    private:
+        void parse();
+        void decode_record(MetaData_Record& metadata_record);
+        MetaData metadata;
+        FileStorage m_storage;
+};
+#endif
diff --git a/scl/metadata_provider.h b/scl/metadata_provider.h
new file mode 100644 (file)
index 0000000..39c5e0a
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012 - 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 __METADATA_PROVIDER_H__
+#define __METADATA_PROVIDER_H_
+#include "imetadata_provider.h"
+#include "metadata_bin_parser.h"
+#include <dlog.h>
+
+class Metadata_Provider:public IMetadata_Provider{
+    public:
+        Metadata_Provider(const Metadata_Bin_Parser* metadataParser):m_metadataParser(metadataParser) {
+            current_record_name = NULL;
+            curRecordIndex = -1;
+        }
+
+        int get_width(const char* field_name)const {
+            const MetaData* metadata = m_metadataParser->get_metadata();
+            const MetaData_Record& metadata_record = metadata->m_vec_metadata_record.at(curRecordIndex);
+            std::vector<MetaData_Field>::const_iterator it;
+            for (it = metadata_record.vField.begin(); it != metadata_record.vField.end(); ++it) {
+                if (0 == strcmp(it->m_name,  field_name)) {
+                    return it->m_width;
+                }
+            }
+
+            return 0;
+        }
+        void set_current_metadata_record(const char*record_name) {
+            assert(record_name != NULL);
+            if (current_record_name == NULL ||0 != strcmp(current_record_name, record_name)) {
+                current_record_name = record_name;
+                curRecordIndex = (int)find_metadata_record_index(record_name);
+                if (curRecordIndex == -1) {
+                    LOGW("Can not find %s metadata record.", record_name);
+                }
+            }
+        }
+
+    private:
+       size_t find_metadata_record_index(const char* name)const {
+            if (name == NULL) return -1;
+
+            const MetaData* metadata = m_metadataParser->get_metadata();
+            for (size_t i = 0; i < metadata->m_vec_metadata_record.size(); ++i) {
+                const MetaData_Record& metadata_record = metadata->m_vec_metadata_record.at(i);
+
+                if (0 == strcmp(metadata_record.m_name, name)) {
+                    return i;
+                }
+            }
+
+            return -1;
+        }
+        const Metadata_Bin_Parser *m_metadataParser;
+        const char* current_record_name;
+        int curRecordIndex;
+};
+#endif
diff --git a/scl/modifier_decoration_bin_parser.cpp b/scl/modifier_decoration_bin_parser.cpp
new file mode 100644 (file)
index 0000000..ad97d58
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012 - 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 "modifier_decoration_bin_parser.h"
+#include <memory.h>
+#include "put_record.h"
+
+BinModifierDecorationParser::BinModifierDecorationParser() {
+    memset(m_modifier_decoration_table, 0x00, sizeof(SclModifierDecoration) * MAX_SCL_MODIFIER_DECORATION_NUM);
+    parser_info_provider = NULL;
+}
+
+BinModifierDecorationParser::~BinModifierDecorationParser() {
+}
+
+BinModifierDecorationParser*
+BinModifierDecorationParser::get_instance() {
+    static BinModifierDecorationParser instance;
+    return &instance;
+}
+void
+BinModifierDecorationParser::init(const FileStorage& storage, int offset, int size, IParserInfo_Provider* provider) {
+    m_storage.set_str_provider(provider);
+    m_storage.get_storage(storage, offset, size);
+    this->parser_info_provider = provider;
+
+    parsing_modifier_decoration_table();
+}
+
+/* recompute_layout will change the table */
+PSclModifierDecoration BinModifierDecorationParser::get_modifier_decoration_table() {
+    return m_modifier_decoration_table;
+}
+
+void
+BinModifierDecorationParser::parsing_modifier_decoration_table() {
+    PSclModifierDecoration cur = m_modifier_decoration_table;
+
+    Modifier_decoration_width record_width;
+    set_modifier_decoration_width(*parser_info_provider, record_width);
+
+    // skip data_size
+    m_storage.advance(8);
+
+    int size = m_storage.get<sint_t>(4);
+    for (int i = 0; i < size; ++i) {
+        cur->valid = (sclboolean)true;
+        m_storage.get<sint_t>(record_width.extract_background);
+        m_storage.get_str(&(cur->name), record_width.name, m_string_collector);
+        for (int m = 0; m < DISPLAYMODE_MAX; ++m) {
+            for (int n = 0; n < KEY_MODIFIER_MAX; ++n) {
+                m_storage.get_str(&(cur->bg_image_path[m][n]), record_width.bg_image_path, m_string_collector);
+            }
+        }
+
+        cur++;
+    }
+#ifdef __SCL_TXT_DEBUG
+    put_modifier_decoration(DECODE, m_modifier_decoration_table);
+#endif
+}
+
+int
+BinModifierDecorationParser::get_modifier_decoration_id(const char *name )
+{
+    if (name == NULL) return -1;
+
+    for (int i = 0; i < MAX_SCL_MODIFIER_DECORATION_NUM; ++i) {
+        if ( m_modifier_decoration_table[i].name ) {
+            if ( 0 == strcmp(m_modifier_decoration_table[i].name, name) ) {
+                return i;
+            }
+        }
+    }
+
+    return -1;
+}
+
diff --git a/scl/modifier_decoration_bin_parser.h b/scl/modifier_decoration_bin_parser.h
new file mode 100644 (file)
index 0000000..318c169
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012 - 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 __BinModifierDecorationParser__H__
+#define __BinModifierDecorationParser__H__
+#include <libxml/parser.h>
+#include "sclres_type.h"
+#include "iparserinfo_provider.h"
+#include <vector>
+#include "string_collector.h"
+#include "file_storage_impl.h"
+#include "_auto_metadata.h"
+
+class BinModifierDecorationParser {
+    public:
+        ~BinModifierDecorationParser();
+        static BinModifierDecorationParser *get_instance();
+    void init(const FileStorage& storage, int, int, IParserInfo_Provider*);
+    PSclModifierDecoration get_modifier_decoration_table();
+    int get_modifier_decoration_id(const char *name);
+    private:
+    BinModifierDecorationParser();
+    void parsing_modifier_decoration_table();
+
+    private:
+        SclModifierDecoration m_modifier_decoration_table[MAX_SCL_MODIFIER_DECORATION_NUM];
+        IParserInfo_Provider *parser_info_provider;
+
+        StringCollector m_string_collector;
+        FileStorage m_storage;
+};
+
+
+#endif
diff --git a/scl/modifier_decoration_parser.cpp b/scl/modifier_decoration_parser.cpp
new file mode 100644 (file)
index 0000000..7710e95
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2012 - 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 <memory.h>
+#include <libxml/parser.h>
+
+#include "modifier_decoration_parser.h"
+#include "xml_parser_utils.h"
+#include "simple_debug.h"
+
+static int get_key_modifier_state_prop(const char*);
+//UTILS
+typedef struct _Modifier_decoration_state_match_table {
+    int modifier_decoration_state;
+    const char* key;
+}Modifier_decoration_state_match_table_t;
+
+typedef struct _Key_modifier_state_match_table {
+    int key_modifier_state;
+    const char* key;
+}Key_modifier_state_match_table_t;
+
+static int
+get_key_modifier_state_prop(const char* key ) {
+  static Key_modifier_state_match_table_t table[] = {
+    {KEY_MODIFIER_NONE,                             "none"                          },
+    {KEY_MODIFIER_LONGKEY,                          "longkey"                       },
+    {KEY_MODIFIER_MULTITAP_START,                   "multitap_start"                },
+    {KEY_MODIFIER_MULTITAP_REPEAT,                  "multitap_repeat"               },
+    {KEY_MODIFIER_DIRECTION_LEFT,                   "direction_left"                },
+    {KEY_MODIFIER_DIRECTION_RIGHT,                  "direction_right"               },
+    {KEY_MODIFIER_DIRECTION_UP,                     "direction_up"                  },
+    {KEY_MODIFIER_DIRECTION_DOWN,                   "direction_down"                },
+    {KEY_MODIFIER_DIRECTION_UP_LEFT,                "direction_up_left"             },
+    {KEY_MODIFIER_DIRECTION_UP_RIGHT,               "direction_up_right"            },
+    {KEY_MODIFIER_DIRECTION_DOWN_LEFT,              "direction_down_left"           },
+    {KEY_MODIFIER_DIRECTION_DOWN_RIGHT,             "direction_down_right"          },
+
+    {KEY_MODIFIER_DIRECTION_LEFT_LONG,              "direction_left_long"           },
+    {KEY_MODIFIER_DIRECTION_RIGHT_LONG,             "direction_right_long"          },
+    {KEY_MODIFIER_DIRECTION_UP_LONG,                "direction_up_long"             },
+    {KEY_MODIFIER_DIRECTION_DOWN_LONG,              "direction_down_long"           },
+    {KEY_MODIFIER_DIRECTION_UP_LEFT_LONG,           "direction_up_left_long"        },
+    {KEY_MODIFIER_DIRECTION_UP_RIGHT_LONG,          "direction_up_right_long"       },
+    {KEY_MODIFIER_DIRECTION_DOWN_LEFT_LONG,         "direction_down_left_long"      },
+    {KEY_MODIFIER_DIRECTION_DOWN_RIGHT_LONG,        "direction_down_right_long"     },
+
+    {KEY_MODIFIER_DIRECTION_LEFT_RETURN,            "direction_left_return"         },
+    {KEY_MODIFIER_DIRECTION_RIGHT_RETURN,           "direction_right_return"        },
+    {KEY_MODIFIER_DIRECTION_UP_RETURN,              "direction_up_return"           },
+    {KEY_MODIFIER_DIRECTION_DOWN_RETURN,            "direction_down_return"         },
+    {KEY_MODIFIER_DIRECTION_UP_LEFT_RETURN,         "direction_up_left_return"      },
+    {KEY_MODIFIER_DIRECTION_UP_RIGHT_RETURN,        "direction_up_right_return"     },
+    {KEY_MODIFIER_DIRECTION_DOWN_LEFT_RETURN,       "direction_down_left_return"    },
+    {KEY_MODIFIER_DIRECTION_DOWN_RIGHT_RETURN,      "direction_down_right_return"   },
+
+    {KEY_MODIFIER_DIRECTION_CURVE_UP_LEFT,          "direction_curve_up_left"       },
+    {KEY_MODIFIER_DIRECTION_CURVE_UP_RIGHT,         "direction_curve_up_right"      },
+    {KEY_MODIFIER_DIRECTION_CURVE_DOWN_LEFT,        "direction_curve_down_left"     },
+    {KEY_MODIFIER_DIRECTION_CURVE_DOWN_RIGHT,       "direction_curve_down_right"    },
+    {KEY_MODIFIER_DIRECTION_CURVE_LEFT_UP,          "direction_curve_left_up"       },
+    {KEY_MODIFIER_DIRECTION_CURVE_LEFT_DOWN,        "direction_curve_left_down"     },
+    {KEY_MODIFIER_DIRECTION_CURVE_RIGHT_UP,         "direction_curve_right_up"      },
+    {KEY_MODIFIER_DIRECTION_CURVE_RIGHT_DOWN,       "direction_curve_right_down"    }
+    };
+
+    int key_modifier_state = KEY_MODIFIER_NONE;
+
+    for (size_t i = 0; i < sizeof(table)/sizeof(Key_modifier_state_match_table_t); ++i) {
+        if (0 == strcmp(key, table[i].key) )
+        {
+            key_modifier_state = table[i].key_modifier_state;
+            break;
+        }
+    }
+    return key_modifier_state;
+}
+
+class ModifierDecorationParserImpl {
+    public:
+        ModifierDecorationParserImpl() {
+            memset(m_modifier_decoration_table, 0x00, sizeof(SclModifierDecoration) * MAX_SCL_MODIFIER_DECORATION_NUM);
+        }
+
+        ~ModifierDecorationParserImpl() {
+            reset();
+        }
+
+        void reset()
+        {
+            for (int i = 0; i < MAX_SCL_MODIFIER_DECORATION_NUM; ++i) {
+                SclModifierDecoration& cur_rec = m_modifier_decoration_table[i];
+                for (int display_state = 0; display_state < DISPLAYMODE_MAX; ++display_state) {
+                    for (int key_modifier_state = 0; key_modifier_state < KEY_MODIFIER_MAX; ++key_modifier_state) {
+                        if (cur_rec.bg_image_path[display_state][key_modifier_state])
+                            delete cur_rec.bg_image_path[display_state][key_modifier_state];
+                        cur_rec.bg_image_path[display_state][key_modifier_state] = NULL;
+                    }
+                }
+            }
+            memset(m_modifier_decoration_table, 0x00, sizeof(SclModifierDecoration) * MAX_SCL_MODIFIER_DECORATION_NUM);
+        }
+        int reload_modifier_decoration_table(const char* input_file) {
+            reset();
+            return parsing_modifier_decoration_table(input_file);
+        }
+
+        int parsing_modifier_decoration_table(const char* input_file) {
+            xmlDocPtr doc;
+            xmlNodePtr cur_node;
+
+            doc = xmlReadFile(input_file, NULL, 0);
+            if (doc == NULL) {
+                SCLLOG(SclLog::DEBUG, "Could not load file: %s.", input_file);
+                return -1;
+            }
+            cur_node = xmlDocGetRootElement(doc);
+            if (cur_node == NULL) {
+                SCLLOG(SclLog::DEBUG, "ModifierDecorationParser: empty document.\n");
+                xmlFreeDoc(doc);
+                return -1;
+            }
+            if (0 != xmlStrcmp(cur_node->name, (const xmlChar*)"modifier_decoration_table"))
+            {
+                SCLLOG(SclLog::DEBUG, "ModifierDecorationParser: root name error: %s\n!", (char *)cur_node->name);
+                xmlFreeDoc(doc);
+                return -1;
+            }
+
+            cur_node = cur_node->xmlChildrenNode;
+
+
+            SclModifierDecoration* cur_rec = m_modifier_decoration_table;
+
+            int size = 0;
+            while (cur_node != NULL) {
+                if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"modifier_decoration_record")) {
+                    parsing_modifier_decoration_record(cur_node, cur_rec);
+                    size++;
+                    cur_rec++;
+                    if (size >= MAX_SCL_MODIFIER_DECORATION_NUM) {
+                        SCLLOG(SclLog::ERROR, "No Space for modifier decoration record.");
+                        break;
+                    }
+                }
+
+                cur_node = cur_node->next;
+            }
+            xmlFreeDoc(doc);
+
+            return 0;
+        }
+
+        void parsing_modifier_decoration_record(const xmlNodePtr cur_node, const PSclModifierDecoration cur_rec) {
+            assert(cur_node != NULL);
+            assert(cur_rec != NULL);
+
+            set_modifier_decoration_default_record(cur_rec);
+
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"name")) {
+                    xmlChar* temp = xmlNodeGetContent(child_node);
+                    cur_rec->name = (sclchar *)temp;
+                    cur_rec->valid = TRUE;
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"display_part_background")) {
+                    cur_rec->extract_background = get_content_bool(child_node);
+                    cur_rec->valid = TRUE;
+                } else if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"background_image_path")) {
+                    parsing_background_image_record_node(child_node, cur_rec);
+                    cur_rec->valid = TRUE;
+                }
+                child_node = child_node->next;
+            }
+        }
+
+        void set_modifier_decoration_default_record(const PSclModifierDecoration cur_rec) {
+            cur_rec->valid = FALSE;
+            cur_rec->extract_background = false;
+            cur_rec->name = NULL;
+            for (int display_state = 0; display_state < DISPLAYMODE_MAX; ++display_state) {
+                for (int key_modifier_state = 0; key_modifier_state < KEY_MODIFIER_MAX; ++key_modifier_state) {
+                    cur_rec->bg_image_path[display_state][key_modifier_state] = NULL;
+                }
+            }
+        }
+
+        void parsing_background_image_record_node(const xmlNodePtr cur_node, const PSclModifierDecoration cur_rec) {
+            assert(cur_node != NULL);
+            assert(cur_rec != NULL);
+            assert(0 == xmlStrcmp(cur_node->name, (const xmlChar*)"background_image_path"));
+            xmlNodePtr child_node = cur_node->xmlChildrenNode;
+
+            while (child_node != NULL) {
+                if (0 == xmlStrcmp(child_node->name, (const xmlChar*)"image")) {
+                    /* FIXME */
+                    int display_state = DISPLAYMODE_PORTRAIT;
+                    xmlChar* display_state_xml = xmlGetProp(child_node, (const xmlChar*)"display_state");
+                    if (display_state_xml != NULL) {
+                        if (0 == xmlStrcmp(display_state_xml, (const xmlChar*)"landscape")) {
+                            display_state = DISPLAYMODE_LANDSCAPE;
+                        }
+                        xmlFree(display_state_xml);
+                    }
+
+                    int key_modifier_state = KEY_MODIFIER_NONE;
+                    xmlChar* key_modifier_state_xml = xmlGetProp(child_node, (const xmlChar*)"key_modifier_state");
+                    if (key_modifier_state_xml != NULL) {
+                        key_modifier_state = get_key_modifier_state_prop((const char*)key_modifier_state_xml);
+                        xmlFree(key_modifier_state_xml);
+                    }
+
+                    if (display_state != -1 && key_modifier_state != -1) {
+                        sclchar* key = (sclchar*)xmlNodeGetContent(child_node);
+                        cur_rec->bg_image_path[display_state][key_modifier_state] = key;
+                        //Warning:: Donot xmlFree key
+                    }
+                }
+                child_node = child_node->next;
+            }
+        }
+
+        SclModifierDecoration m_modifier_decoration_table[MAX_SCL_MODIFIER_DECORATION_NUM];
+};
+
+ModifierDecorationParser*
+ModifierDecorationParser::get_instance() {
+    static ModifierDecorationParser instance;
+    return &instance;
+}
+
+ModifierDecorationParser::ModifierDecorationParser() {
+    m_impl = new ModifierDecorationParserImpl;
+}
+
+ModifierDecorationParser::~ModifierDecorationParser() {
+    if (m_impl) {
+        SCLLOG(SclLog::MESSAGE, "~ModifierDecorationParser() has called");
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+
+int
+ModifierDecorationParser::init(const char* file) {
+    return m_impl->parsing_modifier_decoration_table(file);
+}
+
+int
+ModifierDecorationParser::reload(const char* file) {
+    return m_impl->reload_modifier_decoration_table(file);
+}
+
+/* recompute_layout will change the table */
+PSclModifierDecoration
+ModifierDecorationParser::get_modifier_decoration_table() {
+    return m_impl->m_modifier_decoration_table;
+}
+
+int
+ModifierDecorationParser::get_modifier_decoration_id(const char *name)
+{
+    if (name == NULL) {
+        SCLLOG(SclLog::DEBUG, "get_modifier_decoration_id() has failed");
+        return -1;
+    }
+
+    PSclModifierDecoration modifier_decoration_table = get_modifier_decoration_table();
+    if (modifier_decoration_table == NULL) {
+        SCLLOG(SclLog::DEBUG, "get_modifier_decoration_id() has failed");
+        return -1;
+    }
+    for (int i = 0; i < MAX_SCL_MODIFIER_DECORATION_NUM; ++i) {
+        if (modifier_decoration_table[i].name) {
+            if (0 == strcmp(modifier_decoration_table[i].name, name)) {
+                return i;
+            }
+        }
+    }
+
+    SCLLOG(SclLog::DEBUG, "get_modifier_decoration_id() has failed");
+    return -1;
+}
+
diff --git a/scl/modifier_decoration_parser.h b/scl/modifier_decoration_parser.h
new file mode 100644 (file)
index 0000000..c9d9417
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 - 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 __ModifierDecorationParser__H__
+#define __ModifierDecorationParser__H__
+#include "sclres_type.h"
+
+class ModifierDecorationParserImpl;
+
+class ModifierDecorationParser {
+    ModifierDecorationParserImpl *m_impl;
+    public:
+        int init(const char* file);
+        int reload(const char* file);
+        PSclModifierDecoration get_modifier_decoration_table();
+        int get_modifier_decoration_id(const char *name);
+    public:
+        ~ModifierDecorationParser();
+        static ModifierDecorationParser *get_instance();
+    private:
+        ModifierDecorationParser();
+};
+
+
+#endif
diff --git a/scl/nine_patch_file_list_bin_parser.cpp b/scl/nine_patch_file_list_bin_parser.cpp
new file mode 100644 (file)
index 0000000..530ce13
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012 - 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 "nine_patch_file_list_bin_parser.h"
+#include <memory.h>
+#include <assert.h>
+#include "put_record.h"
+
+BinNinePatchFileParser::BinNinePatchFileParser() {
+    m_size = 0;
+    memset(m_nine_patch_file_list, 0x00, sizeof(SclNinePatchInfo) * MAX_NINE_PATCH_FILE_LIST);
+    parser_info_provider = NULL;
+}
+
+BinNinePatchFileParser::~BinNinePatchFileParser() {
+    m_size = 0;
+}
+BinNinePatchFileParser* BinNinePatchFileParser::get_instance() {
+    static BinNinePatchFileParser instance;
+    return &instance;
+}
+void BinNinePatchFileParser::init(const FileStorage& storage, int offset, int size, IParserInfo_Provider* provider) {
+    m_storage.set_str_provider(provider);
+    m_storage.get_storage(storage, offset, size);
+    this->parser_info_provider = provider;
+
+    parsing_nine_patch_file_list();
+}
+
+void BinNinePatchFileParser::parsing_nine_patch_file_list() {
+    Nine_patch_width record_width;
+    set_nine_patch_width(*parser_info_provider, record_width);
+
+    // skip data_size
+    m_storage.advance(8);
+
+    SclNinePatchInfo* cur = m_nine_patch_file_list;
+    m_size = m_storage.get<sint_t>(4);
+    for (int i = 0; i < m_size; ++i) {
+        char* temp = NULL;
+        m_storage.get_str(&(temp), record_width.image_path, m_string_collector);
+        cur->image_path = (char*)temp;
+
+        cur->left = m_storage.get<sint_t>(record_width.left);
+        cur->right = m_storage.get<sint_t>(record_width.right);
+        cur->top = m_storage.get<sint_t>(record_width.top);
+        cur->bottom = m_storage.get<sint_t>(record_width.bottom);
+        cur++;
+    }
+#ifdef __SCL_TXT_DEBUG
+    put_nine_patch_info(DECODE, m_nine_patch_file_list);
+#endif
+}
+
+SclNinePatchInfo*
+BinNinePatchFileParser::get_nine_patch_list() {
+    return m_nine_patch_file_list;
+}
+bool
+BinNinePatchFileParser::get_nine_patch_info(const char* filename, SclNinePatchInfo *info) {
+    if (filename == NULL) return false;
+
+    for (int i = 0; i < MAX_NINE_PATCH_FILE_LIST && i < m_size; ++i) {
+        if ( m_nine_patch_file_list[i].image_path != NULL &&
+            0 == strcmp(m_nine_patch_file_list[i].image_path, filename) ) {
+                if (info) {
+                    *info = m_nine_patch_file_list[i];
+                }
+            return true;
+        }
+    }
+
+    return false;
+}
diff --git a/scl/nine_patch_file_list_bin_parser.h b/scl/nine_patch_file_list_bin_parser.h
new file mode 100644 (file)
index 0000000..433ab26
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 - 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 __BinNinePatchFileParser__H__
+#define __BinNinePatchFileParser__H__
+#include "iparserinfo_provider.h"
+#include "sclres_type.h"
+#include "string_collector.h"
+#include "file_storage_impl.h"
+#include "_auto_metadata.h"
+
+class BinNinePatchFileParser {
+    static const int MAX_NINE_PATCH_FILE_LIST = 128;
+    public:
+        ~BinNinePatchFileParser();
+        static BinNinePatchFileParser *get_instance();
+    void init(const FileStorage& storage, int, int, IParserInfo_Provider*);
+    bool get_nine_patch_info(const char *filename, SclNinePatchInfo *info);
+    SclNinePatchInfo* get_nine_patch_list();
+    private:
+    BinNinePatchFileParser();
+    void parsing_nine_patch_file_list();
+    private:
+        SclNinePatchInfo m_nine_patch_file_list[MAX_NINE_PATCH_FILE_LIST];
+        int m_size;
+        StringCollector m_string_collector;
+        FileStorage m_storage;
+        IParserInfo_Provider* parser_info_provider;
+};
+
+
+#endif
diff --git a/scl/nine_patch_file_list_parser.cpp b/scl/nine_patch_file_list_parser.cpp
new file mode 100644 (file)
index 0000000..f12a9b2
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2012 - 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 <memory.h>
+#include <assert.h>
+#include <libxml/parser.h>
+
+#include "nine_patch_file_list_parser.h"
+#include "xml_parser_utils.h"
+#include "simple_debug.h"
+
+class NinePatchFileListParserImpl {
+    public:
+        NinePatchFileListParserImpl() {
+            m_size = 0;
+            memset(m_nine_patch_file_list, 0x00, sizeof(SclNinePatchInfo) * MAX_NINE_PATCH_FILE_LIST);
+        }
+        ~NinePatchFileListParserImpl() {
+            reset();
+        }
+
+        void reset() {
+            for (int i = 0; i < m_size; ++i) {
+                if (m_nine_patch_file_list[i].image_path)
+                    xmlFree(m_nine_patch_file_list[i].image_path);
+                m_nine_patch_file_list[i].image_path = NULL;
+            }
+            m_size = 0;
+            memset(m_nine_patch_file_list, 0x00, sizeof(SclNinePatchInfo) * MAX_NINE_PATCH_FILE_LIST);
+        }
+
+        int reload_nine_patch_file_list(const char* input_file) {
+            reset();
+            return parsing_nine_patch_file_list(input_file);
+        }
+
+        int parsing_nine_patch_file_list(const char* input_file) {
+            xmlDocPtr doc;
+            xmlNodePtr cur_node;
+
+            doc = xmlReadFile(input_file, NULL, 0);
+            if (doc == NULL) {
+                SCLLOG(SclLog::DEBUG, "Could not load file: %s.", input_file);
+                return -1;
+            }
+
+            cur_node = xmlDocGetRootElement(doc);
+            if (cur_node == NULL) {
+                SCLLOG(SclLog::DEBUG, "Nine_Patch_File_Parser: empty document.\n");
+                xmlFreeDoc(doc);
+                return -1;
+            }
+            if (0 != xmlStrcmp(cur_node->name, (const xmlChar*)"nine_patch_file_list"))
+            {
+                SCLLOG(SclLog::DEBUG, "Nine_Patch_File_Parser: root name error: %s\n!", (char *)cur_node->name);
+                xmlFreeDoc(doc);
+                return -1;
+            }
+
+            cur_node = cur_node->xmlChildrenNode;
+
+            assert(m_size == 0);
+            while (cur_node != NULL) {
+                if (0 == xmlStrcmp(cur_node->name, (const xmlChar *)"file")) {
+                    assert(m_size >= 0 && m_size < MAX_NINE_PATCH_FILE_LIST);
+                    if (m_size >= 0 && m_size < MAX_NINE_PATCH_FILE_LIST) {
+                        m_nine_patch_file_list[m_size].image_path = (char*)xmlNodeGetContent(cur_node);
+                        get_prop_number(cur_node, "left", &(m_nine_patch_file_list[m_size].left));
+                        get_prop_number(cur_node, "right", &(m_nine_patch_file_list[m_size].right));
+                        get_prop_number(cur_node, "top", &(m_nine_patch_file_list[m_size].top));
+                        get_prop_number(cur_node, "bottom", &(m_nine_patch_file_list[m_size].bottom));
+                        if (m_nine_patch_file_list[m_size].image_path == NULL) {
+                            SCLLOG(SclLog::ERROR, "NinePatchFileParser: image_path should be not NULL");
+                        }
+                        m_size++;
+                        if (m_size >= MAX_NINE_PATCH_FILE_LIST) {
+                            SCLLOG(SclLog::ERROR, "No Space for nine patch file list record.");
+                            break;
+                        }
+                    }
+                }
+
+                cur_node = cur_node->next;
+            }
+            xmlFreeDoc(doc);
+
+            return 0;
+        }
+        SclNinePatchInfo m_nine_patch_file_list[MAX_NINE_PATCH_FILE_LIST];
+        int m_size;
+};
+
+NinePatchFileParser::NinePatchFileParser() {
+    m_impl = new NinePatchFileListParserImpl;
+}
+
+NinePatchFileParser::~NinePatchFileParser() {
+    if (m_impl) {
+        SCLLOG(SclLog::MESSAGE, "~NinePatchFileParser() has called.");
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+NinePatchFileParser*
+NinePatchFileParser::get_instance() {
+    static NinePatchFileParser instance;
+    return &instance;
+}
+
+int
+NinePatchFileParser::init(const char* file) {
+    return m_impl->parsing_nine_patch_file_list(file);
+}
+
+int
+NinePatchFileParser::reload(const char* file) {
+    return m_impl->reload_nine_patch_file_list(file);
+}
+
+bool
+NinePatchFileParser::get_nine_patch_info(const char* filename, SclNinePatchInfo *info) {
+    if (filename == NULL) {
+        SCLLOG(SclLog::DEBUG, "get_nine_patch_info() has failed.");
+        return false;
+    }
+
+    SclNinePatchInfo *nine_patch_list = get_nine_patch_list();
+    if (nine_patch_list == NULL) {
+        SCLLOG(SclLog::DEBUG, "get_nine_patch_info() has failed.");
+        return false;
+    }
+
+    for (int i = 0; i < MAX_NINE_PATCH_FILE_LIST && i < m_impl->m_size; ++i) {
+        if ( nine_patch_list[i].image_path != NULL &&
+            0 == strcmp(nine_patch_list[i].image_path, filename) ) {
+                if (info) {
+                    *info = nine_patch_list[i];
+                }
+            return true;
+        }
+    }
+
+    SCLLOG(SclLog::DEBUG, "get_nine_patch_info() has failed.");
+    return false;
+}
+
+SclNinePatchInfo*
+NinePatchFileParser::get_nine_patch_list() {
+    return m_impl->m_nine_patch_file_list;
+}
diff --git a/scl/nine_patch_file_list_parser.h b/scl/nine_patch_file_list_parser.h
new file mode 100644 (file)
index 0000000..b99c625
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 - 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 __NinePatchFileParser__H__
+#define __NinePatchFileParser__H__
+#include "sclres_type.h"
+
+const int MAX_NINE_PATCH_FILE_LIST = 128;
+class NinePatchFileListParserImpl;
+
+class NinePatchFileParser {
+    NinePatchFileListParserImpl *m_impl;
+    public:
+    int init(const char* file);
+    int reload(const char* file);
+    SclNinePatchInfo* get_nine_patch_list();
+    bool get_nine_patch_info(const char *filename, SclNinePatchInfo *info);
+    public:
+    ~NinePatchFileParser();
+    static NinePatchFileParser *get_instance();
+    private:
+    NinePatchFileParser();
+};
+
+
+#endif
diff --git a/scl/parserinfo_provider.h b/scl/parserinfo_provider.h
new file mode 100644 (file)
index 0000000..bd01ec5
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 - 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 __PARSERINFO_PROVIDER_H__
+#define __PARSERINFO_PROVIDER_H__
+#include "iparserinfo_provider.h"
+#include "istring_provider.h"
+#include "imetadata_provider.h"
+
+class ParserInfo_Provider: public IParserInfo_Provider{
+    public:
+        ParserInfo_Provider(IMetadata_Provider* metadataProvider,
+                            const IString_Provider* stringProvider) :m_metadataProvider(metadataProvider),
+                            m_stringProvider(stringProvider) {}
+        void set_current_metadata_record(const char* record_name) {
+            assert(m_metadataProvider);
+            if (m_metadataProvider != NULL) {
+                m_metadataProvider->set_current_metadata_record(record_name);
+            }
+        }
+        int get_width(const char* field_name)const {
+            assert(m_metadataProvider != NULL);
+            if (m_metadataProvider != NULL)
+                return m_metadataProvider->get_width(field_name);
+
+            return 0 ;
+        }
+
+        const char* get_string_by_id(const int id)const {
+            if (m_stringProvider != NULL) {
+                return m_stringProvider->get_string_by_id(id);
+            }
+            return NULL;
+        }
+
+    private:
+        IMetadata_Provider *m_metadataProvider;
+        const IString_Provider *m_stringProvider;
+};
+#endif
diff --git a/scl/sclactionstate.cpp b/scl/sclactionstate.cpp
new file mode 100644 (file)
index 0000000..5b7a133
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 - 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 <memory.h>
+#include "sclactionstate.h"
+#include "scldebug.h"
+
+using namespace scl;
+
+CSCLActionState::CSCLActionState()
+{
+    SCL_DEBUG();
+
+    reset();
+}
+
+CSCLActionState::~CSCLActionState()
+{
+    SCL_DEBUG();
+}
+
+CSCLActionState*
+CSCLActionState::get_instance()
+{
+    static CSCLActionState instance;
+    return &instance;
+}
+
+
+void
+CSCLActionState::reset()
+{
+    m_cur_action_state = ACTION_STATE_BASE_INIT;
+    memset(m_action_buffer, 0x00, sizeof(m_action_buffer));
+}
+
+void
+CSCLActionState::clear_action_buf()
+{
+}
diff --git a/scl/sclactionstate.h b/scl/sclactionstate.h
new file mode 100644 (file)
index 0000000..bb19635
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012 - 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 "sclconfig.h"
+
+#ifndef __SCL_ACTIONSTATE_H__
+#define __SCL_ACTIONSTATE_H__
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+
+#define MAX_ACTION_BUF 50
+
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLActionState
+{
+private:
+    CSCLActionState();
+public:
+    virtual ~CSCLActionState();
+
+    /* for singleton */
+    static CSCLActionState* get_instance();
+
+    /* reset the action state to init status */
+    void reset();
+    void clear_action_buf();
+    SCLActionState get_cur_action_state() {
+        return m_cur_action_state;
+    }
+    void set_cur_action_state(SCLActionState state) {
+        m_cur_action_state = state;
+    }
+
+public:
+    /* stores the state information */
+    SCLActionState m_action_buffer[MAX_ACTION_BUF];
+    SCLActionState m_cur_action_state;
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_ACTIONSTATE_H__
diff --git a/scl/sclanimator-nui.cpp b/scl/sclanimator-nui.cpp
new file mode 100644 (file)
index 0000000..c2c8c9b
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2012 - 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 "sclanimator-nui.h"
+#include "scldebug.h"
+
+#include <Ecore.h>
+#include <Elementary.h>
+
+#include "sclutils.h"
+#include "sclwindows.h"
+
+using namespace scl;
+
+/**
+ * Constructor
+ */
+CSCLAnimatorImplNui::CSCLAnimatorImplNui()
+{
+    SCL_DEBUG();
+
+    m_highlight_ui_object = NULL;
+    m_highlight_ui_object_alternate = NULL;
+}
+
+/**
+ * De-constructor
+ */
+CSCLAnimatorImplNui::~CSCLAnimatorImplNui()
+{
+    SCL_DEBUG();
+}
+
+void CSCLAnimatorImplNui::init()
+{
+}
+
+void CSCLAnimatorImplNui::fini()
+{
+    if (m_highlight_ui_object) {
+        evas_object_del(m_highlight_ui_object);
+        m_highlight_ui_object = NULL;
+    }
+    if (m_highlight_ui_object_alternate) {
+        evas_object_del(m_highlight_ui_object_alternate);
+        m_highlight_ui_object_alternate = NULL;
+    }
+}
+
+
+sclboolean
+CSCLAnimatorImplNui::check_animation_supported()
+{
+    /* EFL Backend finished implementing animation support */
+    return TRUE;
+}
+
+void
+CSCLAnimatorImplNui::animator_timer(SclAnimationState *state)
+{
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+
+    if (state && windows && utils) {
+        switch (state->desc.type) {
+            case ANIMATION_TYPE_HIGHLIGHT_UI: {
+                if (state->active) {
+                    SclRectangle rect = state->rect_cur;
+                    if (m_highlight_ui_object == NULL) {
+                        Evas_Object *window_object = static_cast<Evas_Object*>(windows->get_base_window());
+                        Evas *evas = evas_object_evas_get(window_object);
+                        m_highlight_ui_object = evas_object_image_add(evas);
+                        sclchar composed_path[_POSIX_PATH_MAX] = {0, };
+                        utils->get_composed_path(composed_path, IMG_PATH_PREFIX, SCL_HIGHLIGHT_UI_IMAGE);
+                        evas_object_image_file_set(m_highlight_ui_object, composed_path, NULL);
+                    }
+                    evas_object_move(m_highlight_ui_object, rect.x, rect.y);
+                    evas_object_image_fill_set(m_highlight_ui_object, 0, 0, rect.width, rect.height);
+                    evas_object_resize(m_highlight_ui_object, rect.width, rect.height);
+                    evas_object_raise(m_highlight_ui_object);
+                    evas_object_show(m_highlight_ui_object);
+
+                    sclboolean circular = FALSE;
+                    if (state->desc.circular) {
+                        if (m_highlight_ui_object_alternate == NULL) {
+                            Evas_Object *window_object = static_cast<Evas_Object*>(windows->get_base_window());
+                            Evas *evas = evas_object_evas_get(window_object);
+                            m_highlight_ui_object_alternate = evas_object_image_add(evas);
+                            sclchar composed_path[_POSIX_PATH_MAX] = {0, };
+                            utils->get_composed_path(composed_path, IMG_PATH_PREFIX, SCL_HIGHLIGHT_UI_IMAGE);
+                            evas_object_image_file_set(m_highlight_ui_object_alternate, composed_path, NULL);
+                        }
+                        SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());
+                        if (window_context) {
+                            if (rect.x < 0) {
+                                evas_object_move(m_highlight_ui_object_alternate,
+                                    window_context->geometry.width + rect.x, rect.y);
+                                evas_object_image_fill_set(m_highlight_ui_object_alternate,
+                                    0, 0, rect.width, rect.height);
+                                evas_object_resize(m_highlight_ui_object_alternate,
+                                    rect.width, rect.height);
+                                evas_object_raise(m_highlight_ui_object_alternate);
+                                evas_object_show(m_highlight_ui_object_alternate);
+                                circular = TRUE;
+                            } else if (rect.x + rect.width > window_context->geometry.width) {
+                                evas_object_move(m_highlight_ui_object_alternate,
+                                    -(window_context->geometry.width - rect.x), rect.y);
+                                evas_object_image_fill_set(m_highlight_ui_object_alternate,
+                                    0, 0, rect.width, rect.height);
+                                evas_object_resize(m_highlight_ui_object_alternate,
+                                    rect.width, rect.height);
+                                evas_object_raise(m_highlight_ui_object_alternate);
+                                evas_object_show(m_highlight_ui_object_alternate);
+                                circular = TRUE;
+                            }
+                        }
+                    }
+                    if (!circular) {
+                        if (m_highlight_ui_object_alternate) {
+                            evas_object_hide(m_highlight_ui_object_alternate);
+                        }
+                    } else {
+                        if (m_highlight_ui_object_alternate) {
+                            sclint window_layer = 29000;
+                            if (!windows->is_base_window(state->desc.window_from) ||
+                                !windows->is_base_window(state->desc.window_to)) {
+                                    window_layer = 29010;
+                            }
+                            evas_object_layer_set(m_highlight_ui_object_alternate, window_layer + 1);
+                        }
+                    }
+
+                    sclint window_layer = 29000;
+                    if (!windows->is_base_window(state->desc.window_from) ||
+                        !windows->is_base_window(state->desc.window_to)) {
+                            window_layer = 29010;
+                    }
+                    evas_object_layer_set(m_highlight_ui_object, window_layer + 1);
+                } else {
+                    evas_object_hide(m_highlight_ui_object);
+                }
+            }
+            break;
+            default:
+            break;
+        }
+    }
+}
diff --git a/scl/sclanimator-nui.h b/scl/sclanimator-nui.h
new file mode 100644 (file)
index 0000000..d0411d6
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 - 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 "sclanimator.h"
+
+#ifndef __SCL_ANIMATOR_NUI_H__
+#define __SCL_ANIMATOR_NUI_H__
+
+#include <Evas.h>
+
+namespace scl
+{
+class CSCLAnimatorImplNui : public CSCLAnimatorImpl
+{
+public :
+    CSCLAnimatorImplNui();
+    ~CSCLAnimatorImplNui();
+
+    void init();
+    void fini();
+
+    sclboolean check_animation_supported();
+    void animator_timer(SclAnimationState *state);
+
+private:
+    Evas_Object *m_highlight_ui_object;
+    Evas_Object *m_highlight_ui_object_alternate;
+};
+} /* End of scl namespace */
+#endif //__SCL_ANIMATOR_NUI_H__
diff --git a/scl/sclanimator.cpp b/scl/sclanimator.cpp
new file mode 100644 (file)
index 0000000..180b043
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2012 - 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 "sclanimator.h"
+#ifdef  __WIN32__
+#include "sclanimator-win32.h"
+#elif defined(__EFL__)
+#include "sclanimator-efl.h"
+#elif defined(__NUI__)
+#include "sclanimator-nui.h"
+#elif __GTK__
+#include "sclanimator-gtk.h"
+#else
+#include "sclanimator-cairo.h"
+#endif
+#include "scldebug.h"
+
+#include "sclevents.h"
+#include "sclwindows.h"
+
+using namespace scl;
+
+CSCLAnimator::CSCLAnimator()
+{
+    SCL_DEBUG();
+    m_impl = NULL;
+}
+
+CSCLAnimator::~CSCLAnimator()
+{
+    SCL_DEBUG();
+
+    if (m_impl) {
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+
+void CSCLAnimator::init()
+{
+    CSCLAnimatorImpl *impl = get_scl_animator_impl();
+    if (impl) {
+        impl->init();
+    }
+}
+
+void CSCLAnimator::fini()
+{
+    CSCLAnimatorImpl *impl = get_scl_animator_impl();
+    if (impl) {
+        impl->fini();
+    }
+}
+
+sclboolean CSCLAnimator::check_animation_supported()
+{
+    sclboolean ret = FALSE;
+
+    CSCLAnimatorImpl *impl = get_scl_animator_impl();
+    if (impl) {
+        ret = impl->check_animation_supported();
+    }
+    return ret;
+}
+
+CSCLAnimatorImpl* CSCLAnimator::get_scl_animator_impl()
+{
+    SCL_DEBUG();
+    if (m_impl == 0) {
+#ifdef  __WIN32__
+        m_impl = new CSCLAnimatorImplWin32;
+#elif defined(__EFL__)
+        m_impl = new CSCLAnimatorImplEfl;
+#elif defined(__NUI__)
+        m_impl = new CSCLAnimatorImplNui;
+#elif __GTK__
+        m_impl = new CSCLAnimatorImplGtk;
+#else
+        m_impl = new CSCLAnimatorImplCairo;
+#endif
+    }
+    return m_impl;
+}
+
+CSCLAnimator* CSCLAnimator::get_instance()
+{
+    static CSCLAnimator instance;
+    return &instance;
+}
+
+sclint
+CSCLAnimator::create_animator(SclAnimationDesc *desc)
+{
+    static sclint animator_id = 0;
+
+    if (desc) {
+        animator_id++;
+        /* Just in case for overflow */
+        if (animator_id < 0) animator_id = 0;
+
+        SclAnimationState state;
+        state.active = FALSE;
+        state.rect_cur = desc->rect_from;
+        state.step = 0;
+
+        state.desc = *desc;
+
+        destroy_animator(animator_id);
+        m_animators[animator_id] = state;
+    } else {
+        return NOT_USED;
+    }
+
+    return animator_id;
+}
+
+sclboolean
+CSCLAnimator::destroy_animator(sclint id)
+{
+    sclboolean ret = TRUE;
+
+    std::map<sclint, SclAnimationState>::iterator iter;
+    iter = m_animators.find(id);
+    if (iter != m_animators.end()) {
+        SclAnimationState *state = &(iter->second);
+        state->active = FALSE;
+        m_animators.erase(iter->first);
+    } else {
+        ret = FALSE;
+    }
+
+    sclboolean destroy_timer = TRUE;
+    for (iter = m_animators.begin();iter != m_animators.end();std::advance(iter, 1)) {
+        if (iter != m_animators.end()) {
+            SclAnimationState *state = &(iter->second);
+            if (state->active) {
+                destroy_timer = FALSE;
+            }
+        }
+    }
+
+    if (destroy_timer) {
+        CSCLEvents *events = CSCLEvents::get_instance();
+        if (events) {
+            events->destroy_timer(SCL_TIMER_ANIMATION);
+        }
+    }
+
+    return ret;
+}
+
+sclint
+CSCLAnimator::find_animator_by_type(SCLAnimationType type)
+{
+    sclint ret = NOT_USED;
+
+    for (std::map<sclint, SclAnimationState>::iterator iter = m_animators.begin();
+        iter != m_animators.end();std::advance(iter, 1)) {
+            if (iter != m_animators.end()) {
+                SclAnimationState *state = &(iter->second);
+                if (state->desc.type == type) {
+                    ret = iter->first;
+                }
+            }
+    }
+
+    return ret;
+}
+
+
+SclAnimationState*
+CSCLAnimator::get_animation_state(sclint id)
+{
+    SclAnimationState *ret = NULL;
+
+    std::map<sclint, SclAnimationState>::iterator iter = m_animators.find(id);
+    if (iter != m_animators.end()) {
+        ret = &(iter->second);
+    } else {
+        ret = NULL;
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLAnimator::start_animator(sclint id)
+{
+    sclboolean ret = TRUE;
+
+    std::map<sclint, SclAnimationState>::iterator iter = m_animators.find(id);
+    if (iter != m_animators.end()) {
+        SclAnimationState *state = &(iter->second);
+        state->active = TRUE;
+    } else {
+        ret = FALSE;
+    }
+
+    /*
+    sclboolean start_timer = TRUE;
+    for(std::map<sclint, SclAnimationState>::iterator iter = m_animators.begin();
+        iter != m_animators.end();std::advance(iter, 1)) {
+            if (iter != m_animators.end()) {
+                SclAnimationState *state = &(iter->second);
+                if (state->active) {
+                    start_timer = FALSE;
+                }
+            }
+    }
+
+    if (start_timer) {
+        CSCLEvents *events = CSCLEvents::get_instance();
+        if (events) {
+            events->create_timer(SCL_TIMER_ANIMATION, SCL_ANIMATION_TIMER_INTERVAL, 0);
+        }
+    }
+    */
+    CSCLEvents *events = CSCLEvents::get_instance();
+    if (events) {
+        events->destroy_timer(SCL_TIMER_ANIMATION);
+        events->create_timer(SCL_TIMER_ANIMATION, SCL_ANIMATION_TIMER_INTERVAL, 0);
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLAnimator::stop_animator(sclint id)
+{
+    sclboolean ret = TRUE;
+
+    std::map<sclint, SclAnimationState>::iterator iter;
+    iter = m_animators.find(id);
+    if (iter != m_animators.end()) {
+        SclAnimationState *state = &(iter->second);
+        state->active = FALSE;
+        m_animators.erase(iter->first);
+    } else {
+        ret = FALSE;
+    }
+
+    sclboolean destroy_timer = TRUE;
+    for (iter = m_animators.begin();iter != m_animators.end();std::advance(iter, 1)) {
+        if (iter != m_animators.end()) {
+            SclAnimationState *state = &(iter->second);
+            if (state->active) {
+                destroy_timer = FALSE;
+            }
+        }
+    }
+
+    if (destroy_timer) {
+        CSCLEvents *events = CSCLEvents::get_instance();
+        if (events) {
+            events->destroy_timer(SCL_TIMER_ANIMATION);
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLAnimator::animator_timer_highlight_ui(SclAnimationState *state)
+{
+    sclboolean ret = TRUE;
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+
+    if (state && windows) {
+        SclRectangle rect_from = state->desc.rect_from;
+        SclRectangle rect_to = state->desc.rect_to;
+
+        sclint delta_x = 0; /* We will calculate the X considering circulation */
+        sclint delta_y = rect_to.y - rect_from.y;
+        sclint delta_width = rect_to.width - rect_from.width;
+        sclint delta_height = rect_to.height - rect_from.height;
+
+        state->rect_cur.y = rect_from.y +
+            ((delta_y) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
+        state->rect_cur.width = rect_from.width +
+            ((delta_width) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
+        state->rect_cur.height = rect_from.height +
+            ((delta_height) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
+
+        if (state->desc.circular) {
+            SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+            if (base_window_context) {
+                if (rect_from.x > rect_to.x) {
+                    delta_x = rect_to.x;
+                    delta_x += (base_window_context->geometry.width - rect_from.x);
+                } else {
+                    delta_x = -(rect_from.x);
+                    delta_x -= (base_window_context->geometry.width - rect_to.x);
+                }
+
+                state->rect_cur.x = rect_from.x +
+                    ((delta_x) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
+
+                if (state->rect_cur.x + state->rect_cur.width <= 0) {
+                    /* Make the highlight UI come out from the right side of the window */
+                    state->rect_cur.x += base_window_context->geometry.width;
+                } else if (state->rect_cur.x > base_window_context->geometry.width) {
+                    state->rect_cur.x -= base_window_context->geometry.width;
+                }
+            }
+        } else {
+            delta_x = rect_to.x - rect_from.x;
+
+            state->rect_cur.x = rect_from.x +
+                ((delta_x) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
+        }
+    }
+
+    return ret;
+}
+sclboolean
+CSCLAnimator::animator_timer()
+{
+    sclboolean destroy_timer = TRUE;
+    for (std::map<sclint, SclAnimationState>::iterator iter = m_animators.begin();
+        iter != m_animators.end();std::advance(iter, 1)) {
+            if (iter != m_animators.end()) {
+                CSCLWindows *windows = CSCLWindows::get_instance();
+                SclAnimationState *state = &(iter->second);
+                if (state && state->active && windows) {
+                    state->step++;
+                    if (SCL_ANIMATION_TIMER_INTERVAL * state->step >= state->desc.length) {
+                        state->active = FALSE;
+                    } else {
+                        if (state->desc.type == ANIMATION_TYPE_HIGHLIGHT_UI) {
+                            animator_timer_highlight_ui(state);
+                        }
+                    }
+
+                    CSCLAnimatorImpl *impl = get_scl_animator_impl();
+                    if (impl) {
+                        impl->animator_timer(state);
+                    }
+
+                    if (state->active == FALSE) {
+                        windows->update_window(state->desc.window_to,
+                            state->desc.rect_to.x, state->desc.rect_to.y,
+                            state->desc.rect_to.width, state->desc.rect_to.height);
+                    } else {
+                        destroy_timer = FALSE;
+                    }
+                }
+            }
+    }
+    if (destroy_timer) {
+        CSCLEvents *events = CSCLEvents::get_instance();
+        if (events) {
+            events->destroy_timer(SCL_TIMER_ANIMATION);
+        }
+    }
+    return TRUE;
+}
+
diff --git a/scl/sclanimator.h b/scl/sclanimator.h
new file mode 100644 (file)
index 0000000..3369770
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012 - 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 "scltypes.h"
+#include "sclconfig.h"
+#include "sclstructs.h"
+
+#include <map>
+
+#ifndef __SCL_ANIMATOR_H__
+#define __SCL_ANIMATOR_H__
+
+#ifdef __cplusplus
+//SCL_BEGIN_DECLS
+#endif
+
+namespace scl
+{
+
+/* Currently this SCL Animation class is not designed for specific animations, not for general use.
+   Should refine later to provide general animation behavior */
+typedef enum {
+    ANIMATION_TYPE_NONE,
+    ANIMATION_TYPE_HIGHLIGHT_UI,
+
+    ANIMATION_TYPE_MAX
+}SCLAnimationType;
+
+typedef struct {
+    SCLAnimationType type;
+    sclint length;
+
+    sclwindow window_from;
+    sclwindow window_to;
+
+    SclRectangle rect_from;
+    SclRectangle rect_to;
+
+    sclboolean circular;
+}SclAnimationDesc;
+
+typedef struct {
+    sclboolean active;
+
+    SclAnimationDesc desc;
+    sclint step;
+
+    SclRectangle rect_cur;
+}SclAnimationState;
+
+
+class CSCLAnimatorImpl
+{
+public:
+    CSCLAnimatorImpl() {}
+    virtual ~CSCLAnimatorImpl() {}
+
+    virtual void init() = 0;
+    virtual void fini() = 0;
+
+    /* By default, animation is not supported */
+    virtual sclboolean check_animation_supported() { return FALSE; }
+    virtual void animator_timer(SclAnimationState *state) = 0;
+
+    friend class CSCLAnimator;
+private:
+};
+
+class CSCLAnimator
+{
+private:
+    CSCLAnimator();
+public :
+    virtual ~CSCLAnimator();
+
+    static CSCLAnimator* get_instance();
+
+    void init();
+    void fini();
+
+    /* Some backends may not provide animation feature */
+    sclboolean check_animation_supported();
+
+    sclint create_animator(SclAnimationDesc *desc);
+    sclboolean destroy_animator(sclint id);
+
+    sclint find_animator_by_type(SCLAnimationType type);
+
+    SclAnimationState* get_animation_state(sclint id);
+
+    sclboolean start_animator(sclint id);
+    sclboolean stop_animator(sclint id);
+
+    sclboolean animator_timer();
+
+protected :
+    CSCLAnimatorImpl* get_scl_animator_impl();
+
+    sclboolean animator_timer_highlight_ui(SclAnimationState *state);
+private :
+    CSCLAnimatorImpl* m_impl;
+
+    std::map<sclint, SclAnimationState> m_animators;
+};
+
+
+} /* End of scl namespace */
+
+#ifdef __cplusplus
+//SCL_END_DECLS
+#endif
+
+#endif //__SCL_ANIMATOR_H__
diff --git a/scl/sclbackendcallback.h b/scl/sclbackendcallback.h
new file mode 100644 (file)
index 0000000..0cb22a0
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_BACKENDCALLBACK_H__
+#define __SCL_BACKENDCALLBACK_H__
+
+#include "sclgraphicsinfo.h"
+
+using namespace scl;
+
+//SCL_BEGIN_DECLS
+/* FIXME : Need to check the dependency cause by the next include statement */
+
+//typedef void (*scl_ui_draw_text_cb)(const char *str, int x, int y, int w, int h, int fontsize, void* user_data);
+
+struct ISCLUIGraphicsBackendCallback {
+    //virtual void on_draw_text(const char *str, int x, int y, int w, int h, int fontsize, void* user_data) { }
+    virtual void on_draw_text(const SclFontInfo& font_info, const SclColor& color, const char *str, int pos_x, int pos_y, int w, int h,
+                              SCLLabelAlignment align, int padding_x, int padding_y, int inner_width, int inner_height, void* user_data) { }
+
+    /*
+    const SclFontInfo& font_info, const SclColor& color,
+                               const sclchar *str, SclTextCachedInfo *cachedinfo, sclint pos_x, sclint pos_y, sclint width, sclint height,
+                               SCLLabelAlignment align, sclint padding_x, sclint padding_y,
+                               sclint inner_width, sclint inner_height)
+    */
+
+    virtual void on_draw_image(const char *image_path, int dest_x, int dest_y, int dest_weight, int dest_height, int src_x, int src_y, int src_width, int src_height, void* user_data) { }
+
+    virtual void on_draw_rectangle(int pos_x, int pos_y, int width, int height, bool fill, int fill_color_r, int fill_color_g, int fill_color_b, int fill_color_a, void* user_data) { }
+
+    virtual void update_window(int x, int w, int width, int height, void* user_data) { }
+
+    //virtual void on_draw_image(const char *str, int x, int y, int w, int h, int fontsize, void* user_data) { }
+};
+
+#endif //__SCL_BACKENDCALLBACK_H__
diff --git a/scl/sclconfig.h b/scl/sclconfig.h
new file mode 100644 (file)
index 0000000..2b48208
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_CONFIG_H__
+#define __SCL_CONFIG_H__
+
+#ifndef EXAPI
+#define EXAPI __attribute__ ((visibility("default")))
+#endif
+
+namespace scl
+{
+
+#ifndef IMG_PATH_PREFIX
+#define IMG_PATH_PREFIX "image"
+#endif
+
+/* Display direction definition */
+typedef enum _SCLDisplayMode {
+    DISPLAYMODE_PORTRAIT = 0,  /* portrait display mode */
+    DISPLAYMODE_LANDSCAPE,             /* landscape display mode */
+    DISPLAYMODE_MAX,                   /* maximum count of display mode */
+}SCLDisplayMode;
+
+/* Rotation definition */
+typedef enum _SCLRotation {
+    ROTATION_0 = 0,            /* No rotation */
+    ROTATION_90_CW,            /* 90 degree, clockwise */
+    ROTATION_180,              /* 180 degree */
+    ROTATION_90_CCW,   /* 90 degree, counter-clockwise (Same as 270 degree, clockwise) */
+    ROTATION_MAX,
+}SCLRotation;
+
+/**@brief  Layout and Input mode Style definition */
+typedef enum _SCLLayoutStyle {
+    LAYOUT_STYLE_BASE = 0,
+    LAYOUT_STYLE_POPUP,
+    LAYOUT_STYLE_POPUP_GRAB,
+    MAX_LAYOUT_STYLE
+}SCLLayoutStyle;
+
+/* Key Define */
+
+/**@brief  Button Type definition */
+typedef enum _SCLButtonType {
+    BUTTON_TYPE_NORMAL  = 0,           /**< Normal key */
+    BUTTON_TYPE_GRAB,                          /**< Focus grab */
+    /* No button gets focus when cursor moves out of this button's area */
+    BUTTON_TYPE_SELFISH,
+    /* A button that fires click event when dragged into the button's area */
+    BUTTON_TYPE_DRAG,                          /**< Drag button */
+    /* A button with variant value - ex> [a] -> [b] */
+    BUTTON_TYPE_MULTITAP,                      /**< Multi-tap key */
+    /* A multitap with automatic commitment - ex> ([a] -> a[b]) , ([p] -> p[i] -> pi[n] -> pin[g])*/
+    BUTTON_TYPE_ROTATION,                      /**< Rotation key */
+    BUTTON_TYPE_DIRECTION,                     /**< Direction decided by whole mouse movement from inital point */
+    BUTTON_TYPE_RELATIVE_DIRECTION,    /**< Direction decided by recent mouse movement */
+    BUTTON_TYPE_TOGGLE,                                /** A button that has toggled state */
+    BUTTON_TYPE_UIITEM,                                /** Not a button, just for displaying image */
+    MAX_BUTTON_TYPE                                    /* maximum number of Key type */
+}SCLButtonType;
+
+/* Values used for extra_option field of SclLayoutKeyProperties structure, in case of BUTTON_TYPE_DIRECTION type button */
+#define DIRECTION_EXTRA_OPTION_4_DIRECTIONS 0
+#define DIRECTION_EXTRA_OPTION_8_DIRECTIONS 1
+#define DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_LONG 2
+#define DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG 3
+#define DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN 4
+#define DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN 5
+#define DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE 6
+
+/**@brief Key Type definition */
+typedef enum _SCLKeyType {
+    KEY_TYPE_NONE = 0,         /**< none */
+    KEY_TYPE_CHAR,                     /**< key that can be displayed independently */
+    KEY_TYPE_CONTROL,          /**< key to use as control */
+    KEY_TYPE_MODECHANGE,       /**< key to change mode*/
+    KEY_TYPE_STRING,           /**< key to be displayed as string */
+    KEY_TYPE_USER,                     /**< key to be processed by user custom function */
+    MAX_KEY_TYPE                       /* maximum number of Key type */
+}SCLKeyType;
+
+/**@brief Key Event Type definition */
+typedef enum _SCLEventType {
+    EVENT_TYPE_NONE = 0,       /**< none */
+    EVENT_TYPE_PRESS,          /**< button press event */
+    EVENT_TYPE_MOVE,           /**< button move event */
+    EVENT_TYPE_RELEASE,                /**< button release event */
+    EVENT_TYPE_LONGPRESS,      /**< button longpress event */
+    EVENT_TYPE_REPEAT,         /**< button repeat event */
+    MAX_EVENT_TYPE                     /* maximum number of Key type */
+}SCLEventType;
+
+
+/**@brief Key Modifier definition */
+typedef enum _SCLKeyModifier {
+    KEY_MODIFIER_NONE = 0,                                             /**< none */
+    KEY_MODIFIER_LONGKEY,                                              /**< longkey event */
+    KEY_MODIFIER_MULTITAP_START,                               /**< multitap started */
+    KEY_MODIFIER_MULTITAP_REPEAT,                              /**< multitap repeated */
+    KEY_MODIFIER_MULTITAP_RELEASE,                             /**< multitap released */
+
+    KEY_MODIFIER_DIRECTION_LEFT,                               /**< drag left */
+    KEY_MODIFIER_DIRECTION_RIGHT,                              /**< drag right */
+    KEY_MODIFIER_DIRECTION_UP,                                 /**< drag up */
+    KEY_MODIFIER_DIRECTION_DOWN,                               /**< drag down */
+    KEY_MODIFIER_DIRECTION_UP_LEFT,                            /**< drag up left */
+    KEY_MODIFIER_DIRECTION_UP_RIGHT,                   /**< drag up right */
+    KEY_MODIFIER_DIRECTION_DOWN_LEFT,                  /**< drag down left */
+    KEY_MODIFIER_DIRECTION_DOWN_RIGHT,                 /**< drag down right */
+
+    KEY_MODIFIER_DIRECTION_LEFT_LONG,                  /**< drag left */
+    KEY_MODIFIER_DIRECTION_RIGHT_LONG,                 /**< drag right */
+    KEY_MODIFIER_DIRECTION_UP_LONG,                            /**< drag up */
+    KEY_MODIFIER_DIRECTION_DOWN_LONG,                  /**< drag down */
+    KEY_MODIFIER_DIRECTION_UP_LEFT_LONG,               /**< drag up left */
+    KEY_MODIFIER_DIRECTION_UP_RIGHT_LONG,              /**< drag up right */
+    KEY_MODIFIER_DIRECTION_DOWN_LEFT_LONG,             /**< drag down left */
+    KEY_MODIFIER_DIRECTION_DOWN_RIGHT_LONG,            /**< drag down right */
+
+    KEY_MODIFIER_DIRECTION_LEFT_RETURN,                        /**< drag left */
+    KEY_MODIFIER_DIRECTION_RIGHT_RETURN,               /**< drag right */
+    KEY_MODIFIER_DIRECTION_UP_RETURN,                  /**< drag up */
+    KEY_MODIFIER_DIRECTION_DOWN_RETURN,                        /**< drag down */
+    KEY_MODIFIER_DIRECTION_UP_LEFT_RETURN,             /**< drag up left */
+    KEY_MODIFIER_DIRECTION_UP_RIGHT_RETURN,            /**< drag up right */
+    KEY_MODIFIER_DIRECTION_DOWN_LEFT_RETURN,   /**< drag down left */
+    KEY_MODIFIER_DIRECTION_DOWN_RIGHT_RETURN,  /**< drag down right */
+
+    KEY_MODIFIER_DIRECTION_CURVE_UP_LEFT,              /**< drag up left */
+    KEY_MODIFIER_DIRECTION_CURVE_UP_RIGHT,             /**< drag up right */
+    KEY_MODIFIER_DIRECTION_CURVE_DOWN_LEFT,            /**< drag down left */
+    KEY_MODIFIER_DIRECTION_CURVE_DOWN_RIGHT,   /**< drag down right */
+    KEY_MODIFIER_DIRECTION_CURVE_LEFT_UP,              /**< drag left up */
+    KEY_MODIFIER_DIRECTION_CURVE_LEFT_DOWN,            /**< drag left down */
+    KEY_MODIFIER_DIRECTION_CURVE_RIGHT_UP,             /**< drag right up */
+    KEY_MODIFIER_DIRECTION_CURVE_RIGHT_DOWN,   /**< drag right down */
+
+    KEY_MODIFIER_TOGGLED,                                              /**< toggled state */
+
+    KEY_MODIFIER_MAX                   /* maximum number of Key type */
+}SCLKeyModifier;
+
+
+/**@brief  Popup Type definition */
+typedef enum _SCLPopupType {
+    /**< doesn't use popup */
+    POPUP_TYPE_NONE = 0,
+    /**< to use popup (It is used in extention character sign. After to be selected, this action is continued until selecting another area) */
+    POPUP_TYPE_BTN_RELEASE_POPUP,
+    /**< to use popup (It is used in extention character sign. After to be selected, this action disappears instantly) */
+    POPUP_TYPE_BTN_RELEASE_POPUP_ONCE,
+    /**< to use popup (it is used in extention character sign. This action disappears at Drag-Up */
+    POPUP_TYPE_BTN_PRESS_POPUP_DRAG,
+    /**< to use popup (it is used in extention character sign. This action disappears at Drag-Up */
+    POPUP_TYPE_BTN_LONGPRESS_POPUP,
+    /**< to use popup (it is used in extention character sign. This action disappears at Drag-Up */
+    POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE,
+    /**< to use popup (for multi-tap char) */
+    POPUP_TYPE_AUTO_POPUP,
+    /* maximum number of popup type */
+    MAX_POPUP_TYPE
+}SCLPopupType;
+
+/**@brief Candidate position style definition */
+typedef enum _SCLCandidatePosition {
+    CAND_POS_ABOVE_KEYPAD = 0,
+    CAND_POS_BELOW_TEXT,
+    CAND_POS_MANUAL,
+    MAX_CANDIDATE_POSITION
+}SCLCandidatePosition;
+
+/**@brief Candidate style definition */
+typedef enum _SCLCandidateStyle {
+    CAND_STYLE_DEFAULT = 0,
+    CAND_STYLE_A,
+    CAND_STYLE_B,
+    CAND_STYLE_C,
+    MAX_CANDIDATE_STYLE
+}SCLCandidateStyle;
+
+/**@brief Magnifier display style definition */
+typedef enum _SCLMagnifierStyle {
+    MAGNIFIER_STYLE_LABEL_ONLY = 0,
+    MAGNIFIER_STYLE_SEL_AREA_CAPTURE,
+    MAX_MAGNIFIER_STYLE
+}SCLMagnifierStyle;
+
+/**@brief Preview window position type definition */
+typedef enum _SCLPreviewPosition {
+    PREVIEW_POS_CENTER_OF_APPL_AREA = 0,
+    PREVIEW_POS_ABOVE_SELECTED_BUTTON,
+    PREVIEW_POS_MANUAL,
+    MAX_PREVIEW_POSITION
+}SCLPreviewPosition;
+
+/**@brief Action state definition */
+typedef enum _SCLActionState {
+    ACTION_STATE_BASE_INIT = 0,
+    ACTION_STATE_BASE_PRESS,
+    ACTION_STATE_BASE_MOVING,
+    ACTION_STATE_BASE_RELEASE,
+    ACTION_STATE_BASE_LONGKEY,
+    ACTION_STATE_BASE_REPEATKEY,
+    ACTION_STATE_POPUP_INIT,
+    ACTION_STATE_POPUP_PRESS,
+    ACTION_STATE_POPUP_MOVING,
+    ACTION_STATE_POPUP_RELEASE,
+    ACTION_STATE_POPUP_LONGKEY,
+    ACTION_STATE_POPUP_REPEATKEY,
+    MAX_ACTION_STATE
+}SCLActionState;
+
+/**@brief  Button state definition */
+typedef enum _SCLButtonState {
+    BUTTON_STATE_NORMAL = 0,   /**< normal state */
+    BUTTON_STATE_PRESSED,              /**< pressed state */
+    BUTTON_STATE_DISABLED,             /**< disabled state */
+    BUTTON_STATE_TOGGLED,              /**< toggled state */
+    //BUTTON_STATE_HIGHLIGHT,  /**< highlighted state */
+    //BUTTON_STATE_LONGKEY,            /**< londkey state */
+    SCL_BUTTON_STATE_MAX               /* maximum number of button state */
+}SCLButtonState;
+
+
+/**@brief  Drag Direction definition */
+typedef enum _SCLDragType {
+    DRAG_NONE = 0,             /* doesn't use Drag */
+    DRAG_LEFT,                 /* drag to left side */
+    DRAG_RIGHT,                        /* drag to right side */
+    DRAG_UP,                   /* drag to upper side */
+    DRAG_DOWN,                 /* drag to down side */
+    DRAG_LEFT_TOP,             /* drag to left top side */
+    DRAG_RIGHT_TOP,            /* drag to right top side */
+    DRAG_LEFT_BOTTOM,  /* drag to left bottom side */
+    DRAG_RIGHT_BOTTOM, /* drag to right bottom side */
+    MAX_DRAG,                  /* maximum number of drag type */
+}SCLDragType;
+
+/**@brief  Label alignment definition */
+typedef enum _SCLLabelAlignment {
+    LABEL_ALIGN_LEFT_TOP = 0,
+    LABEL_ALIGN_CENTER_TOP,
+    LABEL_ALIGN_RIGHT_TOP,
+    LABEL_ALIGN_LEFT_MIDDLE,
+    LABEL_ALIGN_CENTER_MIDDLE,
+    LABEL_ALIGN_RIGHT_MIDDLE,
+    LABEL_ALIGN_LEFT_BOTTOM,
+    LABEL_ALIGN_CENTER_BOTTOM,
+    LABEL_ALIGN_RIGHT_BOTTOM,
+    MAX_LABEL_ALIGNMENT
+}SCLLabelAlignment;
+
+/**@brief  Shadow direction definition */
+typedef enum _SCLShadowDirection {
+    SHADOW_DIRECTION_NONE = 0,
+    SHADOW_DIRECTION_LEFT_TOP ,
+    SHADOW_DIRECTION_CENTER_TOP,
+    SHADOW_DIRECTION_RIGHT_TOP,
+    SHADOW_DIRECTION_LEFT_MIDDLE,
+    SHADOW_DIRECTION_CENTER_MIDDLE,
+    SHADOW_DIRECTION_RIGHT_MIDDLE,
+    SHADOW_DIRECTION_LEFT_BOTTOM,
+    SHADOW_DIRECTION_CENTER_BOTTOM,
+    SHADOW_DIRECTION_RIGHT_BOTTOM,
+    MAX_SHADOW_DIRECTION
+}SCLShadowDirection;
+
+/**@brief  timer id */
+typedef enum _SCLTimer {
+    SCL_TIMER_AUTOPOPUP = 100,
+    SCL_TIMER_SHORT_LONGKEY,
+    SCL_TIMER_LONGKEY,
+    SCL_TIMER_REPEATKEY,
+    SCL_TIMER_USERAREA,
+    SCL_TIMER_BUTTON_DELAY,
+    SCL_TIMER_POPUP_TIMEOUT,
+    SCL_TIMER_ANIMATION,
+    SCL_TIMER_AUTOTEST,
+    SCL_TIMER_MULTITAP,
+}SCLTimer;
+
+/**@brief  Feedback style */
+typedef enum _SCLFeedbackStyle {
+    FEEDBACK_STYLE_SOUND,
+    FEEDBACK_STYLE_VIBRATION,
+    MAX_FEEDBACK_STYLE
+}SCLFeedbackStyle;
+
+/**@brief  Touch Offset */
+typedef enum _SCLTouchOffsetLevel {
+    TOUCH_OFFSET_LEVEL_1,
+    TOUCH_OFFSET_LEVEL_2,
+    TOUCH_OFFSET_LEVEL_3,
+    MAX_TOUCH_OFFSET_LEVEL
+}SCLTouchOffsetLevel;
+
+/* Type Limitation definition */
+#define MAX_SIZE_OF_LAYOUT_NAME 255
+#define MAX_SIZE_OF_MULTITAP_CHAR 10
+#define MAX_SIZE_OF_LABEL_FOR_ONE 9
+#define MAX_SIZE_OF_LAYOUT 10
+#define MAX_SIZE_OF_CANDIDATE 50
+#define MAX_PRIVATE_KEY 100
+#define MAX_DISABLED_KEY 100
+#define MAX_SIZE_OF_AUTOPOPUP_STRING 20
+#define MAX_SIZE_OF_MAGNIFIER_STRING 4
+#define MAX_SIZE_OF_SUBLAYOUT_STRING 32
+
+/**@brief  Window Decorator Images */
+typedef enum _SCLWindowDecorator {
+    WND_DECORATOR_TOP_LEFT,
+    WND_DECORATOR_TOP_CENTER,
+    WND_DECORATOR_TOP_RIGHT,
+    WND_DECORATOR_MIDDLE_LEFT,
+    WND_DECORATOR_MIDDLE_CENTER,
+    WND_DECORATOR_MIDDLE_RIGHT,
+    WND_DECORATOR_BOTTOM_LEFT,
+    WND_DECORATOR_BOTTOM_CENTER,
+    WND_DECORATOR_BOTTOM_RIGHT,
+    MAX_WND_DECORATOR,
+}SCLWindowDecorator;
+
+/**@brief  Highligh moving direction */
+typedef enum _SCLHighlightNavigationDirection {
+    HIGHLIGHT_NAVIGATE_NONE,
+    HIGHLIGHT_NAVIGATE_LEFT,
+    HIGHLIGHT_NAVIGATE_RIGHT,
+    HIGHLIGHT_NAVIGATE_UP,
+    HIGHLIGHT_NAVIGATE_DOWN,
+    HIGHLIGHT_NAVIGATE_MAX
+}SCLHighlightNavigationDirection;
+
+/**@brief  SCL Notification to ISEs */
+typedef enum _SCLUINotiType {
+    SCL_UINOTITYPE_POPUP_OPENING,
+    SCL_UINOTITYPE_POPUP_OPENED,
+    SCL_UINOTITYPE_POPUP_CLOSING,
+    SCL_UINOTITYPE_POPUP_CLOSED,
+    SCL_UINOTITYPE_GESTURE_FLICK,
+    SCL_UINOTITYPE_SHIFT_STATE_CHANGE,
+    SCL_UINOTITYPE_INPUT_MODE_CHANGE,
+    SCL_UINOTITYPE_HIGHLIGHT_NAVIGATE,
+    MAX_NOTITYPE,
+}SCLUINotiType;
+
+/**@brief  Current dragging state */
+typedef enum _SCLDragState {
+    SCL_DRAG_STATE_NONE,
+    SCL_DRAG_STATE_LEFT,
+    SCL_DRAG_STATE_RIGHT,
+    SCL_DRAG_STATE_UP,
+    SCL_DRAG_STATE_DOWN,
+    SCL_DRAG_STATE_INVALID,
+    SCL_DRAG_STATE_RETURN,
+    SCL_DRAG_STATE_MAX,
+} SCLDragState;
+
+typedef enum _SCLMultitouchType {
+    SCL_MULTI_TOUCH_TYPE_EXCLUSIVE,                    /* On a new PRESS event, previous touch events will be forcefully released */
+    SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS,      /* On a new PRESS event, previous touch events will be forcefully settled */
+    SCL_MULTI_TOUCH_TYPE_COOPERATIVE,          /* New touch events do not affect previous touch events */
+    SCL_MULTI_TOUCH_TYPE_GRAB_SUB_EVENTS,      /* New touch events are considered to be sub events, not generating button events */
+} SCLMultiTouchType;
+
+/* Shift flag */
+typedef enum _SCLShiftState {
+    SCL_SHIFT_STATE_OFF,
+    SCL_SHIFT_STATE_ON,
+    SCL_SHIFT_STATE_LOCK,
+    SCL_SHIFT_STATE_MAX,
+} SCLShiftState;
+
+/* Shift Multi-touch state */
+typedef enum _SCLShiftMultitouchState {
+    SCL_SHIFT_MULTITOUCH_OFF,                          /* Shift button is set to OFF state */
+    SCL_SHIFT_MULTITOUCH_ON_PRESSED,           /* When OFF state, shift button is just pressed  */
+    SCL_SHIFT_MULTITOUCH_ON_KEY_ENTERED,       /* While the shift button is in pressed state, another key was entered  */
+    SCL_SHIFT_MULTITOUCH_ON_RELEASED,          /* Shift button was released without any other key stroke */
+    SCL_SHIFT_MULTITOUCH_LOCK,                         /* Shift button is set to LOCK state */
+    SCL_SHIFT_MULTITOUCH_MAX,
+} SCLShiftMultitouchState;
+
+/* UI Parser types */
+typedef enum _SCLParserType {
+    SCL_PARSER_TYPE_XML,
+    SCL_PARSER_TYPE_BINARY_XML,
+} SCLParserType;
+
+/* Starting Coordinates Options */
+typedef enum _SCLStartingCoordinatesOption {
+    SCL_STARTING_COORDINATES_OPTION_ALL,                       /* Draw everything relative to the starting coordinate */
+    SCL_STARTING_COORDINATES_OPTION_BUTTONS_ONLY,      /* Affect starting coordinates only to the buttons */
+} SCLStartingCoordinatesOption;
+
+/* SCL predefined Identifiers */
+#define SCL_SHIFT_STATE_OFF_HINT_STRING "Shift Off"
+#define SCL_SHIFT_STATE_ON_HINT_STRING "Shift On"
+#define SCL_SHIFT_STATE_LOCK_HINT_STRING "Shift Lock"
+
+#define SCL_INPUTMODE_AUTOPOPUP 10000
+#define SCL_LAYOUT_AUTOPOPUP 10000
+#define SCL_LAYOUT_AUTOPOPUP_NAME "Hidden Text Popup"
+
+#define SCL_LABEL_PROPERTY_AUTOPOPUP 10000
+#define SCL_LABEL_PROPERTY_CANDIDATE 10001
+#define SCL_LABEL_PROPERTY_ZOOMING 10002
+#define SCL_LABEL_PROPERTY_PREVIEW 10003
+
+#define SCL_LABEL_OVERLENGTH_TEXT_RESIZE_RATE 0.9f
+
+#define SCL_LONGKEY_DURATION 800
+#define SCL_LONGKEY_CANCEL_DIST -1
+#define SCL_AUTOPOPUP_KEY_DURATION 500
+#define SCL_REPEATKEY_DURATION 150
+#define SCL_REPEATKEY_WORD_DELETION_START_DURATION 100
+#define SCL_REPEATKEY_ACCELERATION 10
+#define SCL_REPEATKEY_MIN_DURATION 50
+
+#define SCL_BUTTON_MIN_DURATION 100
+#define SCL_MULTITAP_DEFAULT_DURATION 1000
+
+#define SCL_DIRECTION_RECOG_DIST 60
+#define SCL_DIRECTION_RECOG_DIST_SIDE 20
+#define SCL_DIRECTION_LONG_RECOG_DIST 50
+#define SCL_DIRECTION_RELATIVE_RECOG_DIST 10
+#define SCL_DIRECTION_RELATIVE_DIFFDIR_RECOG_DIST 30
+
+#define SCL_DRAG_CURVE_RECOG_DIST 70
+#define SCL_DRAG_CURVE_4_DIRECTION_ANGLE_VALUE 1.0f // ratio between x and y for determining 4 direction, 3 means atan(1/3) degree
+#define SCL_DRAG_CURVE_FINAL_ANGLE_VALUE 3.0f // ratio between x and y for determining final drag curve, 3 means atan(1/3) degree
+
+#define SCL_DRAG_RETURN_RECOG_THRESHOLD_RETURN 1.1f // In RETURN drag state, apply this value for checking drag return action
+#define SCL_DRAG_RETURN_RECOG_THRESHOLD_OTHER 0.9f // In non-NONE drag state, apply this value for checking drag return action
+#define SCL_DRAG_RETURN_RECOG_DIST_BACKWARD 20
+#define SCL_DRAG_RETURN_RECOG_ANGLE_BACKWARD (M_PI * 3) / 4
+
+#define SCL_AUTOTEST_TIMER_INTERVAL 20
+#define SCL_AUTOTEST_TIMER_INITIAL_INTERVAL 3000
+#define SCL_AUTOTEST_NUM 500
+
+#define SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_X 15
+#define SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_Y 20
+
+#define SCL_FLICK_GESTURE_RECOG_THRESHOLD 200
+#define SCL_FLICK_GESTURE_RECOG_TIME 500
+
+#define SCL_AUTO_DETECT_PORTRAIT_LANDSCAPE TRUE
+
+/* FIXME : This should be configurable also */
+#define SCL_HIGHLIGHT_UI_IMAGE "B09_Qwerty_btn_highlight.png"
+
+#define SCL_ANIMATION_TIMER_INTERVAL (1000 / 30) // 30 frames per second
+#define SCL_ANIMATION_TIME 300 // Animation for 300 ms
+
+typedef enum _SCLDebugMode {
+    DEBUGMODE_DISABLED,
+    DEBUGMODE_DISPLAY_INTERNAL,
+    DEBUGMODE_AUTOTEST,
+}SCLDebugMode;
+
+}
+
+#endif //__SCL_CONFIG_H__
diff --git a/scl/sclcontext.cpp b/scl/sclcontext.cpp
new file mode 100644 (file)
index 0000000..aaf2345
--- /dev/null
@@ -0,0 +1,712 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+
+#include "sclcontext.h"
+#include "scldebug.h"
+#include "sclwindows.h"
+#include "sclutils.h"
+#include "sclresourcecache.h"
+#include "sclres.h"
+#include <algorithm>
+
+//#include "sclresource.h"
+
+using namespace scl;
+
+CSCLContext::CSCLContext()
+{
+    SCL_DEBUG();
+
+    reset();
+}
+
+CSCLContext::~CSCLContext()
+{
+    SCL_DEBUG();
+}
+
+CSCLContext*
+CSCLContext::get_instance()
+{
+    static CSCLContext instance;
+    return &instance;
+}
+
+void
+CSCLContext::reset()
+{
+    SCL_DEBUG();
+
+    m_display_mode = DISPLAYMODE_PORTRAIT;
+    m_input_mode = 0;
+
+    m_shift_state = SCL_SHIFT_STATE_OFF;
+    m_shift_multi_touch_state = SCL_SHIFT_MULTITOUCH_OFF;
+
+    m_rotation = ROTATION_0;
+    m_prev_display_mode = DISPLAYMODE_PORTRAIT;
+    m_prev_input_mode = NOT_USED;
+
+    m_hidden = false;
+    m_caps_lock_mode = false;
+
+    m_magnifier_enabled = TRUE;
+    m_sound_enabled = TRUE;
+    m_vibration_enabled = TRUE;
+    m_shift_multi_touch_enabled = TRUE;
+    m_highlight_ui_enabled = FALSE;
+    m_highlight_ui_animation_enabled = FALSE;
+
+    m_tts_enabled = FALSE;
+    m_cur_highlighted_key = 0;
+    m_cur_highlighted_window = SCLWINDOW_INVALID;
+
+    m_multi_touch_context.clear();
+    m_last_touch_device_id = SCLTOUCHDEVICE_INVALID;
+
+    m_last_pressed_window = SCLWINDOW_INVALID;
+    m_last_pressed_key = NOT_USED;
+
+    m_last_event_fired_window = SCLWINDOW_INVALID;
+    m_last_event_fired_key = NOT_USED;
+
+    memset(m_cur_sub_layout, 0x00, sizeof(m_cur_sub_layout));
+}
+
+sclshort
+CSCLContext::get_popup_layout(sclwindow window) const
+{
+    SCL_DEBUG();
+
+    sclshort ret = NOT_USED;
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    if (!windows) return ret;
+
+    //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+    SclWindowContext *window_context = windows->get_window_context(window);
+
+    if (window_context) {
+        ret = window_context->layout;
+    }
+
+    return ret;
+}
+
+void
+CSCLContext::set_popup_layout(sclwindow window, sclshort val)
+{
+    SCL_DEBUG();
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    if (!windows) return;
+
+    //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+    SclWindowContext *window_context = windows->get_window_context(window);
+
+    if (window_context) {
+        window_context->layout = val;
+    }
+}
+
+void
+CSCLContext::set_base_layout(sclshort val)
+{
+    SCL_DEBUG();
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    if (!windows) return;
+
+    //SclWindowContext *window_context = windows->get_window_context(windows->get_base_window(), FALSE);
+    SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());
+    if (window_context) {
+        window_context->layout = val;
+    }
+}
+
+sclshort
+CSCLContext::get_base_layout() const
+{
+    SCL_DEBUG();
+
+    sclshort ret = NOT_USED;
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    if (!windows) return ret;
+
+    //SclWindowContext *window_context = windows->get_window_context(windows->get_base_window(), FALSE);
+    SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());
+    if (window_context) {
+        ret = window_context->layout;
+    }
+
+    return ret;
+}
+
+scl16
+CSCLContext::get_cur_pressed_event_id(scltouchdevice touch_id)
+{
+    scl16 ret = NOT_USED;
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->event_id;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_cur_pressed_event_id(scltouchdevice touch_id, scl16 id)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        multi_touch_context->event_id = id;
+    }
+}
+
+scl8
+CSCLContext::get_cur_pressed_key(scltouchdevice touch_id)
+{
+    scl8 ret = NOT_USED;
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->cur_pressed_key;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_cur_pressed_key(scltouchdevice touch_id, scl8 val)
+{
+    MultiTouchContext *window_context = find_multi_touch_context(touch_id);
+    if (window_context) {
+        window_context->cur_pressed_key = val;
+    }
+}
+
+sclwindow
+CSCLContext::get_cur_pressed_window(scltouchdevice touch_id)
+{
+    sclwindow ret = SCLWINDOW_INVALID;
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->cur_pressed_window;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_cur_pressed_window(scltouchdevice touch_id, sclwindow val)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        multi_touch_context->cur_pressed_window = val;
+    }
+}
+
+SclPoint
+CSCLContext::get_cur_pressed_point(scltouchdevice touch_id)
+{
+    SclPoint ret = {0, 0};
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->cur_pressed_point;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_cur_pressed_point(scltouchdevice touch_id, sclint x, sclint y)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        multi_touch_context->cur_pressed_point.x = x;
+        multi_touch_context->cur_pressed_point.y = y;
+        set_farthest_move_point(touch_id, x, y); // reset farthest move point
+    }
+}
+
+SclPoint
+CSCLContext::get_cur_moving_point(scltouchdevice touch_id)
+{
+    SclPoint ret = {0, 0};
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->cur_moving_point;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_cur_moving_point(scltouchdevice touch_id, sclint x, sclint y)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        multi_touch_context->cur_moving_point.x = x;
+        multi_touch_context->cur_moving_point.y = y;
+    }
+}
+
+sclwindow
+CSCLContext::get_cur_moving_window(scltouchdevice touch_id)
+{
+    sclwindow ret = SCLWINDOW_INVALID;
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->cur_moving_window;
+    }
+    return ret;
+}
+
+
+void
+CSCLContext::set_cur_moving_window(scltouchdevice touch_id, sclwindow window)
+{
+    MultiTouchContext *window_context = find_multi_touch_context(touch_id);
+    if (window_context) {
+        window_context->cur_moving_window = window;
+    }
+}
+
+struct timeval
+CSCLContext::get_cur_pressed_time(scltouchdevice touch_id)
+{
+    struct timeval ret = {0, 0};
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->cur_pressed_time;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_cur_pressed_time(scltouchdevice touch_id)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        gettimeofday(&(multi_touch_context->cur_pressed_time), NULL);
+    }
+}
+
+SclPoint
+CSCLContext::get_farthest_move_point(scltouchdevice touch_id)
+{
+    SclPoint ret = {0, 0};
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->farthest_move_point;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_farthest_move_point(scltouchdevice touch_id, sclint x, sclint y)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        if (utils) {
+            multi_touch_context->farthest_move_dist =
+                utils->get_approximate_distance(x, y,
+                multi_touch_context->cur_pressed_point.x, multi_touch_context->cur_pressed_point.y);
+        }
+
+        multi_touch_context->farthest_move_point.x = x;
+        multi_touch_context->farthest_move_point.y = y;
+    }
+}
+
+sclint
+CSCLContext::get_farthest_move_dist(scltouchdevice touch_id)
+{
+    sclint ret = 0;
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->farthest_move_dist;
+    }
+    return ret;
+}
+
+SCLDragState
+CSCLContext::get_cur_drag_state(scltouchdevice touch_id)
+{
+    SCLDragState ret = SCL_DRAG_STATE_NONE;
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->cur_drag_state;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_cur_drag_state(scltouchdevice touch_id, SCLDragState state)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        multi_touch_context->cur_drag_state = state;
+    }
+}
+
+SCLKeyModifier
+CSCLContext::get_cur_key_modifier(scltouchdevice touch_id)
+{
+    SCLKeyModifier ret = KEY_MODIFIER_NONE;
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->cur_key_modifier;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_cur_key_modifier(scltouchdevice touch_id, SCLKeyModifier modifier)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        multi_touch_context->cur_key_modifier = modifier;
+    }
+}
+
+scl8
+CSCLContext::get_prev_pressed_key(scltouchdevice touch_id)
+{
+    scl8 ret = NOT_USED;
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->prev_pressed_key;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_prev_pressed_key(scltouchdevice touch_id, scl8 val)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        multi_touch_context->prev_pressed_key = val;
+    }
+}
+
+sclwindow
+CSCLContext::get_prev_pressed_window(scltouchdevice touch_id)
+{
+    sclwindow ret = SCLWINDOW_INVALID;
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->prev_pressed_window;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_prev_pressed_window(scltouchdevice touch_id, sclwindow val)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        multi_touch_context->prev_pressed_window = val;
+    }
+}
+
+SclPoint
+CSCLContext::get_prev_moving_point(scltouchdevice touch_id)
+{
+    SclPoint ret = {0, 0};
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->prev_moving_point;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_prev_moving_point(scltouchdevice touch_id, sclint x, sclint y)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        multi_touch_context->prev_moving_point.x = x;
+        multi_touch_context->prev_moving_point.y = y;
+    }
+}
+
+SCLDragState
+CSCLContext::get_prev_drag_state(scltouchdevice touch_id)
+{
+    SCLDragState ret = SCL_DRAG_STATE_NONE;
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        ret = multi_touch_context->prev_drag_state;
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_prev_drag_state(scltouchdevice touch_id, SCLDragState state)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        multi_touch_context->prev_drag_state = state;
+    }
+}
+
+void
+CSCLContext::create_multi_touch_context(scltouchdevice touch_id, sclboolean is_sub_event)
+{
+    MultiTouchContext new_multi_touch_context;
+    memset(&new_multi_touch_context, 0x00, sizeof(MultiTouchContext));
+    new_multi_touch_context.used = TRUE;
+    new_multi_touch_context.cur_pressed_key = NOT_USED;
+    new_multi_touch_context.cur_pressed_window = SCLWINDOW_INVALID;
+    new_multi_touch_context.event_id = 0;
+    new_multi_touch_context.prev_pressed_key = NOT_USED;
+    new_multi_touch_context.prev_pressed_window = SCLWINDOW_INVALID;
+    new_multi_touch_context.cur_pressed_point.x = new_multi_touch_context.cur_pressed_point.y = 0;
+    new_multi_touch_context.cur_pressed_time.tv_sec = new_multi_touch_context.cur_pressed_time.tv_usec = 0;
+    new_multi_touch_context.cur_drag_state = SCL_DRAG_STATE_NONE;
+    new_multi_touch_context.is_sub_event = is_sub_event;
+    m_multi_touch_context[touch_id] = new_multi_touch_context;
+
+    m_multi_touch_seq.insert(m_multi_touch_seq.end(), touch_id);
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    if (utils) {
+        for (std::list<scltouchdevice>::iterator iter = m_multi_touch_seq.begin();iter != m_multi_touch_seq.end();std::advance(iter, 1)) {
+            utils->log("LIST : %d\n", *iter);
+        }
+        utils->log("\n");
+    }
+}
+
+void
+CSCLContext::destroy_multi_touch_context(scltouchdevice touch_id)
+{
+    MultiTouchContext *multi_touch_context = find_multi_touch_context(touch_id);
+    if (multi_touch_context) {
+        memset(multi_touch_context, 0x00, sizeof(MultiTouchContext));
+        m_multi_touch_context.erase(touch_id);
+    }
+
+    sclboolean bFound = TRUE;
+    std::list<scltouchdevice>::iterator iter;
+    do {
+        iter = std::find(m_multi_touch_seq.begin(), m_multi_touch_seq.end(), touch_id);
+        if (iter != m_multi_touch_seq.end()) {
+            m_multi_touch_seq.erase(iter);
+        } else {
+            bFound = FALSE;
+        }
+    } while (bFound);
+
+    /*
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    if (utils) {
+        for(iter = m_multi_touch_seq.begin();iter != m_multi_touch_seq.end();std::advance(iter, 1)) {
+            utils->log("LIST : %d\n", *iter);
+        }
+        utils->log("\n");
+    }
+    */
+}
+
+MultiTouchContext*
+CSCLContext::find_multi_touch_context(scltouchdevice touch_id)
+{
+    MultiTouchContext* ret = NULL;
+    std::map<scltouchdevice, MultiTouchContext>::iterator iter = m_multi_touch_context.find(touch_id);
+    if (iter != m_multi_touch_context.end()) {
+        ret = &(iter->second);
+    }
+
+    return ret;
+}
+
+sclint
+CSCLContext::get_multi_touch_context_num()
+{
+    return m_multi_touch_seq.size();
+}
+
+sclboolean
+CSCLContext::get_multi_touch_event(sclint order, SclUIEventDesc *desc)
+{
+    sclboolean ret = FALSE;
+    sclint index = 0;
+
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    if (!cache) return ret;
+    for (std::list<scltouchdevice>::iterator list_iter = m_multi_touch_seq.begin();
+        !ret && list_iter != m_multi_touch_seq.end();std::advance(list_iter, 1)) {
+            if (index == order) {
+                MultiTouchContext *multi_touch_context = find_multi_touch_context(*list_iter);
+                if (multi_touch_context) {
+                    const SclLayoutKeyCoordinate *coordinate =
+                        cache->get_cur_layout_key_coordinate(multi_touch_context->cur_pressed_window,
+                            multi_touch_context->cur_pressed_key);
+
+                    if (coordinate) {
+                        SCLShiftState shift_index = get_shift_state();
+                        if (shift_index >= SCL_SHIFT_STATE_MAX) shift_index = SCL_SHIFT_STATE_OFF;
+                        desc->key_event = coordinate->key_event[shift_index][0];
+                        desc->key_value = coordinate->key_value[shift_index][0];
+                        desc->key_type = coordinate->key_type;
+                    } else {
+                        desc->key_event = 0;
+                        desc->key_value = NULL;
+                        desc->key_type = KEY_TYPE_NONE;
+                    }
+                    desc->key_modifier = multi_touch_context->cur_key_modifier;
+
+                    desc->touch_id = (*list_iter);
+                    desc->mouse_pressed_point = multi_touch_context->cur_pressed_point;
+                    desc->mouse_current_point = multi_touch_context->cur_moving_point;
+                    desc->mouse_farthest_point = multi_touch_context->farthest_move_point;
+
+                    desc->touch_event_order = index;
+
+                    desc->event_type = EVENT_TYPE_NONE;
+
+                    ret = TRUE;
+                }
+            }
+            index++;
+    }
+
+    return ret;
+}
+
+sclint
+CSCLContext::get_multi_touch_event_order(scltouchdevice touch_id)
+{
+    sclint ret = -1;
+    sclint iSeqIndex = 0;
+
+    for (std::list<scltouchdevice>::iterator list_iter = m_multi_touch_seq.begin();
+        (ret == -1) && list_iter != m_multi_touch_seq.end();std::advance(list_iter, 1)) {
+            if (touch_id == (*list_iter)) {
+                ret = iSeqIndex;
+            } else {
+                iSeqIndex++;
+            }
+    }
+
+    return ret;
+}
+
+sclchar* CSCLContext::get_cur_sublayout()
+{
+    return m_cur_sub_layout;
+}
+
+sclboolean CSCLContext::set_cur_sublayout(const sclchar* sublayout)
+{
+    sclboolean ret = FALSE;
+    if (sublayout) {
+        strncpy(m_cur_sub_layout, sublayout, MAX_SIZE_OF_SUBLAYOUT_STRING);
+        m_cur_sub_layout[MAX_SIZE_OF_SUBLAYOUT_STRING - 1] = '\0';
+    } else {
+        m_cur_sub_layout[0] = '\0';
+    }
+    return ret;
+}
+
+void
+CSCLContext::set_custom_magnifier_label(scltouchdevice touch_id, sclint index, const sclchar* label)
+{
+    if (scl_check_arrindex(index, MAX_SIZE_OF_LABEL_FOR_ONE)) {
+        MagnifierCustomLabelIdx label_index;
+        label_index.touch_id = touch_id;
+        label_index.index = index;
+        if (label) {
+            m_custom_magnifier_label[label_index] = std::string(label);
+        } else {
+            MagnifierCustomLabelIdxMap::iterator iter = m_custom_magnifier_label.find(label_index);
+            if (iter != m_custom_magnifier_label.end()) {
+                m_custom_magnifier_label.erase(iter);
+            }
+        }
+    }
+}
+
+const sclchar*
+CSCLContext::get_custom_magnifier_label(scltouchdevice touch_id, sclint index)
+{
+    MagnifierCustomLabelIdx label_index;
+    label_index.touch_id = touch_id;
+    label_index.index = index;
+
+    const sclchar* ret = NULL;
+
+    if (scl_check_arrindex(index, MAX_SIZE_OF_LABEL_FOR_ONE)) {
+        MagnifierCustomLabelIdxMap::iterator iter = m_custom_magnifier_label.find(label_index);
+        if (iter != m_custom_magnifier_label.end()) {
+            ret = (iter->second).c_str();
+        }
+    }
+
+    return ret;
+}
+
+SCLShiftState CSCLContext::get_shift_state() const
+{
+    SCLShiftState ret = SCL_SHIFT_STATE_OFF;
+    if (m_shift_state < SCL_SHIFT_STATE_MAX) {
+        ret = m_shift_state;
+    }
+    return ret;
+}
+
+void CSCLContext::set_shift_state(SCLShiftState val)
+{
+    if (val < SCL_SHIFT_STATE_MAX) {
+        m_shift_state = val;
+        if (val == SCL_SHIFT_STATE_OFF) {
+            m_shift_multi_touch_state = SCL_SHIFT_MULTITOUCH_OFF;
+        } else if (val == SCL_SHIFT_STATE_ON) {
+            m_shift_multi_touch_state = SCL_SHIFT_MULTITOUCH_ON_RELEASED;
+        } else if (val == SCL_SHIFT_STATE_LOCK) {
+            m_shift_multi_touch_state = SCL_SHIFT_MULTITOUCH_LOCK;
+        }
+    }
+}
+
+sclboolean CSCLContext::get_caps_lock_mode() const
+{
+    return m_caps_lock_mode;
+}
+
+void CSCLContext::set_caps_lock_mode(sclboolean val)
+{
+    m_caps_lock_mode = val;
+}
+
+SCLShiftMultitouchState CSCLContext::get_shift_multi_touch_state() const
+{
+    SCLShiftMultitouchState ret = SCL_SHIFT_MULTITOUCH_OFF;
+    if (m_shift_multi_touch_state < SCL_SHIFT_MULTITOUCH_MAX) {
+        ret = m_shift_multi_touch_state;
+    }
+    return ret;
+}
+
+void CSCLContext::set_shift_multi_touch_state(SCLShiftMultitouchState val)
+{
+    if (val < SCL_SHIFT_MULTITOUCH_MAX) {
+        m_shift_multi_touch_state = val;
+    }
+}
diff --git a/scl/sclcontext.h b/scl/sclcontext.h
new file mode 100644 (file)
index 0000000..9f70bbd
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_CONTEXT_H__
+#define __SCL_CONTEXT_H__
+
+//SCL_BEGIN_DECLS
+#include <sys/time.h>
+#include "scltypes.h"
+#include "sclconfig.h"
+#include "sclstructs.h"
+#include "scleventcallback.h"
+#include <map>
+#include <list>
+#include <string>
+
+namespace scl
+{
+
+typedef struct { // A context information dependant on each multitouch events
+    sclboolean used;
+
+    scl8 cur_pressed_key;
+    sclwindow cur_pressed_window;
+    SclPoint cur_pressed_point;
+    struct timeval cur_pressed_time;
+
+    sclwindow cur_moving_window;
+    SclPoint cur_moving_point;
+
+    SCLDragState cur_drag_state;
+    SCLKeyModifier cur_key_modifier;
+
+    SclPoint farthest_move_point;
+    sclint farthest_move_dist;
+
+    scl8 prev_pressed_key;
+    sclwindow prev_pressed_window;
+
+    SclPoint prev_moving_point;
+    SCLDragState prev_drag_state;
+
+    scl16 event_id;
+
+    sclboolean is_sub_event;
+} MultiTouchContext;
+
+typedef struct { // A struct for identifying Magnifier custom label information
+    scltouchdevice touch_id;
+    sclint index;
+} MagnifierCustomLabelIdx;
+class MagnifierCustomLabelIdxCompare { // Comparison class for MagnifierCustomLabelIdx
+public:
+    bool operator()(const MagnifierCustomLabelIdx x, const MagnifierCustomLabelIdx y) {
+        if (x.touch_id != y.touch_id) {
+            return x.touch_id > y.touch_id;
+        } else {
+            return x.index > y.index;
+        }
+    }
+};
+typedef std::map<MagnifierCustomLabelIdx, std::string, MagnifierCustomLabelIdxCompare> MagnifierCustomLabelIdxMap;
+
+
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLContext
+{
+private:
+    CSCLContext();
+public:
+    virtual ~CSCLContext();
+
+    /* reset to the default context status */
+    void reset();
+
+    /* for singleton */
+    static CSCLContext* get_instance();
+
+    SCLDisplayMode get_display_mode() const {
+        return m_display_mode;
+    }
+    void set_display_mode(SCLDisplayMode val) {
+        m_prev_display_mode = m_display_mode;
+        m_display_mode = val;
+    }
+
+    scl8 get_input_mode() const {
+        return m_input_mode;
+    }
+    void set_input_mode(scl8 val) {
+        m_prev_input_mode = m_input_mode;
+        m_input_mode = val;
+    }
+
+    sclshort get_base_layout() const;
+    void set_base_layout(sclshort val);
+
+    sclshort get_popup_layout(sclwindow window) const;
+    void set_popup_layout(sclwindow window, sclshort val);
+
+    SCLShiftState get_shift_state() const;
+    void set_shift_state(SCLShiftState val);
+
+    sclboolean get_caps_lock_mode() const;
+    void set_caps_lock_mode(sclboolean val);
+
+    SCLShiftMultitouchState get_shift_multi_touch_state() const;
+    void set_shift_multi_touch_state(SCLShiftMultitouchState val);
+
+    SCLDisplayMode get_prev_display_mode() const {
+        return m_prev_display_mode;
+    }
+    scl8 get_prev_inputmode() const {
+        return m_prev_input_mode;
+    }
+
+    sclboolean get_hidden_state() const {
+        return m_hidden;
+    }
+    void set_hidden_state(sclboolean val) {
+        m_hidden = val;
+    }
+
+    SCLRotation get_rotation() const {
+        return m_rotation;
+    }
+    void set_rotation(SCLRotation val) {
+        m_rotation = val;
+    }
+
+    void set_magnifier_enabled(sclboolean enabled) {
+        m_magnifier_enabled = enabled;
+    }
+    sclboolean get_magnifier_enabled() {
+        return m_magnifier_enabled;
+    }
+    void set_sound_enabled(sclboolean enabled) {
+        m_sound_enabled = enabled;
+    }
+    sclboolean get_sound_enabled() {
+        return m_sound_enabled;
+    }
+    void set_vibration_enabled(sclboolean enabled) {
+        m_vibration_enabled = enabled;
+    }
+    sclboolean get_vibration_enabled() {
+        return m_vibration_enabled;
+    }
+    void set_shift_multi_touch_enabled(sclboolean enabled) {
+        m_shift_multi_touch_enabled = enabled;
+    }
+    sclboolean get_shift_multi_touch_enabled() {
+        return m_shift_multi_touch_enabled;
+    }
+    void set_highlight_ui_enabled(sclboolean enabled) {
+        m_highlight_ui_enabled = enabled;
+    }
+    sclboolean get_highlight_ui_enabled() {
+        return m_highlight_ui_enabled;
+    }
+    void set_highlight_ui_animation_enabled(sclboolean enabled) {
+        m_highlight_ui_animation_enabled = enabled;
+    }
+    sclboolean get_highlight_ui_animation_enabled() {
+        return m_highlight_ui_animation_enabled;
+    }
+
+    scl8 get_last_pressed_key() {
+        return m_last_pressed_key;
+    }
+    void set_last_pressed_key(scl8 val) {
+        m_last_pressed_key = val;
+    }
+    sclwindow get_last_pressed_window() {
+        return m_last_pressed_window;
+    }
+    void set_last_pressed_window(sclwindow window) {
+        m_last_pressed_window = window;
+    }
+
+    scl8 get_last_event_fired_key() {
+        return m_last_event_fired_key;
+    }
+    void set_last_event_fired_key(scl8 val) {
+        m_last_event_fired_key = val;
+    }
+    sclwindow get_last_event_fired_window() {
+        return m_last_event_fired_window;
+    }
+    void set_last_event_fired_window(sclwindow window) {
+        m_last_event_fired_window = window;
+    }
+
+    scltouchdevice get_last_touch_device_id() const {
+        return m_last_touch_device_id;
+    }
+    void set_last_touch_device_id(scltouchdevice touch_id) {
+        m_last_touch_device_id = touch_id;
+    }
+
+    void set_tts_enabled(sclboolean enabled) {
+        m_tts_enabled = enabled;
+    }
+
+    sclboolean get_tts_enabled() {
+        return m_tts_enabled;
+    }
+
+    void set_cur_highlighted_key(scl8 val) {
+        m_cur_highlighted_key = val;
+    }
+
+    scl8 get_cur_highlighted_key() {
+        return m_cur_highlighted_key;
+    }
+
+    void set_cur_highlighted_window(sclwindow window) {
+        m_cur_highlighted_window = window;
+    }
+
+    sclwindow get_cur_highlighted_window() {
+        return m_cur_highlighted_window;
+    }
+
+    void create_multi_touch_context(scltouchdevice touch_id, sclboolean is_sub_event = FALSE);
+    void destroy_multi_touch_context(scltouchdevice touch_id);
+    MultiTouchContext* find_multi_touch_context(scltouchdevice touch_id);
+
+    scl16 get_cur_pressed_event_id(scltouchdevice touch_id);
+    void set_cur_pressed_event_id(scltouchdevice touch_id, scl16 id);
+    scl8 get_cur_pressed_key(scltouchdevice touch_id);
+    void set_cur_pressed_key(scltouchdevice touch_id, scl8 val);
+    sclwindow get_cur_pressed_window(scltouchdevice touch_id);
+    void set_cur_pressed_window(scltouchdevice touch_id, sclwindow window);
+    SclPoint get_cur_pressed_point(scltouchdevice touch_id);
+    void set_cur_pressed_point(scltouchdevice touch_id, sclint x, sclint y);
+    struct timeval get_cur_pressed_time(scltouchdevice touch_id);
+    void set_cur_pressed_time(scltouchdevice touch_id);
+
+    void set_custom_magnifier_label(scltouchdevice touch_id, sclint index, const sclchar* label);
+    const sclchar* get_custom_magnifier_label(scltouchdevice touch_id, sclint index);
+
+    SclPoint get_cur_moving_point(scltouchdevice touch_id);
+    void set_cur_moving_point(scltouchdevice touch_id, sclint x, sclint y);
+    sclwindow get_cur_moving_window(scltouchdevice touch_id);
+    void set_cur_moving_window(scltouchdevice touch_id, sclwindow window);
+    SclPoint get_farthest_move_point(scltouchdevice touch_id);
+    void set_farthest_move_point(scltouchdevice touch_id, sclint x, sclint y);
+    sclint get_farthest_move_dist(scltouchdevice touch_id);
+
+    SCLDragState get_cur_drag_state(scltouchdevice touch_id);
+    void set_cur_drag_state(scltouchdevice touch_id, SCLDragState state);
+    SCLKeyModifier get_cur_key_modifier(scltouchdevice touch_id);
+    void set_cur_key_modifier(scltouchdevice touch_id, SCLKeyModifier modifier);
+
+    scl8 get_prev_pressed_key(scltouchdevice touch_id);
+    void set_prev_pressed_key(scltouchdevice touch_id, scl8 val);
+    sclwindow get_prev_pressed_window(scltouchdevice touch_id);
+    void set_prev_pressed_window(scltouchdevice touch_id, sclwindow window);
+
+    SclPoint get_prev_moving_point(scltouchdevice touch_id);
+    void set_prev_moving_point(scltouchdevice touch_id, sclint x, sclint y);
+    SCLDragState get_prev_drag_state(scltouchdevice touch_id);
+    void set_prev_drag_state(scltouchdevice touch_id, SCLDragState state);
+
+    sclint get_multi_touch_context_num();
+    sclboolean get_multi_touch_event(sclint order, SclUIEventDesc *desc);
+    sclint get_multi_touch_event_order(scltouchdevice touch_id);
+
+    sclchar* get_cur_sublayout();
+    sclboolean set_cur_sublayout(const sclchar* sublayout);
+
+protected:
+    /* stores the current context */
+    SCLDisplayMode m_display_mode;
+    scl8 m_input_mode;
+
+    /* stores the last context */
+    SCLDisplayMode m_prev_display_mode;
+    scl8 m_prev_input_mode;
+
+    sclboolean m_hidden;
+    SCLShiftState m_shift_state;
+    sclboolean m_caps_lock_mode;
+    SCLShiftMultitouchState m_shift_multi_touch_state;
+
+    sclchar m_cur_sub_layout[MAX_SIZE_OF_SUBLAYOUT_STRING];
+
+    SCLRotation m_rotation;
+
+    sclboolean m_magnifier_enabled;
+    sclboolean m_sound_enabled;
+    sclboolean m_vibration_enabled;
+    sclboolean m_shift_multi_touch_enabled;
+    sclboolean m_highlight_ui_enabled;
+    sclboolean m_highlight_ui_animation_enabled;
+
+    sclwindow m_last_pressed_window;
+    scl8 m_last_pressed_key;
+
+    sclwindow m_last_event_fired_window;
+    scl8 m_last_event_fired_key;
+
+    sclboolean m_tts_enabled;
+    scl8 m_cur_highlighted_key;
+    sclwindow m_cur_highlighted_window;
+
+    scltouchdevice m_last_touch_device_id;
+    std::map<scltouchdevice, MultiTouchContext> m_multi_touch_context;
+    std::list<scltouchdevice> m_multi_touch_seq;
+
+    MagnifierCustomLabelIdxMap m_custom_magnifier_label;
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_CONTEXT_H__
diff --git a/scl/sclcontroller.cpp b/scl/sclcontroller.cpp
new file mode 100644 (file)
index 0000000..a6101b4
--- /dev/null
@@ -0,0 +1,4126 @@
+/*
+ * Copyright (c) 2012 - 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 <time.h>
+#include <math.h>
+#include <assert.h>
+#include <vector>
+
+#include "sclcontroller.h"
+#include "scldebug.h"
+#include "sclresourcecache.h"
+#include "sclactionstate.h"
+#include "scluibuilder.h"
+#include "sclkeydefines.h"
+#include "sclfeedback.h"
+#include "sclerroradjustment.h"
+#include "sclimageproxy.h"
+#include "sclres_manager.h"
+#include "scleventhandler.h"
+#include "sclanimator.h"
+#include "sclkeyfocushandler.h"
+#include <dlog.h>
+
+//#define DIRECTLY_DRAW_ON_EVENTS
+
+using namespace scl;
+
+static sclboolean
+_play_tts_for_input_mode_name(int mode) {
+    SCL_DEBUG();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    if (context && context->get_tts_enabled() == FALSE) {
+        return FALSE;
+    }
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (!sclres_manager) return FALSE;
+
+    const SclInputModeConfigure *pinput_mode_table = sclres_manager->get_input_mode_configure_table();
+    if (NULL == pinput_mode_table) {
+        return FALSE;
+    }
+
+    const char* name = pinput_mode_table[mode].name;
+    if (NULL == name) {
+        return FALSE;
+    }
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    if (utils)
+        utils->play_tts(name);
+    return TRUE;
+}
+
+static sclboolean
+_play_tts_for_layout_autopopup_name() {
+    SCL_DEBUG();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    if (context && context->get_tts_enabled() == FALSE) {
+        return FALSE;
+    }
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    if (utils)
+        utils->play_tts(SCL_LAYOUT_AUTOPOPUP_NAME);
+    return TRUE;
+}
+
+CSCLController::CSCLController()
+{
+    SCL_DEBUG();
+
+    m_long_key_duration = SCL_LONGKEY_DURATION;
+    m_long_key_cancel_distance = SCL_LONGKEY_CANCEL_DIST;
+    m_repeat_key_duration = SCL_REPEATKEY_DURATION;
+    m_autopopup_key_duration = SCL_AUTOPOPUP_KEY_DURATION;
+
+    m_button_delay_duration = SCL_BUTTON_MIN_DURATION;
+    m_multitap_delay_duration = SCL_MULTITAP_DEFAULT_DURATION;
+
+    m_key_repeated_num = 0;
+
+    m_debug_mode = DEBUGMODE_DISABLED;
+    m_debug_variable = 0;
+
+    m_input_events_disabled = FALSE;
+}
+
+CSCLController::~CSCLController()
+{
+    SCL_DEBUG();
+}
+
+CSCLController*
+CSCLController::get_instance()
+{
+    static CSCLController instance;
+    return &instance;
+}
+
+void
+CSCLController::init()
+{
+    SCL_DEBUG();
+}
+
+//#define TEST_NEWBACKEND
+#ifdef TEST_NEWBACKEND
+#include <Ecore_Evas.h>
+#include <Ecore.h>
+#include <vector>
+typedef enum {
+    EFLOBJECT_NONE,
+    EFLOBJECT_IMAGE,
+    EFLOBJECT_CLIPOBJECT,
+    EFLOBJECT_TEXTBLOCK,
+} EFLOBJECT_TYPE;
+
+    typedef struct {
+        EFLOBJECT_TYPE type;
+        SclRectangle position;
+        Evas_Object *object;
+        char *etc_info;
+        sclboolean extracted;
+        void *data;
+    } EFLObject;
+#include <Ecore_Evas.h>
+#include <Ecore.h>
+    typedef struct {
+        sclboolean used;
+
+        Evas_Object *image;
+        Evas_Object *clipper;
+
+        sclwindow window;
+        sclchar image_path[_POSIX_PATH_MAX];
+        sclint imgPathHash;
+        sclint dest_x;
+        sclint dest_y;
+        sclint dest_width;
+        sclint dest_height;
+        sclint src_x;
+        sclint src_y;
+        sclint src_width;
+        sclint src_height;
+        sclboolean extrace_image;
+    } ImageCache;
+
+    typedef struct {
+        sclboolean used;
+
+        Evas_Object *text;
+
+        sclwindow window;
+        scl::SclFontInfo font_info;
+        SclColor color;
+        sclchar str[_POSIX_PATH_MAX];;
+        sclint strHash;
+        sclint pos_x;
+        sclint pos_y;
+        sclint width;
+        sclint height;
+        SCLLabelAlignment align;
+        sclshort padding_x;
+        sclshort padding_y;
+        sclbyte inner_width;
+        sclbyte inner_height;
+    } TextCache;
+
+extern std::vector<ImageCache> g_ImageCache;
+extern std::vector<TextCache> g_TextCache;
+#else
+#endif
+
+/**
+ * Sets the current input mode to the given mode
+ */
+sclboolean
+CSCLController::process_input_mode_change(const sclbyte mode)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!utils || !context || !windows || !cache || !sclres_manager) return FALSE;
+
+    PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+    if (!sclres_input_mode_configure) return FALSE;
+
+    if (context && windows && cache && utils) {
+        if (mode == context->get_input_mode() || mode == (sclbyte)NOT_USED) {
+            /* ButtonContext does not get initialized if we don't call here */
+            cache->recompute_layout(windows->get_base_window());
+            return FALSE;
+        }
+
+        context->set_input_mode(mode);
+        /* FIXME : NEWXML temporary commenting out */
+        //context->set_base_layout(sclres_input_mode_configure[mode].layouts[context->get_display()]);
+
+        _play_tts_for_input_mode_name(mode);
+
+        sclwindow window = windows->get_base_window();
+        handle_engine_signal(SCL_SIG_INPMODE_CHANGE, window);
+
+#ifdef TEST_NEWBACKEND
+        SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+        if (window_context) {
+            if (window_context->etc_info) {
+                Eina_List *list = (Eina_List*)(window_context->etc_info);
+                Eina_List *iter = NULL;
+                Eina_List *iter_next = NULL;
+                void *data = NULL;
+                int iIndex = 0;
+
+                EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) {
+                    if (data) {
+                        EFLObject *object = (EFLObject*)(data);
+                        if (object) {
+                            Evas_Object* eo = object->object;
+                            if (object->extracted) {
+                                void *data = evas_object_image_data_get(eo, 1);
+                                if (data) {
+                                    free(data);
+                                }
+                            }
+
+                            sclint loop;
+                            for (loop = 0;loop < (sclint)g_ImageCache.size();loop++) {
+                                if (g_ImageCache[loop].image == object->object) {
+                                    g_ImageCache[loop].used = FALSE;
+                                }
+                            }
+                            for (loop = 0;loop < (sclint)g_TextCache.size();loop++) {
+                                if (g_TextCache[loop].text == object->object) {
+                                    g_TextCache[loop].used = FALSE;
+                                }
+                            }
+
+                            if (eo) {
+                                evas_object_del(eo);
+                                object->object = NULL;
+                            }
+                            delete object;
+                        }
+                        list = eina_list_remove_list(list, iter);
+                    }
+                    iIndex++;
+                }
+                window_context->etc_info = list;
+            }
+        }
+#endif
+    }
+
+    return ret;
+}
+
+/**
+ * Sets the current display mode to the given mode
+ */
+sclboolean
+CSCLController::process_rotation_change(const SCLRotation rotation)
+{
+    SCL_DEBUG();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!sclres_manager) return FALSE;
+
+    PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+    if (!sclres_input_mode_configure) return FALSE;
+
+    if (context && windows) {
+        SCLDisplayMode mode;
+        if (rotation == ROTATION_90_CW || rotation == ROTATION_90_CCW) {
+            mode = DISPLAYMODE_LANDSCAPE;
+        } else {
+            mode = DISPLAYMODE_PORTRAIT;
+        }
+
+        //if (mode == context->get_display()) return FALSE;
+        context->set_display_mode(mode);
+        context->set_rotation(rotation);
+        /* FIXME : NEWXML temporary commenting out */
+        //context->set_base_layout(sclres_input_mode_configure[context->get_input_mode()].layouts[context->get_display()]);
+
+        sclwindow window = windows->get_base_window();
+        handle_engine_signal(SCL_SIG_DISP_CHANGE, window);
+        windows->update_window(window);
+
+        /* Moved to here since the new WMSync requires the rotation call be invoked as the
+           last step of display change process */
+        /* Make sure to set window's rotation degree before sending engine signal, which adjusts the size of main window */
+        windows->set_window_rotation(NULL, rotation);
+    }
+    return TRUE;
+}
+
+/**
+ * Checks if the given button with given touch_id needs magnifier window
+ */
+sclboolean
+CSCLController::check_magnifier_available(sclwindow window, sclbyte key_index, scltouchdevice touch_id)
+{
+    sclboolean ret = FALSE;
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    const SclLayout *layout = NULL;
+    SclButtonContext *button_context = NULL;
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+
+    if (context && cache) {
+        layout = cache->get_cur_layout(window);
+        button_context = cache->get_cur_button_context(window, key_index);
+        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+
+        SCLShiftState shift_index = context->get_shift_state();
+        if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+        if (context->get_caps_lock_mode()) {
+            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+        }
+
+        if (layout && coordinate && button_context && context->get_magnifier_enabled()) {
+            if (coordinate->key_type != KEY_TYPE_CONTROL &&
+                coordinate->key_type != KEY_TYPE_MODECHANGE &&
+                coordinate->key_type != KEY_TYPE_NONE) {
+                    ret = TRUE;
+
+                    /* Do not show if current layout does not allow magnifier */
+                    if (!(layout->use_magnifier_window)) {
+                        //utils->log("show_magnifier !(layout->use_magnifier_window \n");
+                        ret = FALSE;
+                    }
+
+                    /* Do not show if there's nothing to show */
+                    const sclchar* custom_label = NULL;
+                    for (sclint label_index = 0;label_index < MAX_SIZE_OF_LABEL_FOR_ONE && !custom_label;label_index++) {
+                        const sclchar *temp_label = context->get_custom_magnifier_label(touch_id, label_index);
+                        if (temp_label) {
+                            custom_label = temp_label;
+                        }
+                    }
+                    if (!custom_label) {
+                        //if (coordinate->key_value[shift_index][button_context->multikeyIdx] == NULL) {
+                        if (coordinate->label[shift_index][button_context->multitap_index] == NULL) {
+                            //utils->log("show_magnifier coordinate->key_value[shift][button_context->multikeyIdx] == NULL \n");
+                            ret = FALSE;
+                            //} else if (strlen(coordinate->key_value[shift_index][button_context->multikeyIdx]) == 0) {
+                        } else if (strlen(coordinate->label[shift_index][button_context->multitap_index]) == 0) {
+                            //utils->log("show_magnifier coordinate->key_value[shift][button_context->multikeyIdx]) == 0 \n");
+                            ret = FALSE;
+                        }
+                    }
+
+                    if (touch_id != context->get_last_touch_device_id()) {
+                        ret = FALSE;
+                    }
+                }
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLController::process_button_pressed_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+                                             scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+    sclboolean redraw = FALSE;
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLFeedback *feedback = CSCLFeedback::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!sclres_manager) return FALSE;
+
+    PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+    PSclLayout sclres_layout = sclres_manager->get_layout_table();
+    if (!sclres_input_mode_configure || !sclres_layout) return FALSE;
+
+    SclButtonContext *button_context = NULL;
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+
+    if (context && cache) {
+        button_context = cache->get_cur_button_context(window, key_index);
+        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+    }
+
+    if (context && cache && windows && events && utils && feedback && handler && button_context && coordinate) {
+        /* First check if this button is enabled in current active sublayout */
+        sclboolean sub_layout_match = TRUE;
+        if (coordinate->sub_layout && context->get_cur_sublayout()) {
+            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+                sub_layout_match = FALSE;
+            }
+        }
+
+        /* If this button is pressed */
+        if ( x >= coordinate->x - coordinate->add_hit_left &&
+                x < coordinate->x + coordinate->width + coordinate->add_hit_right &&
+                y >= coordinate->y - coordinate->add_hit_top &&
+                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom &&
+                /* Process the event only if the this item's sublayout id is active one */
+                sub_layout_match ) {
+            /* If currently shift mode is ON, and the last key was multitap, this means the shift did not
+               turned off because of multitap button. So we need to turn it off here forcibly */
+            sclwindow last_win = context->get_last_event_fired_window();
+            scl8 last_key = context->get_last_event_fired_key();
+            LOGD("last_win : %p last_key : :%d", last_win, last_key);
+            const SclLayoutKeyCoordinate *last_coordinate = cache->get_cur_layout_key_coordinate(last_win, last_key);
+            if (last_coordinate) {
+                LOGD("last_coordinate->button_type : %d", last_coordinate->button_type);
+                if (last_coordinate->button_type == BUTTON_TYPE_MULTITAP && context->get_shift_state() == SCL_SHIFT_STATE_ON) {
+                    /* And if the multitap button was different from the one we are dealing with... */
+                    LOGD("last_win %p window %p last_key %d key_index %d", last_win, window, last_key, key_index);
+                    if (last_win != window || last_key != key_index) {
+                        SclNotiShiftStateChangeDesc desc;
+                        desc.ui_event_desc = NULL;
+                        desc.shift_state = SCL_SHIFT_STATE_OFF;
+
+                        SCLEventReturnType ret = handler->on_event_notification(SCL_UINOTITYPE_SHIFT_STATE_CHANGE, &desc);
+                        if (ret == SCL_EVENT_PASS_ON) {
+                            context->set_shift_state(SCL_SHIFT_STATE_OFF);
+                            windows->update_window(windows->get_base_window());
+                        }
+                    }
+                }
+            }
+
+            /* If newly pressed key has type MULTI_TOUCH_TYPE_EXCLUSIVE, release all existing pressed events */
+            if (actual_event) {
+                if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_EXCLUSIVE) {
+                    /* When calling mouse_release, the seq order of current multitouch events will be changed,
+                    so we put all the multitouch events into a vector and use them afterwards forreleasing */
+                    sclint loop = 0;
+                    sclint multi_touch_context_num = context->get_multi_touch_context_num();
+                    std::vector<SclUIEventDesc> multi_touch_events;
+                    for (loop = 0;loop < multi_touch_context_num;loop++) {
+                        SclUIEventDesc desc;
+                        context->get_multi_touch_event(loop, &desc);
+                        multi_touch_events.push_back(desc);
+                    }
+                    for (loop = 0;loop < multi_touch_context_num;loop++) {
+                        SclUIEventDesc desc = multi_touch_events[loop];
+                        if (desc.touch_id != touch_id) {
+                            mouse_release(context->get_cur_moving_window(desc.touch_id),
+                                context->get_cur_moving_point(desc.touch_id).x,
+                                context->get_cur_moving_point(desc.touch_id).y,
+                                desc.touch_id, FALSE);
+                        }
+                    }
+                }
+            }
+
+            /* Make an unique ID for timer */
+            const scl16 uniqId = utils->get_unique_id();
+
+            context->set_cur_pressed_event_id(touch_id, uniqId);
+            context->set_cur_pressed_key(touch_id, key_index);
+            context->set_cur_pressed_window(touch_id, window);
+
+            button_context->state = BUTTON_STATE_PRESSED;
+
+            if (context->get_highlight_ui_enabled()) {
+                CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+                if (focus_handler) {
+                    sclwindow prev_window = focus_handler->get_current_focus_window();
+                    scl8 prev_key = focus_handler->get_current_focus_key();
+                    const SclLayoutKeyCoordinate *prev_coordinate =
+                        cache->get_cur_layout_key_coordinate(prev_window, prev_key);
+
+                    focus_handler->set_current_focus(window, key_index);
+
+                    if (prev_coordinate) {
+                        windows->update_window(prev_window,
+                            prev_coordinate->x, prev_coordinate->y, prev_coordinate->width, prev_coordinate->height);
+                    }
+                }
+            }
+
+            redraw = TRUE;
+            ret = TRUE;
+
+#ifndef DIRECTLY_DRAW_ON_EVENTS
+            /* If the window doesn't get exposed before corresponding release event,
+             * the inverted state of a button will never be drawn onto screen.
+             * To prevent such a case, we draw the inverted state of button forcefully and directly,
+             * without waiting for expose event */
+            /*CSCLGraphics *grps = CSCLGraphics::get_instance();
+            CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+            scldrawctx draw_ctx = grps->begin_paint(window, TRUE);
+            builder->draw_button(window, draw_ctx, key_index, button_context->state, TRUE);
+            grps->end_paint(window, draw_ctx);*/
+#endif
+
+            /* for feedback */
+            feedback->button_pressed(window, key_index);
+
+            /* Special routine for autopopup */
+            if (coordinate->popup_type == POPUP_TYPE_AUTO_POPUP) {
+                events->create_timer(SCL_TIMER_AUTOPOPUP, m_autopopup_key_duration, uniqId);
+            } else {
+                /* for long key & repeat key */
+                events->create_timer(SCL_TIMER_LONGKEY, m_long_key_duration, uniqId);
+            }
+
+            SCLShiftState shift_index = context->get_shift_state();
+            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+            if (context->get_caps_lock_mode()) {
+                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+            }
+
+            SclUIEventDesc key_event_desc;
+            key_event_desc.key_value = coordinate->key_value[shift_index][0];
+            key_event_desc.key_event = coordinate->key_event[shift_index][0];
+            key_event_desc.key_type = coordinate->key_type;
+            key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+            key_event_desc.event_type = EVENT_TYPE_PRESS;
+
+            SclPoint curpoint = {x, y};
+            key_event_desc.touch_id = touch_id;
+            key_event_desc.mouse_pressed_point = curpoint;
+            key_event_desc.mouse_current_point = curpoint;
+            key_event_desc.mouse_farthest_point = curpoint;
+
+            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+            SCLEventReturnType processed = handler->on_event_drag_state_changed(key_event_desc);
+
+            /* Only if the handler didn't return SCL_EVENT_DONE */
+            if (processed == SCL_EVENT_PASS_ON) {
+                /* Now process normal behaviours of each button type */
+                switch (coordinate->button_type) {
+                case BUTTON_TYPE_NORMAL:
+                case BUTTON_TYPE_GRAB:
+                case BUTTON_TYPE_SELFISH:
+                case BUTTON_TYPE_DIRECTION:
+                case BUTTON_TYPE_RELATIVE_DIRECTION: {
+                    /* Send click event right away if this button uses repeat key */
+                    if (coordinate->use_repeat_key) {
+                        handler->on_event_key_clicked(key_event_desc);
+                    }
+                }
+                break;
+                case BUTTON_TYPE_MULTITAP: {
+                }
+                break;
+                case BUTTON_TYPE_ROTATION: {
+                }
+                break;
+                case BUTTON_TYPE_DRAG: {
+                    /* Drag buttons fires click event immediately when they are pressed */
+                    handler->on_event_key_clicked(key_event_desc);
+                }
+                break;
+                case BUTTON_TYPE_UIITEM: break;
+                case MAX_BUTTON_TYPE: break;
+                default: break;
+                }
+                switch (coordinate->popup_type) {
+                case POPUP_TYPE_BTN_PRESS_POPUP_DRAG: {
+                    SclNotiPopupOpeningDesc desc;
+                    desc.ui_event_desc = &key_event_desc;
+                    desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
+                    if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
+                        sclint popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
+                        SCLDisplayMode display_mode = context->get_display_mode();
+                        /* FIXME */
+                        //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
+                        if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
+                            scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+                            sclshort popupLayoutId =
+                                sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
+                            SclRectangle popupRect;
+                            SclRectangle baseWndRect;
+                            SclLayout *layout = NULL;
+                            /* FIXME */
+                            //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
+                            if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
+                                layout = &sclres_layout[popupLayoutId];
+                            }
+                            if (layout) {
+                                windows->get_window_rect(windows->get_base_window(), &baseWndRect);
+                                popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
+                                popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
+                                //popupRect.width = utils->get_scale_x(layout->width);
+                                //popupRect.height= utils->get_scale_y(layout->height);
+                                if (!(sclres_manager->loaded(popupLayoutId))) {
+                                    sclres_manager->load(popupLayoutId);
+                                }
+                                popupRect.width = layout->width;
+                                popupRect.height = layout->height;
+                                windows->close_all_popups();
+
+                                SclWindowOpener opener;
+                                opener.window = window;
+                                opener.key = key_index;
+
+                                sclwindow popup_window = windows->open_popup(opener,
+                                    popupRect,
+                                    popup_input_mode,
+                                    popupLayoutId,
+                                    coordinate->popup_type,
+                                    sclres_input_mode_configure[popup_input_mode].use_virtual_window,
+                                    sclres_input_mode_configure[popup_input_mode].use_dim_window,
+                                    coordinate->extract_offset_x,
+                                    coordinate->extract_offset_y,
+                                    sclres_input_mode_configure[popup_input_mode].timeout);
+
+                                SclNotiPopupOpenedDesc opened_desc;
+                                opened_desc.ui_event_desc = &key_event_desc;
+                                opened_desc.input_mode = desc.input_mode;
+                                opened_desc.window = popup_window;
+                                handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
+
+                                windows->hide_window(windows->get_magnifier_window());
+                                /* FIXME : The parent key should be turned back to NORMAL state when RELEASED,
+                                    in case of POPUP_TYPE_BTN_PRESS_POPUP_DRAG type. Temporarily setting NORMAL here. */
+                                button_context->state = BUTTON_STATE_NORMAL;
+                                _play_tts_for_input_mode_name(popup_input_mode);
+                            }
+                        }
+                    }
+                }
+                break;
+                case POPUP_TYPE_BTN_RELEASE_POPUP:
+                case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE:
+                case POPUP_TYPE_BTN_LONGPRESS_POPUP:
+                case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE:
+                case POPUP_TYPE_AUTO_POPUP:
+                case POPUP_TYPE_NONE:
+                case MAX_POPUP_TYPE:
+                default:
+                    /* Nothing to do in here */
+                    break;
+                }
+            }
+
+            /* Shows the magnifier window(the magnifier window will display when a kind of button type is character) */
+            //if (windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP) == windows->get_base_window()) {
+            if (coordinate->use_magnifier) {
+                sclboolean showMagnifier = check_magnifier_available(window, key_index, touch_id);
+
+                PSclMagnifierWndConfigure magnifier_configure = NULL;
+                if (sclres_manager) {
+                    magnifier_configure = sclres_manager->get_magnifier_configure();
+                }
+                if (showMagnifier && magnifier_configure) {
+                    SclPoint pos = {0, 0};
+                    /* calculates x position to be set */
+                    pos.x = (coordinate->x + (coordinate->width / 2)) -
+                        (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+                    /* calculates y position to be set */
+                    sclint scnWidth, scnHeight;
+                    utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+                    pos.y = coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
+
+                    /* FIXME : Temporary way of clearing magnifier window */
+                    /*SclWindowContext *window_context = windows->get_window_context(windows->get_magnifier_window(), FALSE);
+                    sclboolean clearmagwin = FALSE;
+                    if (window_context) {
+                        clearmagwin = !(window_context->hidden);
+                    }
+                    static int clearnum = 0;
+                    if (key_index == prevkey && window == prevwin) {
+                        clearmagwin = FALSE;
+                    }
+                    if (clearmagwin) {
+                        if (++clearnum > 1) {
+                            clearmagwin = FALSE;
+                        }
+                    } else {
+                        clearnum = 0;
+                    }
+
+                    if (clearmagwin) {
+                        CSCLGraphics *graphics = CSCLGraphics::get_instance();
+                        CSCLUtils *utils = CSCLUtils::get_instance();
+                        sclchar composed_path[_POSIX_PATH_MAX] = {0,};
+                        scldrawctx draw_ctx = graphics->begin_paint(windows->get_magnifier_window());
+                        utils->get_composed_path(composed_path, scl_magnifier_configure.bg_image_path);
+                        graphics->draw_image(windows->get_magnifier_window(), draw_ctx, composed_path, 0, 0);
+                        graphics->end_paint(windows->get_magnifier_window(), draw_ctx);
+                    }
+                    */
+                    windows->hide_window(windows->get_magnifier_window());
+
+                    SclWindowContext *window_context = windows->get_window_context(window);
+                    if (window_context) {
+                        pos.x += window_context->geometry.x;
+                        pos.y += window_context->geometry.y;
+                    }
+
+                    if (pos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+                        pos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+                    }
+                    if (pos.x > scnWidth +
+                        magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                        magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+                        pos.x = scnWidth + magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                            magnifier_configure->width * utils->get_custom_scale_rate_x();
+                    }
+                    pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+                    pos.x += coordinate->magnifier_offset_x;
+                    pos.y += coordinate->magnifier_offset_y;
+                    windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
+                    //windows->resize_window(windows->get_magnifier_window(), utils->get_scale_x(scl_magnifier_configure.width), utils->get_scale_y(scl_magnifier_configure.height));
+                    /*If we use transient_for them the ISE will occur some crash. It needs to check X11 */
+                    /*windows->set_parent(windows->get_base_window(), windows->get_magnifier_window());*/
+
+                    windows->show_window(windows->get_magnifier_window(), TRUE);
+                    //windows->update_window(windows->get_magnifier_window());
+                }
+#if 0
+                static int fFirst = true;
+                if (fFirst) {
+                    windows->show_window(windows->get_magnifier_window());
+                    fFirst = false;
+                } else {
+                    windows->update_window(windows->get_magnifier_window());
+                }
+#endif
+                /* We cannot use move_resize_window. It had occured some wrong behavior */
+                /*windows->move_resize_window(windows->get_magnifier_window(), pos.x, pos.y, scl_magnifier_configure.width, scl_magnifier_configure.height);*/
+                if (!showMagnifier) {
+                    windows->hide_window(windows->get_magnifier_window());
+                }
+            }
+        } else {
+            /* COMMENTED OUT FOR TESTING MULTITOUCH!! */
+            ///* In case the current button is not the given key index */
+            //if (button_context->state == BUTTON_STATE_PRESSED) {
+            //    /* Even if the press event occurs outside of this button's physical area, reset its context */
+            //    button_context->state = BUTTON_STATE_NORMAL;
+            //    redraw = TRUE;
+            //}
+            /* BUTTON_TYPE_MULTITAP type button should restore its multikey index when another button is clicked */
+            if (coordinate->button_type & BUTTON_TYPE_MULTITAP) {
+                button_context->multitap_index = 0;
+            }
+        }
+
+        /* If there is any need for redrawing */
+        if (redraw) {
+#ifdef DIRECTLY_DRAW_ON_EVENTS
+            CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+            if (builder) {
+                builder->draw_button(window, NULL, key_index, button_context->state, TRUE);
+            }
+#else
+            if (windows) {
+                windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+            }
+#endif
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLController::process_button_long_pressed_event(sclwindow window, sclbyte key_index,
+                                                  scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!sclres_manager) return FALSE;
+
+    PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+    PSclLayout sclres_layout = sclres_manager->get_layout_table();
+
+    if (!sclres_input_mode_configure || !sclres_layout) return FALSE;
+
+    if (context && cache && handler && windows && state) {
+        const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+        SclButtonContext *button_context = cache->get_cur_button_context(window, key_index);
+
+        /* Should return FALSE if this key does not have any longkey related property */
+        if (coordinate) {
+            if (actual_event) {
+                if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+                    /* When calling mouse_release, the seq order of current multitouch events will be changed,
+                       so we put all the multitouch events into a vector and use them afterwards for releasing */
+                    sclboolean finished = FALSE;
+                    sclint loop = 0;
+                    sclint multi_touch_context_num = context->get_multi_touch_context_num();
+                    std::vector<SclUIEventDesc> multitouch_events;
+                    for (loop = 0;loop < multi_touch_context_num;loop++) {
+                        SclUIEventDesc desc;
+                        context->get_multi_touch_event(loop, &desc);
+                        multitouch_events.push_back(desc);
+                    }
+                    for (loop = 0;loop < multi_touch_context_num && !finished;loop++) {
+                        SclUIEventDesc desc = multitouch_events[loop];
+                        if (desc.touch_id != touch_id) {
+                            sclwindow cur_pressed_window = context->get_cur_pressed_window(desc.touch_id);
+                            scl8 cur_pressed_key = context->get_cur_pressed_key(desc.touch_id);
+                            const SclLayoutKeyCoordinate *cur_pressed_coordinate =
+                                cache->get_cur_layout_key_coordinate(cur_pressed_window, cur_pressed_key);
+                            if (cur_pressed_coordinate) {
+                                if (cur_pressed_coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+                                    mouse_release(context->get_cur_moving_window(desc.touch_id),
+                                        context->get_cur_moving_point(desc.touch_id).x,
+                                        context->get_cur_moving_point(desc.touch_id).y,
+                                        desc.touch_id, FALSE);
+                                }
+                            }
+                        } else {
+                            finished = TRUE;
+                        }
+                    }
+                }
+            }
+        }
+
+        /* Should return FALSE if this key does not have any longkey related property */
+        if (coordinate) {
+            if (coordinate->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP ||
+                coordinate->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE ) {
+                    SclUIEventDesc key_event_desc;
+                    key_event_desc.key_type = coordinate->long_key_type;
+                    if (coordinate->long_key_value == NULL && coordinate->long_key_event == 0) {
+                        SCLShiftState shift_index = context->get_shift_state();
+                        if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+                        if (context->get_caps_lock_mode()) {
+                            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+                        }
+
+                        key_event_desc.key_value = coordinate->key_value[shift_index][0];
+                        key_event_desc.key_event = coordinate->key_event[shift_index][0];
+                    } else {
+                        key_event_desc.key_value = coordinate->long_key_value;
+                        key_event_desc.key_event = coordinate->long_key_event;
+                    }
+                    key_event_desc.key_modifier = KEY_MODIFIER_LONGKEY;
+
+                    key_event_desc.event_type = EVENT_TYPE_LONGPRESS;
+                    key_event_desc.touch_id = touch_id;
+                    key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                    key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                    key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                    key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                    SCLEventReturnType processed = handler->on_event_drag_state_changed(key_event_desc);
+
+                    /* Only if the handler didn't return SCL_EVENT_DONE */
+                    if (processed == SCL_EVENT_PASS_ON) {
+                        SclRectangle popupRect;
+                        SclRectangle baseWndRect;
+                        windows->get_window_rect(windows->get_base_window(), &baseWndRect);
+                        popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
+                        popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
+
+                        SclNotiPopupOpeningDesc desc;
+                        desc.ui_event_desc = &key_event_desc;
+                        desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
+                        if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
+                            sclint popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
+                            SCLDisplayMode display_mode = context->get_display_mode();
+                            /* FIXME */
+                            //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
+                            if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
+                                scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+                                SclLayout *layout = NULL;
+                                sclshort popupLayoutId =
+                                    sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
+                                /* FIXME */
+                                //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
+                                if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
+                                    layout = &sclres_layout[popupLayoutId];
+                                }
+                                if (layout) {
+                                    //popupRect.width = utils->get_scale_x(layout->width);
+                                    //popupRect.height= utils->get_scale_y(layout->height);
+                                    if (!(sclres_manager->loaded(popupLayoutId))) {
+                                        sclres_manager->load(popupLayoutId);
+                                    }
+                                    popupRect.width = layout->width;
+                                    popupRect.height = layout->height;
+
+                                    SclWindowOpener opener;
+                                    opener.window = window;
+                                    opener.key = key_index;
+
+                                    sclwindow popup_window = windows->open_popup(
+                                        opener,
+                                        popupRect,
+                                        popup_input_mode,
+                                        popupLayoutId,
+                                        coordinate->popup_type,
+                                        sclres_input_mode_configure[popup_input_mode].use_virtual_window,
+                                        sclres_input_mode_configure[popup_input_mode].use_dim_window,
+                                        coordinate->extract_offset_x,
+                                        coordinate->extract_offset_y,
+                                        sclres_input_mode_configure[popup_input_mode].timeout);
+
+                                    SclNotiPopupOpenedDesc opened_desc;
+                                    opened_desc.ui_event_desc = &key_event_desc;
+                                    opened_desc.input_mode = desc.input_mode;
+                                    opened_desc.window = popup_window;
+                                    handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
+
+                                    windows->hide_window(windows->get_magnifier_window());
+                                    _play_tts_for_input_mode_name(popup_input_mode);
+                                    ret = TRUE;
+                                }
+                            }
+                        }
+                    }
+            } else if (coordinate->long_key_value) {
+                if (strlen(coordinate->long_key_value) > 0) {
+                        if (windows->is_base_window(window)) {
+                            state->set_cur_action_state(ACTION_STATE_BASE_LONGKEY);
+                        } else {
+                            state->set_cur_action_state(ACTION_STATE_POPUP_LONGKEY);
+                        }
+                        ret = TRUE;
+
+                        PSclMagnifierWndConfigure magnifier_configure = NULL;
+                        if (sclres_manager) {
+                            magnifier_configure = sclres_manager->get_magnifier_configure();
+                        }
+                        if (coordinate->use_long_key_magnifier && magnifier_configure) {
+                            CSCLUtils *utils = CSCLUtils::get_instance();
+                            SclPoint pos = {0, 0};
+
+                            const SclLayout* layout = cache->get_cur_layout(window);
+                            if (utils && layout) {
+                                sclint scnWidth, scnHeight;
+                                utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+                                //SclWindowContext *window_context = windows->get_window_context(window, TRUE);
+                                SclWindowContext *window_context = windows->get_window_context(window);
+                                if (window_context) {
+                                    pos.x = window_context->geometry.x + (coordinate->x + (coordinate->width / 2)) -
+                                        (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+                                    pos.y = window_context->geometry.y + coordinate->y -
+                                        magnifier_configure->height * utils->get_custom_scale_rate_y();
+                                }
+                                if (pos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+                                    pos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+                                }
+                                if (pos.x > scnWidth +
+                                    magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                    magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+                                    pos.x = scnWidth +
+                                        magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                        magnifier_configure->width * utils->get_custom_scale_rate_x();
+                                }
+                                pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+                                pos.x += coordinate->magnifier_offset_x;
+                                pos.y += coordinate->magnifier_offset_y;
+                                windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
+                                windows->update_window(windows->get_magnifier_window());
+                                windows->show_window(windows->get_magnifier_window(), TRUE);
+                            }
+                        }
+
+                        SclUIEventDesc key_event_desc;
+                        key_event_desc.key_type = coordinate->long_key_type;
+                        key_event_desc.key_value = coordinate->long_key_value;
+                        key_event_desc.key_event = coordinate->long_key_event;
+                        key_event_desc.key_modifier = KEY_MODIFIER_LONGKEY;
+
+                        key_event_desc.event_type = EVENT_TYPE_LONGPRESS;
+                        key_event_desc.touch_id = touch_id;
+                        key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                        key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                        key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                        key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                        handler->on_event_key_clicked(key_event_desc);
+                    //}
+                }
+            }
+        }
+        if (ret) {
+            context->set_cur_key_modifier(touch_id, KEY_MODIFIER_LONGKEY);
+            if (coordinate && button_context) {
+                if (coordinate->button_type & BUTTON_TYPE_MULTITAP) {
+                    button_context->multitap_index = 0;
+                }
+            }
+        }
+    }
+    /* Longkey processing in here */
+    return ret;
+}
+
+sclboolean
+CSCLController::process_button_repeat_pressed_event(sclwindow window, sclbyte key_index,
+                                                    scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+
+    if (context && cache && windows && handler) {
+        const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+
+        SCLShiftState shift_index = context->get_shift_state();
+        if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+        if (context->get_caps_lock_mode()) {
+            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+        }
+
+        if (coordinate) {
+            switch (coordinate->button_type) {
+                case BUTTON_TYPE_NORMAL:
+                case BUTTON_TYPE_GRAB:
+                case BUTTON_TYPE_SELFISH:
+                case BUTTON_TYPE_DIRECTION:
+                case BUTTON_TYPE_RELATIVE_DIRECTION: {
+                    /* This is for enabling backspace key in search layout*/
+                    //if (coordinate->key_type != KEY_TYPE_MODECHANGE && coordinate->key_type != KEY_TYPE_COMPOSITION) {
+                    //if (coordinate->key_type != KEY_TYPE_MODECHANGE || coordinate->key_event[0][0] == MVK_BackSpace) {
+                    if (coordinate->key_type != KEY_TYPE_MODECHANGE) {
+                        sclulong repeatKeyEvent = coordinate->key_event[shift_index][0];
+
+                        /* In case of Delete key, Change from Char deletion to Word deletion
+                           when the input acceleration speed is reached to Max */
+                        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+                        PSclDefaultConfigure default_configure = NULL;
+                        if (sclres_manager) {
+                            default_configure = sclres_manager->get_default_configure();
+                        }
+                        if (default_configure) {
+                            if (default_configure->use_word_deletion) {
+                                scllong interval = m_repeat_key_duration - (m_key_repeated_num * SCL_REPEATKEY_ACCELERATION);
+                                if (repeatKeyEvent == MVK_BackSpace &&
+                                    interval <= SCL_REPEATKEY_WORD_DELETION_START_DURATION) {
+                                    repeatKeyEvent = MVK_3270_DeleteWord;
+                                }
+                            }
+                        }
+
+                        SclUIEventDesc key_event_desc;
+                        key_event_desc.key_value = coordinate->key_value[shift_index][0];
+                        key_event_desc.key_event = repeatKeyEvent;
+                        key_event_desc.key_type = coordinate->key_type;
+                        key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+
+                        key_event_desc.event_type = EVENT_TYPE_REPEAT;
+                        key_event_desc.touch_id = touch_id;
+                        key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                        key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                        key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                        key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                        handler->on_event_key_clicked(key_event_desc);
+                    }
+                }
+                break;
+                case BUTTON_TYPE_UIITEM: break;
+                case MAX_BUTTON_TYPE: break;
+                default: break;
+            }
+        }
+    }
+
+    /* Longkey processing in here */
+    return TRUE;
+}
+
+sclboolean
+CSCLController::process_button_move_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+                                          scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLFeedback *feedback = CSCLFeedback::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    SclButtonContext *button_context = NULL;
+
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+
+    if (cache) {
+        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+        button_context = cache->get_cur_button_context(window, key_index);
+    }
+
+    if (button_context && coordinate && feedback && utils && context && handler && cache && events && windows) {
+        /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
+        sclint thresholdX = 0;
+        sclint thresholdY = 0;
+        if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
+            thresholdX = utils->get_scaled_x(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_X);
+            thresholdY = utils->get_scaled_y(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_Y);
+        }
+
+        /* First check if this button is enabled in current active sublayout */
+        sclboolean subLayoutMatch = TRUE;
+        if (coordinate->sub_layout && context->get_cur_sublayout()) {
+            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+                subLayoutMatch = FALSE;
+            }
+        }
+        if ( x >= coordinate->x - coordinate->add_hit_left  - thresholdX &&
+            x < coordinate->x + coordinate->width + coordinate->add_hit_right + thresholdX&&
+                y >= coordinate->y - coordinate->add_hit_top - thresholdY &&
+                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom + thresholdY &&
+                subLayoutMatch ) {
+            ret = TRUE;
+
+            SCLShiftState shift_index = context->get_shift_state();
+            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+            if (context->get_caps_lock_mode()) {
+                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+            }
+
+            const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
+
+            sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+            scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+            SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
+            const SclLayoutKeyCoordinate *pressed_coordinate =
+                cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+            if (pressed_context == NULL || pressed_coordinate == NULL) {
+                return FALSE;
+            }
+
+            if (key_index != pressed_key || window != pressed_window) {
+                /* When the focus has moved to another button, destroy all the timers */
+                events->destroy_all_timer();
+
+                if (check_event_transition_enabled(pressed_coordinate, coordinate)) {
+                    if (layout) {
+                        const scl16 uniqId = utils->get_unique_id();
+                        context->set_cur_pressed_event_id(touch_id, uniqId);
+                        /* Special routine for autopopup */
+                        if (coordinate->popup_type == POPUP_TYPE_AUTO_POPUP) {
+                            events->create_timer(SCL_TIMER_AUTOPOPUP, m_autopopup_key_duration, uniqId);
+                        } else {
+                            /* for long key & repeat key */
+                            events->create_timer(SCL_TIMER_LONGKEY, m_long_key_duration, uniqId);
+                        }
+
+                        context->set_cur_pressed_window(touch_id, window);
+                        context->set_cur_pressed_key(touch_id, key_index);
+
+                        sclboolean showMagnifier = check_magnifier_available(window, key_index, touch_id);
+
+                        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+                        PSclMagnifierWndConfigure magnifier_configure = NULL;
+                        if (sclres_manager) {
+                            magnifier_configure = sclres_manager->get_magnifier_configure();
+                        }
+
+                        SclWindowContext *window_context = windows->get_window_context(window);
+                        if (showMagnifier && magnifier_configure && window_context) {
+                            SclPoint pos = {0, 0};
+                            /* calculates x position to be set */
+                            pos.x = window_context->geometry.x;
+                            pos.x += (coordinate->x + (coordinate->width / 2)) -
+                                (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+                            /* calculates y position to be set */
+                            pos.y = window_context->geometry.y;
+                            pos.y += coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
+
+                            if (pos.x < window_context->geometry.x - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+                                pos.x = window_context->geometry.x - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+                            }
+                            if (pos.x > window_context->geometry.x + window_context->geometry.width +
+                                magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+                                pos.x = window_context->geometry.x + window_context->geometry.width +
+                                    magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                    magnifier_configure->width * utils->get_custom_scale_rate_x();
+                            }
+                            pos.x += coordinate->magnifier_offset_x;
+                            pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+                            pos.y += coordinate->magnifier_offset_y;
+                            if (windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP) == windows->get_base_window()) {
+                                windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
+                                windows->update_window(windows->get_magnifier_window());
+                            }
+                        }
+
+                        /* for feedback */
+                        feedback->button_moved(window, key_index);
+
+                        button_context->state = BUTTON_STATE_PRESSED;
+                        if (pressed_context) {
+                            /* But, if this button should be in pressed state in other multitouch id, do not initialize it */
+                            sclboolean found = FALSE;
+                            for (sclint loop = 0;loop < context->get_multi_touch_context_num() && !found;loop++) {
+                                SclUIEventDesc desc;
+                                context->get_multi_touch_event(loop, &desc);
+                                if (desc.touch_id != touch_id) {
+                                    MultiTouchContext *multi_touch_context =
+                                        context->find_multi_touch_context(desc.touch_id);
+                                    if (multi_touch_context) {
+                                        if (multi_touch_context->cur_pressed_window == pressed_window &&
+                                            multi_touch_context->cur_pressed_key == pressed_key) {
+                                            found = TRUE;
+                                        }
+                                    }
+                                }
+                            }
+                            if (!found) {
+                                pressed_context->state = BUTTON_STATE_NORMAL;
+                            }
+                        }
+                        /* If the window doesn't get exposed before corresponding release event,
+                        * the inverted state of a button will never be drawn onto screen.
+                        * To prevent such a case, we draw the inverted state of button forcefully and directly,
+                        * without waiting for expose event */
+                        /* Redrawing pressed button does not work properly, commented out */
+                        /*
+                        CSCLGraphics *grps = CSCLGraphics::get_instance();
+                        CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+                        scldrawctx draw_ctx;
+                        if (pressed_window != SCLWINDOW_INVALID && pressed_key != NOT_USED) {
+                            draw_ctx = grps->begin_paint(pressed_window, TRUE);
+                            builder->draw_button(pressed_window, draw_ctx, pressed_key, FALSE);
+                            grps->end_paint(pressed_window, draw_ctx);
+                        }
+                        draw_ctx = grps->begin_paint(window, TRUE);
+                        builder->draw_button(window, draw_ctx, key_index, TRUE);
+                        grps->end_paint(window, draw_ctx);
+                        */
+
+                        switch (coordinate->button_type) {
+                        case BUTTON_TYPE_DRAG: {
+                            SclUIEventDesc key_event_desc;
+                            key_event_desc.key_value = coordinate->key_value[shift_index][0];
+                            key_event_desc.key_event = coordinate->key_event[shift_index][0];
+                            key_event_desc.key_type = coordinate->key_type;
+                            key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+
+                            key_event_desc.event_type = EVENT_TYPE_MOVE;
+                            key_event_desc.touch_id = touch_id;
+                            key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                            key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                            key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                            if (sclres_manager) {
+                                magnifier_configure = sclres_manager->get_magnifier_configure();
+                            }
+                            sclboolean processed = handler->on_event_drag_state_changed(key_event_desc);
+                            if (processed && context->get_magnifier_enabled() && magnifier_configure) {
+                                SclPoint zoomwinpos = {0, 0};
+                                /* calculates x position to be set */
+                                zoomwinpos.x = (coordinate->x + (coordinate->width / 2)) -
+                                    (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+                                /* calculates y position to be set */
+                                sclint scnWidth, scnHeight;
+                                utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+                                zoomwinpos.y = coordinate->y -
+                                    magnifier_configure->height * utils->get_custom_scale_rate_y();
+                                SclWindowContext *window_context = windows->get_window_context(window);
+                                if (window_context) {
+                                    zoomwinpos.x += window_context->geometry.x;
+                                    zoomwinpos.y += window_context->geometry.y;
+                                }
+                                if (zoomwinpos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+                                    zoomwinpos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+                                }
+                                if (zoomwinpos.x > scnWidth +
+                                    magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                    magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+                                        zoomwinpos.x = scnWidth +
+                                            magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                            magnifier_configure->width * utils->get_custom_scale_rate_x();
+                                }
+                                zoomwinpos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+                                zoomwinpos.x += coordinate->magnifier_offset_x;
+                                zoomwinpos.y += coordinate->magnifier_offset_y;
+                                windows->move_window(windows->get_magnifier_window(), zoomwinpos.x, zoomwinpos.y);
+                                windows->show_window(windows->get_magnifier_window(), 0);
+                            }
+
+                            handler->on_event_key_clicked(key_event_desc);
+                            if (!(windows->is_base_window(window))) {
+                                /* When press event occured in popup window, reset POPUP_TIMEOUT timer */
+                                //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+                                SclWindowContext *window_context = windows->get_window_context(window);
+                                if (window_context) {
+                                    if (window_context->timeout > 0) {
+                                        events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+                                        events->create_timer(SCL_TIMER_POPUP_TIMEOUT, window_context->timeout, 0, TRUE);
+                                    }
+                                }
+                            }
+                        }
+                        break;
+                        case BUTTON_TYPE_NORMAL: break;
+                        case BUTTON_TYPE_GRAB: break;
+                        case BUTTON_TYPE_SELFISH: break;
+                        case BUTTON_TYPE_MULTITAP: break;
+                        case BUTTON_TYPE_ROTATION: break;
+                        case BUTTON_TYPE_DIRECTION: break;
+                        case BUTTON_TYPE_RELATIVE_DIRECTION: break;
+                        case BUTTON_TYPE_UIITEM: break;
+                        case MAX_BUTTON_TYPE: break;
+                        default:
+                            break;
+                        }
+
+#ifdef DIRECTLY_DRAW_ON_EVENTS
+                        CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+                        if (builder) {
+                            if (button_context) {
+                                builder->draw_button(window, NULL, key_index, button_context->state);
+                            }
+                            if (pressedContext) {
+                                builder->draw_button(pressed_window, NULL, pressed_key, pressedContext->state, TRUE);
+                            }
+                        }
+#else
+                        windows->update_window(window,
+                                coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+                        if (pressed_coordinate) {
+                            windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
+                                    pressed_coordinate->width, pressed_coordinate->height);
+                        }
+#endif
+                    }
+
+                    //utils->log("Now Moving : %d %d\n", pos.x, pos.y);
+                } else {
+                    /* If the focus went out from our SELFISH button */
+                    if (pressed_coordinate->button_type == BUTTON_TYPE_SELFISH) {
+                        pressed_context->state = BUTTON_STATE_NORMAL;
+                        windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
+                            pressed_coordinate->width, pressed_coordinate->height);
+                        /* And if this SELFISH button was the last button pressed */
+                        if (touch_id == context->get_last_touch_device_id()) {
+                            windows->hide_window(windows->get_magnifier_window());
+                        }
+                    }
+                }
+            } else {
+                /* If the focus came back into our SELFISH button */
+                if (pressed_coordinate->button_type == BUTTON_TYPE_SELFISH && pressed_context->state != BUTTON_STATE_PRESSED) {
+                    pressed_context->state = BUTTON_STATE_PRESSED;
+                    windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
+                        pressed_coordinate->width, pressed_coordinate->height);
+                    /* And if this SELFISH button was the last button pressed */
+                    if (touch_id == context->get_last_touch_device_id()) {
+                        sclboolean showMagnifier = check_magnifier_available(pressed_window, pressed_key, touch_id);
+
+                        if (showMagnifier) {
+                            windows->show_window(windows->get_magnifier_window());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLController::process_button_over_event(sclwindow window, sclint x, sclint y, sclbyte key_index)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLFeedback *feedback = CSCLFeedback::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    SclButtonContext *button_context = NULL;
+
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+    if (cache) {
+        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+        button_context = cache->get_cur_button_context(window, key_index);
+    }
+
+    if (button_context && coordinate && feedback && utils && context && cache && events && windows) {
+       /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
+        sclboolean subLayoutMatch = TRUE;
+        if (coordinate->sub_layout && context->get_cur_sublayout()) {
+            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+                subLayoutMatch = FALSE;
+            }
+        }
+        if ( x >= coordinate->x - coordinate->add_hit_left &&
+            x < coordinate->x + coordinate->width + coordinate->add_hit_right &&
+                y >= coordinate->y - coordinate->add_hit_top &&
+                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom &&
+                subLayoutMatch ) {
+            ret = TRUE;
+
+            SCLShiftState shift_index = context->get_shift_state();
+            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+            if (context->get_caps_lock_mode()) {
+                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+            }
+
+            const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
+
+            sclwindow highlighted_window = context->get_cur_highlighted_window();
+            scl8 highlighted_key = context->get_cur_highlighted_key();
+            SclButtonContext *cur_context = cache->get_cur_button_context(window, key_index);
+
+            if (cur_context == NULL) {
+                return FALSE;
+            }
+            if (key_index != highlighted_key || window != highlighted_window) {
+                SECURE_LOGD("%d != %d || %p != %p", key_index, highlighted_key, window, highlighted_window);
+                if (layout) {
+                    if (coordinate->key_type != KEY_TYPE_NONE) {
+                        if (context->get_tts_enabled()) {
+                            const sclchar *targetstr = coordinate->hint_string[shift_index][button_context->multitap_index];
+                            if (targetstr == NULL) {
+                                targetstr = coordinate->label[shift_index][0];
+                            }
+                            if (targetstr == NULL) {
+                                targetstr = coordinate->key_value[shift_index][button_context->multitap_index];
+                            }
+                            /*if(state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
+                                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ) {
+                                    targetstr = coordinate->long_key_value;
+                            }*/
+                            const sclchar *sayit = cache->find_substituted_string(targetstr);
+                            utils->play_tts(sayit);
+                        }
+                    }
+                }
+
+                context->set_cur_highlighted_window(window);
+                context->set_cur_highlighted_key(key_index);
+            }
+        }
+    }
+
+    return ret;
+}
+SCLKeyModifier
+CSCLController::get_drag_key_modifier(sclint deltax, sclint deltay, sclfloat dist, sclboolean check_farthest,
+                                      scltouchdevice touch_id, sclbyte extra_option) {
+    typedef struct {
+        double lowerbound;
+        double upperbound;
+        SCLKeyModifier modifier;
+    } DIRECTIONINFO;
+
+    CSCLContext *context = CSCLContext::get_instance();
+    SCLKeyModifier key_modifier = KEY_MODIFIER_NONE;
+
+    if (context) {
+        double theta = atan2(deltay , (deltax ? deltax : 1)); /* Avoid divide by 0 exception */
+        sclfloat ratio = fabs((sclfloat)deltay / (deltax ? deltax : 1));
+        SCLDragState cur_drag_state = context->get_cur_drag_state(touch_id);
+        if (extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS ||
+            extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG ||
+            extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN) { /* 8 directions */
+                /* If the theta is below 0, the direction is upward since the y coordinate grows downward */
+                /* The below angle values are customized for MoAKey, need to provide customizing API */
+                DIRECTIONINFO info[] = {
+                    {-8 * (M_PI / 8), -7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_LEFT},
+                    {-7 * (M_PI / 8), -5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP_LEFT},
+                    {-5 * (M_PI / 8), -2.7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP},
+                    {-2.7 * (M_PI / 8), -1.5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP_RIGHT},
+                    {-1.5 * (M_PI / 8),  1 * (M_PI / 8), KEY_MODIFIER_DIRECTION_RIGHT},
+                    { 1 * (M_PI / 8),  3 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN_RIGHT},
+                    { 3 * (M_PI / 8),  5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN},
+                    { 5 * (M_PI / 8),  7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN_LEFT},
+                    { 7 * (M_PI / 8),  8 * (M_PI / 8), KEY_MODIFIER_DIRECTION_LEFT},
+                };
+                for (size_t loop = 0; loop < sizeof(info) / sizeof(DIRECTIONINFO); loop++) {
+                    if (theta >= info[loop].lowerbound && theta <= info[loop].upperbound) {
+                        key_modifier = info[loop].modifier;
+                    }
+                }
+        } else { /* 4 directions */
+            /* If the state was dragging to one of 4 directions and the final release point is
+            * far enough from inital press point, and the angle is in between out predefined angle value */
+            if (extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE &&
+                cur_drag_state != SCL_DRAG_STATE_NONE && cur_drag_state != SCL_DRAG_STATE_INVALID &&
+                dist > SCL_DRAG_CURVE_RECOG_DIST &&
+                ratio > (1 / SCL_DRAG_CURVE_FINAL_ANGLE_VALUE) &&
+                ratio < SCL_DRAG_CURVE_FINAL_ANGLE_VALUE) {
+                    if (cur_drag_state == SCL_DRAG_STATE_DOWN) {
+                        if (deltax > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_DOWN_RIGHT;
+                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_DOWN_LEFT;
+                    }
+                    if (cur_drag_state == SCL_DRAG_STATE_UP) {
+                        if (deltax > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_UP_RIGHT;
+                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_UP_LEFT;
+                    }
+                    if (cur_drag_state == SCL_DRAG_STATE_LEFT) {
+                        if (deltay > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_LEFT_DOWN;
+                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_LEFT_UP;
+                    }
+                    if (cur_drag_state == SCL_DRAG_STATE_RIGHT) {
+                        if (deltay > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_RIGHT_DOWN;
+                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_RIGHT_UP;
+                    }
+            } else {
+                DIRECTIONINFO info[] = {
+                    {-4 * (M_PI / 4), -3 * (M_PI / 4), KEY_MODIFIER_DIRECTION_LEFT},
+                    {-3 * (M_PI / 4), -1 * (M_PI / 4), KEY_MODIFIER_DIRECTION_UP},
+                    {-1 * (M_PI / 4),  1 * (M_PI / 4), KEY_MODIFIER_DIRECTION_RIGHT},
+                    { 1 * (M_PI / 4),  3 * (M_PI / 4), KEY_MODIFIER_DIRECTION_DOWN},
+                    { 3 * (M_PI / 4),  4 * (M_PI / 4), KEY_MODIFIER_DIRECTION_LEFT},
+                };
+                for (size_t loop = 0; loop < sizeof(info) / sizeof(DIRECTIONINFO); loop++) {
+                    if (theta >= info[loop].lowerbound && theta <= info[loop].upperbound) {
+                        key_modifier = info[loop].modifier;
+                    }
+                }
+            }
+        }
+
+        if (extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG ||
+            extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_LONG) {
+                if (key_modifier >= KEY_MODIFIER_DIRECTION_LEFT &&
+                    key_modifier <= KEY_MODIFIER_DIRECTION_DOWN_RIGHT) {
+                        key_modifier = (SCLKeyModifier)(key_modifier + 8); // Add LONG attribute;
+                }
+        }
+        if (check_farthest || context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN) {
+            if (key_modifier >= KEY_MODIFIER_DIRECTION_LEFT &&
+                key_modifier <= KEY_MODIFIER_DIRECTION_DOWN_RIGHT) {
+                    key_modifier = (SCLKeyModifier)(key_modifier + 16); // Add RETURN attribute;
+            }
+        }
+    }
+
+    return key_modifier;
+}
+
+sclboolean
+CSCLController::process_button_release_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+                                             scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+    sclboolean redraw = FALSE;
+    sclboolean fire_event = FALSE;
+    SCLKeyModifier key_modifier = KEY_MODIFIER_NONE;
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLFeedback *feedback = CSCLFeedback::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (!sclres_manager) return FALSE;
+
+    PSclLayout sclres_layout = sclres_manager->get_layout_table();
+    PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+    if (!sclres_layout || !sclres_input_mode_configure) return FALSE;
+
+    SclButtonContext *button_context = NULL;
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+
+    if (cache) {
+        button_context = cache->get_cur_button_context(window, key_index);
+        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+    }
+
+    const SclLayoutKeyCoordinate *targetCoordinate = NULL;
+
+    if (utils && feedback && windows && context && state && handler && cache && button_context && coordinate) {
+        scl8 savedInputMode = context->get_input_mode();
+
+        sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+        scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+
+        if (actual_event) {
+             if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+                 /* When calling mouse_release, the seq order of current multitouch events will be changed,
+                    so we put all the multitouch events into a vector and use them afterwards for releasing */
+                 sclboolean finished = FALSE;
+                 sclint loop = 0;
+                 sclint multi_touch_context_num = context->get_multi_touch_context_num();
+                 std::vector<SclUIEventDesc> multi_touch_events;
+                 for (loop = 0;loop < multi_touch_context_num;loop++) {
+                     SclUIEventDesc desc;
+                     context->get_multi_touch_event(loop, &desc);
+                     multi_touch_events.push_back(desc);
+                 }
+                 for (loop = 0;loop < multi_touch_context_num && !finished;loop++) {
+                     SclUIEventDesc desc = multi_touch_events[loop];
+                     if (desc.touch_id != touch_id) {
+                         sclwindow cur_pressed_window = context->get_cur_pressed_window(desc.touch_id);
+                         scl8 cur_pressed_key = context->get_cur_pressed_key(desc.touch_id);
+                         const SclLayoutKeyCoordinate *cur_pressed_coordinate =
+                             cache->get_cur_layout_key_coordinate(cur_pressed_window, cur_pressed_key);
+                         if (cur_pressed_coordinate) {
+                             if (cur_pressed_coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+                                 mouse_release(context->get_cur_moving_window(desc.touch_id),
+                                     context->get_cur_moving_point(desc.touch_id).x,
+                                     context->get_cur_moving_point(desc.touch_id).y,
+                                     desc.touch_id, FALSE);
+                             }
+                         }
+                     } else {
+                         finished = TRUE;
+                     }
+                 }
+             }
+         }
+
+        /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
+        sclint thresholdX = 0;
+        sclint thresholdY = 0;
+        if (context) {
+            if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
+                thresholdX = utils->get_scaled_x(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_X);
+                thresholdY = utils->get_scaled_y(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_Y);
+            }
+        }
+
+        /* Check if the pressed button's type is directional button */
+        if (coordinate->button_type == BUTTON_TYPE_DIRECTION || coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+            if (context) {
+                if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
+                    ret = TRUE;
+                    sclboolean check_farthest = FALSE;
+
+                    sclint startx = x;
+                    sclint starty = y;
+
+                    /* If the buttontype is RELATIVE_DIRECTION, get the distance from last move point */
+                    if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+                        startx = context->get_prev_moving_point(touch_id).x;
+                        starty = context->get_prev_moving_point(touch_id).y;
+                    } else {
+                        startx = context->get_cur_pressed_point(touch_id).x;
+                        starty = context->get_cur_pressed_point(touch_id).y;
+                    }
+
+                    sclint deltax = x - startx;
+                    sclint deltay = y - starty;
+
+                    sclfloat dist = utils->get_distance(x, y, startx, starty);
+                    sclfloat direction_recog_dist = SCL_DIRECTION_RECOG_DIST * utils->get_smallest_scale_rate();
+                    if (coordinate->is_side_button) {
+                        direction_recog_dist = SCL_DIRECTION_RECOG_DIST_SIDE * utils->get_smallest_scale_rate();
+                    };
+                    if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+                        direction_recog_dist = SCL_DIRECTION_RELATIVE_RECOG_DIST * utils->get_smallest_scale_rate();
+                    }
+                    if (context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN &&
+                        coordinate->button_type != BUTTON_TYPE_RELATIVE_DIRECTION) {
+                        if (coordinate->extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN ||
+                            coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN ||
+                            coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE) {
+                                deltax = context->get_farthest_move_point(touch_id).x - context->get_cur_pressed_point(touch_id).x;
+                                deltay = context->get_farthest_move_point(touch_id).y - context->get_cur_pressed_point(touch_id).y;
+                                dist = utils->get_distance(context->get_farthest_move_point(touch_id), context->get_cur_pressed_point(touch_id));
+                                check_farthest = TRUE;
+                        }
+                    }
+                    if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+                        key_modifier = context->get_cur_key_modifier(touch_id);
+                    } else if (dist > direction_recog_dist) {
+                        key_modifier = get_drag_key_modifier(deltax, deltay, dist, check_farthest, touch_id, coordinate->extra_option);
+                    }
+                }
+            }
+        }
+
+        /* First check if this button is enabled in current active sublayout */
+        sclboolean subLayoutMatch = TRUE;
+        if (coordinate->sub_layout && context->get_cur_sublayout()) {
+            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+                subLayoutMatch = FALSE;
+            }
+        }
+        /* Check if the event occured inside this button's rectangle */
+        if ( x >= coordinate->x - coordinate->add_hit_left  - thresholdX &&
+                x < coordinate->x + coordinate->width + coordinate->add_hit_right + thresholdX &&
+                y >= coordinate->y - coordinate->add_hit_top - thresholdY &&
+                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom + thresholdY &&
+                subLayoutMatch ) {
+            ret = TRUE;
+        }
+
+        if (ret) {
+            /* for feedback */
+            feedback->button_released(window, key_index);
+
+            /* If this button's index is the same as the one initially pressed */
+            if (pressed_window == window && pressed_key == key_index) {
+                fire_event = TRUE;
+                targetCoordinate = coordinate;
+            } else {
+                const SclLayoutKeyCoordinate *pressed_coordinate =
+                    cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+                if (pressed_coordinate) {
+                    if (check_event_transition_enabled(pressed_coordinate, coordinate)) {
+                        fire_event = TRUE;
+                        targetCoordinate = pressed_coordinate;
+                    } else {
+                        ret = FALSE;
+                    }
+                }
+            }
+        }
+
+        /* In case of mode change buttons, event should be fired only when it was pressed lastly */
+        if (fire_event) {
+            if (coordinate->key_type == KEY_TYPE_MODECHANGE) {
+                if (touch_id != context->get_last_touch_device_id()) {
+                    fire_event = FALSE;
+                }
+            }
+        }
+
+        /* If this key's modifier is LONGKEY, this means the event is already fired so skip this one */
+        if (context->get_cur_key_modifier(touch_id) == KEY_MODIFIER_LONGKEY) {
+            fire_event = FALSE;
+        }
+
+        /* Don't fire any events if we're in longkey state */
+        if (state->get_cur_action_state() != ACTION_STATE_BASE_LONGKEY &&
+                state->get_cur_action_state() != ACTION_STATE_BASE_REPEATKEY &&
+                state->get_cur_action_state() != ACTION_STATE_POPUP_LONGKEY &&
+                state->get_cur_action_state() != ACTION_STATE_POPUP_REPEATKEY) {
+            if (ret) {
+                SCLShiftState shift_index = context->get_shift_state();
+                if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+                if (context->get_caps_lock_mode()) {
+                    shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+                }
+
+                SclUIEventDesc key_event_desc;
+                if (targetCoordinate) {
+                    key_event_desc.key_type = targetCoordinate->key_type;
+
+                    key_event_desc.key_value = targetCoordinate->key_value[shift_index][button_context->multitap_index];
+                    key_event_desc.key_event = targetCoordinate->key_event[shift_index][button_context->multitap_index];
+                }
+                key_event_desc.key_modifier = key_modifier;
+
+                key_event_desc.event_type = EVENT_TYPE_RELEASE;
+                key_event_desc.touch_id = touch_id;
+                key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                if (handler->on_event_drag_state_changed(key_event_desc) != SCL_EVENT_PASS_ON) {
+                    fire_event = FALSE;
+                }
+            }
+            if (fire_event) {
+                if (targetCoordinate) {
+                    SCLShiftState shift_index = context->get_shift_state();
+                    if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+                    if (context->get_caps_lock_mode()) {
+                        shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+                    }
+
+                    SclUIEventDesc key_event_desc;
+                    key_event_desc.key_type = targetCoordinate->key_type;
+
+                    key_event_desc.event_type = EVENT_TYPE_RELEASE;
+                    key_event_desc.touch_id = touch_id;
+                    key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                    key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                    key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                    key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                    switch (targetCoordinate->button_type) {
+                    case BUTTON_TYPE_NORMAL:
+                    case BUTTON_TYPE_GRAB :
+                    case BUTTON_TYPE_SELFISH:
+                    case BUTTON_TYPE_DIRECTION :
+                    case BUTTON_TYPE_RELATIVE_DIRECTION: {
+                        SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
+                        if (pressed_context) {
+                            if (!(targetCoordinate->use_repeat_key) && pressed_context->state == BUTTON_STATE_PRESSED) {
+                                key_event_desc.key_value = targetCoordinate->key_value[shift_index][0];
+                                key_event_desc.key_event = targetCoordinate->key_event[shift_index][0];
+                                key_event_desc.key_modifier = key_modifier;
+                                handler->on_event_key_clicked(key_event_desc);
+                            }
+                        }
+                    }
+                    break;
+                    case BUTTON_TYPE_MULTITAP:
+                    case BUTTON_TYPE_ROTATION: {
+                        if (targetCoordinate->button_type == BUTTON_TYPE_MULTITAP) {
+                            if (window == context->get_last_event_fired_window() &&
+                                key_index == context->get_last_event_fired_key()) {
+                                key_modifier = KEY_MODIFIER_MULTITAP_REPEAT;
+                            } else {
+                                key_modifier = KEY_MODIFIER_MULTITAP_START;
+                            }
+                        } else {
+                            key_modifier = KEY_MODIFIER_NONE;
+                        }
+                        if (button_context->multitap_index < MAX_SIZE_OF_MULTITAP_CHAR) {
+                            key_event_desc.key_value = coordinate->key_value[shift_index][button_context->multitap_index];
+                            key_event_desc.key_event = coordinate->key_event[shift_index][button_context->multitap_index];
+                            key_event_desc.key_modifier = key_modifier;
+                            if (SCL_EVENT_PASS_ON == handler->on_event_key_clicked(key_event_desc)) {
+                                CSCLEvents *events = CSCLEvents::get_instance();
+                                events->destroy_timer(SCL_TIMER_MULTITAP);
+                                events->create_timer(SCL_TIMER_MULTITAP, m_multitap_delay_duration, 0);
+                            }
+                        }
+                        /* Check if the multikey index is in valid range, and increase by one */
+                        if (button_context->multitap_index >= MAX_SIZE_OF_MULTITAP_CHAR - 1) {
+                            button_context->multitap_index = 0;
+                        } else {
+                            sclbyte orgindex = button_context->multitap_index;
+                            button_context->multitap_index = 0;
+                            if (targetCoordinate->key_value[shift_index][orgindex + 1]) {
+                                if (strlen(targetCoordinate->key_value[shift_index][orgindex + 1]) > 0) {
+                                    button_context->multitap_index = orgindex + 1;
+                                }
+                            }
+                        }
+                    }
+                    break;
+                    case BUTTON_TYPE_DRAG : {
+                    }
+                    break;
+                    case BUTTON_TYPE_TOGGLE : {
+                        SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
+                        if (pressed_context) {
+                            if (!(targetCoordinate->use_repeat_key) && pressed_context->state == BUTTON_STATE_PRESSED) {
+                                key_event_desc.key_value = targetCoordinate->key_value[shift_index][0];
+                                key_event_desc.key_event = targetCoordinate->key_event[shift_index][0];
+                                if (pressed_context->toggled) {
+                                    key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+                                } else {
+                                    key_event_desc.key_modifier = KEY_MODIFIER_TOGGLED;
+                                }
+                                if (SCL_EVENT_PASS_ON == handler->on_event_key_clicked(key_event_desc)) {
+                                    pressed_context->toggled = !(pressed_context->toggled);
+                                }
+                            }
+                        }
+                    }
+                    case BUTTON_TYPE_UIITEM: break;
+                    case MAX_BUTTON_TYPE: break;
+                    default: break;
+                    }
+                    switch (coordinate->popup_type) {
+                    case POPUP_TYPE_BTN_RELEASE_POPUP:
+                    case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE: {
+                        SCLDragState dragstate = context->get_cur_drag_state(touch_id);
+                        sclint popup_input_mode = NOT_USED;
+
+                        SclNotiPopupOpeningDesc desc;
+                        desc.ui_event_desc = &key_event_desc;
+
+                        if (scl_check_arrindex(dragstate, SCL_DRAG_STATE_MAX)) {
+                            desc.input_mode = coordinate->popup_input_mode[dragstate];
+                            popup_input_mode = sclres_manager->get_inputmode_id(coordinate->popup_input_mode[dragstate]);
+                            /* FIXME */
+                            //if (!scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP)) {
+                            if (!scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE)) {
+                                desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
+                            }
+                        }
+                        if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
+                            popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
+                            SCLDisplayMode display_mode = context->get_display_mode();
+                            /* FIXME */
+                            //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
+                            if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
+                                scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+                                sclshort popupLayoutId =
+                                    sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
+                                if (popupLayoutId == NOT_USED) {
+                                    // deal with NOT_USED
+                                    LOGD("popupLayoutID is not used.");
+                                }
+                                SclLayout *layout = NULL;
+                                /* FIXME */
+                                //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
+                                if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
+                                    layout = &sclres_layout[popupLayoutId];
+                                }
+                                if (layout) {
+                                    SclRectangle popupRect;
+                                    SclRectangle baseWndRect;
+                                    windows->get_window_rect(windows->get_base_window(), &baseWndRect);
+                                    popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
+                                    popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
+
+                                    //popupRect.width = utils->get_scale_x(layout->width);
+                                    //popupRect.height= utils->get_scale_y(layout->height);
+                                    if (!(sclres_manager->loaded(popupLayoutId))) {
+                                        sclres_manager->load(popupLayoutId);
+                                    }
+                                    popupRect.width = layout->width;
+                                    popupRect.height = layout->height;
+
+                                    /* Let's make sure this popup window does not go beyond the screen area */
+                                    sclint scr_w, scr_h;
+                                    utils->get_screen_resolution(&scr_w, &scr_h);
+
+                                    if (popupRect.x + popupRect.width > scr_w) {
+                                        popupRect.x = scr_w - popupRect.width;
+                                    }
+                                    if (popupRect.y + popupRect.height > scr_h) {
+                                        popupRect.y = scr_h - popupRect.height;
+                                    }
+
+                                    SclWindowOpener opener;
+                                    opener.window = window;
+                                    opener.key = key_index;
+
+                                    sclwindow popup_window = windows->open_popup(
+                                        opener,
+                                        popupRect,
+                                        popup_input_mode,
+                                        popupLayoutId,
+                                        coordinate->popup_type,
+                                        sclres_input_mode_configure[popup_input_mode].use_virtual_window,
+                                        sclres_input_mode_configure[popup_input_mode].use_dim_window,
+                                        coordinate->extract_offset_x,
+                                        coordinate->extract_offset_y,
+                                        sclres_input_mode_configure[popup_input_mode].timeout);
+
+                                    SclNotiPopupOpenedDesc opened_desc;
+                                    opened_desc.ui_event_desc = &key_event_desc;
+                                    opened_desc.input_mode = desc.input_mode;
+                                    opened_desc.window = popup_window;
+                                    handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
+
+                                    windows->hide_window(windows->get_magnifier_window());
+                                    _play_tts_for_input_mode_name(popup_input_mode);
+                                }
+                            }
+                        }
+                    }
+                    break;
+                    case POPUP_TYPE_AUTO_POPUP:
+                    case POPUP_TYPE_BTN_PRESS_POPUP_DRAG:
+                    case POPUP_TYPE_NONE:
+                        /* Nothing to do in here */
+                        break;
+                    case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE: break;
+                    case POPUP_TYPE_BTN_LONGPRESS_POPUP: break;
+                    case MAX_POPUP_TYPE: break;
+                    default: break;
+                    }
+                }
+
+                context->set_last_event_fired_window(window);
+                context->set_last_event_fired_key(key_index);
+            }
+        } else {
+            if (targetCoordinate) {
+                SCLShiftState shift_index = context->get_shift_state();
+                if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+                if (context->get_caps_lock_mode()) {
+                    shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+                }
+
+                SclUIEventDesc key_event_desc;
+                key_event_desc.key_type = targetCoordinate->key_type;
+
+                key_event_desc.key_value = targetCoordinate->key_value[shift_index][button_context->multitap_index];
+                key_event_desc.key_event = targetCoordinate->key_event[shift_index][button_context->multitap_index];
+                key_event_desc.key_modifier = key_modifier;
+
+                key_event_desc.event_type = EVENT_TYPE_RELEASE;
+                key_event_desc.touch_id = touch_id;
+                key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                handler->on_event_drag_state_changed(key_event_desc);
+            }
+        }
+
+        /* If this button was pressed, initialize the button context regardless of event  */
+        if (button_context->state == BUTTON_STATE_PRESSED) {
+            /* But, if this button should be in pressed state in other multitouch id, do not initialize */
+            sclboolean found = FALSE;
+            for (sclint loop = 0;loop < context->get_multi_touch_context_num() && !found;loop++) {
+                SclUIEventDesc desc;
+                context->get_multi_touch_event(loop, &desc);
+                if (desc.touch_id != touch_id) {
+                    MultiTouchContext *multi_touch_context = context->find_multi_touch_context(desc.touch_id);
+                    if (multi_touch_context) {
+                        if (multi_touch_context->cur_pressed_window == window &&
+                            multi_touch_context->cur_pressed_key == key_index) {
+                            found = TRUE;
+                        }
+                    }
+                }
+            }
+            if (!found) {
+                button_context->state = BUTTON_STATE_NORMAL;
+                redraw = TRUE;
+            }
+        }
+
+        /* If this button needs to be redrawn */
+        if (redraw) {
+#ifdef DIRECTLY_DRAW_ON_EVENTS
+            CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+            if (builder) {
+                builder->draw_button(window, NULL, key_index, button_context->state, TRUE);
+            }
+#else
+            if (savedInputMode == context->get_input_mode()) {
+                windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+            }
+
+#endif
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLController::mouse_press(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+
+    if (m_input_events_disabled) return FALSE;
+
+    //utils->log("Controller::mouse_press : %d %d\n", x, y);
+
+    /* Adjust x,y coordinate by touch offset */
+    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    sclint button_index = NOT_USED;
+    SclWindowContext *window_context = NULL;
+    if (windows && cache) {
+        const SclLayout *layout = cache->get_cur_layout(window);
+        if (layout) {
+            x += layout->mouse_manipulate_x;
+            y += layout->mouse_manipulate_y;
+        }
+        window_context = windows->get_window_context(window);
+        /* If the dim window is virtual and currently active, let's just skip this event */
+        if (windows->is_base_window(window)) {
+            SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
+            if (dim_window_context) {
+                LOGD("dim window is_virtual:%d, hidden:%d", dim_window_context->is_virtual, dim_window_context->hidden);
+                if (/*dim_window_context->is_virtual &&*/ !(dim_window_context->hidden)) {
+                    window = windows->get_dim_window();
+                    window_context = dim_window_context;
+                }
+            }
+        }
+    }
+
+    if (cache && state && windows && context && window_context) {
+        SCLDisplayMode display_mode = context->get_display_mode();
+        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+        PSclDefaultConfigure default_configure = NULL;
+        if (sclres_manager) {
+            default_configure = sclres_manager->get_default_configure();
+        }
+        if (default_configure) {
+            adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
+        }
+
+        sclboolean isSubEvent = FALSE;
+        if (context->get_multi_touch_context_num() > 0) {
+            SclUIEventDesc desc;
+            context->get_multi_touch_event(0, &desc);
+            sclwindow pressed_window = context->get_cur_pressed_window(desc.touch_id);
+            scl8 pressed_key = context->get_cur_pressed_key(desc.touch_id);
+            SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+            if (coordinate) {
+                if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_GRAB_SUB_EVENTS) {
+                    isSubEvent = TRUE;
+                    if (utils)
+                        utils->play_vibration(DEFAULT_VIBRATION_STYLE, DEFAULT_VIBRATION_DURATION);
+                }
+            }
+        }
+        context->create_multi_touch_context(touch_id, isSubEvent);
+        context->set_cur_pressed_window(touch_id, window);
+        context->set_cur_pressed_point(touch_id, x, y);
+        context->set_cur_pressed_time(touch_id);
+        context->set_cur_moving_window(touch_id, window);
+        context->set_cur_moving_point(touch_id, x, y);
+        context->set_last_touch_device_id(touch_id);
+        context->set_cur_drag_state(touch_id, SCL_DRAG_STATE_NONE);
+        context->set_cur_key_modifier(touch_id, KEY_MODIFIER_NONE);
+        for (sclint labelidx = 0;labelidx < MAX_SIZE_OF_LABEL_FOR_ONE;labelidx++) {
+            context->set_custom_magnifier_label(touch_id, labelidx, NULL);
+        }
+
+        /* If there is postponed update of button, update it now */
+        CSCLEvents *events = CSCLEvents::get_instance();
+        sclwindow last_win = context->get_last_pressed_window();
+        scl8 last_key = context->get_last_pressed_key();
+        if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
+            const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(last_win, last_key);
+            if (coords) {
+                windows->update_window(last_win, coords->x, coords->y, coords->width, coords->height);
+            }
+        }
+        context->set_prev_pressed_window(touch_id, SCLWINDOW_INVALID);
+        context->set_prev_pressed_key(touch_id, NOT_USED);
+        context->set_prev_drag_state(touch_id, SCL_DRAG_STATE_NONE);
+        context->set_prev_moving_point(touch_id, x, y);
+
+        /* Destroy key related timers */
+        events->destroy_timer(SCL_TIMER_BUTTON_DELAY);
+        events->destroy_timer(SCL_TIMER_AUTOPOPUP);
+        events->destroy_timer(SCL_TIMER_SHORT_LONGKEY);
+        events->destroy_timer(SCL_TIMER_LONGKEY);
+        events->destroy_timer(SCL_TIMER_REPEATKEY);
+        events->destroy_timer(SCL_TIMER_MULTITAP);
+
+        /* Do what has to be done when mouse gets pressed */
+        handle_engine_signal(SCL_SIG_MOUSE_PRESS, window);
+
+        /* Adjust event x and y positions as relative position to the virtual window */
+        if (window_context) {
+            /*if (window_context->isVirtual) {
+                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                if (base_window_context) {
+                    x -= (window_context->x - base_window_context->x);
+                    y -= (window_context->y - base_window_context->y);
+                }
+            }*/
+        }
+
+        if (!isSubEvent) {
+            sclboolean process_finished = FALSE;
+            do {
+                /* Iterate all the buttons and inform the event */
+                sclboolean ended = FALSE;
+                for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+                    SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
+                    const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+                    if (button_context && coordinate) {
+                        if (!(button_context->used)) {
+                            ended = TRUE;
+                        } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                                    coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                            if (process_button_pressed_event(window, x, y, loop, touch_id, actual_event)) {
+                                if (windows->is_base_window(window)) {
+                                    state->set_cur_action_state(ACTION_STATE_BASE_PRESS);
+                                } else {
+                                    state->set_cur_action_state(ACTION_STATE_POPUP_PRESS);
+                                }
+                                button_index = loop;
+                                ret = TRUE;
+                            }
+                        }
+                    }
+                }
+
+                /* For covering a missing area about 1 pixel */
+                if (!ret) {
+                    for (int loop = 0;loop < MAX_KEY;loop++) {
+                        SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
+                        const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+                        if (button_context && coordinate) {
+                            if (!(button_context->used)) {
+                                break;
+                            } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                                        coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                                if (process_button_pressed_event(window, x+1, y+1, loop, touch_id, actual_event)) {
+                                    if (windows->is_base_window(window)) {
+                                        state->set_cur_action_state(ACTION_STATE_BASE_PRESS);
+                                    } else {
+                                        state->set_cur_action_state(ACTION_STATE_POPUP_PRESS);
+                                    }
+                                    button_index = loop;
+                                    break;
+                                }
+                            }
+                        } else {
+                            break;
+                        }
+                    }
+                }
+
+                if (windows->is_base_window(window)) {
+                    process_finished = TRUE;
+                } else if (button_index != NOT_USED) {
+                    process_finished = TRUE;
+                } else {
+                    const SclLayout *layout = cache->get_cur_layout(window);
+                    if (layout) {
+                        if (layout->use_sw_background && layout->bg_color.a == 0) {
+                            /* If we could not find appropriate button in this popup window and the popup is transparent */
+                            SclWindowContext *base_window_context =
+                                windows->get_window_context(windows->get_base_window());
+                            if (base_window_context) {
+                                x = (window_context->geometry.x + x - base_window_context->geometry.x);
+                                y = (window_context->geometry.y + y - base_window_context->geometry.y);
+                            }
+                            window = windows->get_base_window();
+                        } else {
+                            process_finished = TRUE;
+                        }
+                    } else {
+                        process_finished = TRUE;
+                    }
+                }
+            } while (!process_finished);
+        }
+
+        sclwindow skip_window = window;
+        if (ret && button_index != NOT_USED) {
+            const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, button_index);
+            if (coordinate) {
+                sclboolean dont_close_popup = FALSE;
+                if (coordinate->dont_close_popup) {
+                    dont_close_popup = TRUE;
+                }
+                /* If the button's popup type is drag type, the opened popup could be the one opened by this press event */
+                if (coordinate->popup_type == POPUP_TYPE_BTN_PRESS_POPUP_DRAG) {
+                    /* Check the opened popup was opened by this button */
+                    sclwindow popupwin = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                    SclWindowContext *popup_window_context = windows->get_window_context(popupwin);
+                    if (popup_window_context) {
+                        SclWindowOpener opener = popup_window_context->opener;
+                        if (opener.window == window && opener.key == button_index) {
+                            dont_close_popup = TRUE;
+                        }
+                    }
+                }
+                if (dont_close_popup) {
+                    skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                }
+            }
+        } else {
+            SclUIEventDesc key_event_desc;
+            key_event_desc.event_type = EVENT_TYPE_PRESS;
+
+            SclPoint curpoint = {x, y};
+            key_event_desc.touch_id = touch_id;
+            key_event_desc.mouse_pressed_point = curpoint;
+            key_event_desc.mouse_current_point = curpoint;
+            key_event_desc.mouse_farthest_point = curpoint;
+
+            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+            CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+            if (handler) {
+                handler->on_event_drag_state_changed(key_event_desc);
+            }
+        }
+        windows->close_all_popups(skip_window);
+
+        /* When press event occured in popup window, reset POPUP_TIMEOUT timer */
+        if (!(windows->is_base_window(window))) {
+            if (window_context->timeout > 0) {
+                events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+                events->create_timer(SCL_TIMER_POPUP_TIMEOUT, window_context->timeout, 0, TRUE);
+            }
+        } else if (skip_window != window) { /* Or the pressed button has dont_close_popup property, reset POPUP_TIMEOUT timer */
+            //SclWindowContext *skip_window_context = windows->get_window_context(skip_window, FALSE);
+            SclWindowContext *skip_window_context = windows->get_window_context(skip_window);
+            if (skip_window_context) {
+                if (skip_window_context->timeout > 0) {
+                    events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+                    events->create_timer(SCL_TIMER_POPUP_TIMEOUT, skip_window_context->timeout, 0, TRUE);
+                }
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+sclboolean
+CSCLController::mouse_release(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+
+    //if (m_input_events_disabled) return FALSE;
+
+    //utils->log("Controller::mouse_release : %d %d\n", x, y);
+    /* Adjust x,y coordinate by touch offset */
+    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    CSCLEvents *events = CSCLEvents::get_instance();
+
+    sclint button_index = NOT_USED;
+
+    if (cache && state && windows && context && utils && handler && events &&
+        context->find_multi_touch_context(touch_id)) {
+        const SclLayout *layout = cache->get_cur_layout(window);
+        if (layout) {
+            x += layout->mouse_manipulate_x;
+            y += layout->mouse_manipulate_y;
+        }
+
+        sclwindow skip_window = SCLWINDOW_INVALID;
+        SCLDisplayMode display_mode = context->get_display_mode();
+
+        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+        PSclDefaultConfigure default_configure = NULL;
+        if (sclres_manager) {
+            default_configure = sclres_manager->get_default_configure();
+        }
+        if (default_configure) {
+            adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
+        }
+
+        context->set_cur_moving_window(touch_id, SCLWINDOW_INVALID);
+
+        sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+        scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+        //SclWindowContext *window_context = windows->get_window_context(window, TRUE);
+        SclWindowContext *window_context = windows->get_window_context(window);
+        /* Adjust event x and y positions as relative position to the virtual window */
+        if (window_context) {
+            /*if (window_context->isVirtual) {
+                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                if (base_window_context) {
+                    x -= (window_context->x - base_window_context->x);
+                    y -= (window_context->y - base_window_context->y);
+                }
+            }*/
+            /* If the dim window is virtual and currently active, consider base window's event is occured in dim window */
+            if (windows->is_base_window(window)) {
+                SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
+                if (dim_window_context) {
+                    if (dim_window_context->is_virtual && !(dim_window_context->hidden)) {
+                        window = windows->get_dim_window();
+                        window_context = dim_window_context;
+                    }
+                }
+            }
+        }
+
+        /* Iterate all the buttons and inform the event */
+        sclboolean ended = FALSE;
+
+        /* FIXME : The routine below seems to be removed, which was originally requested by Vodafone,
+         * to slow down the speed of repeat key right before stopping repeatkey event */
+        /* if (state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY) {
+            if (m_key_repeated_num > 10) {
+                utils->sleep(100);
+                process_button_repeat_pressed_event(pressed_window, pressed_key, touch_id);
+            }
+            ended = TRUE;
+        }*/
+
+        if (context->get_cur_pressed_window(touch_id) == window) {
+            if (abs(context->get_cur_pressed_point(touch_id).x - x) > utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD) ||
+                abs(context->get_cur_pressed_point(touch_id).y - y) > utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD) )
+            {
+                struct timeval t0 = context->get_cur_pressed_time(touch_id);
+                struct timeval t1;
+                gettimeofday(&t1, NULL);
+                float etime;
+                etime = ((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec))/1000.0;
+                if (etime < SCL_FLICK_GESTURE_RECOG_TIME) {
+                    SCLDragType drag_type = DRAG_NONE;
+                    if (x > context->get_cur_pressed_point(touch_id).x + utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+                        drag_type = DRAG_RIGHT;
+                    }
+                    if (x < context->get_cur_pressed_point(touch_id).x - utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+                        drag_type = DRAG_LEFT;
+                    }
+                    if (y > context->get_cur_pressed_point(touch_id).y + utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+                        drag_type = DRAG_DOWN;
+                    }
+                    if (y < context->get_cur_pressed_point(touch_id).y - utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+                        drag_type = DRAG_UP;
+                    }
+                    SclNotiGestureFlickDesc desc;
+                    SclUIEventDesc ui_event_desc;
+                    ui_event_desc.key_value = NULL;
+                    ui_event_desc.key_event = NOT_USED;
+                    ui_event_desc.key_modifier = KEY_MODIFIER_NONE;
+                    ui_event_desc.event_type = EVENT_TYPE_RELEASE;
+                    ui_event_desc.touch_id = touch_id;
+                    ui_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                    ui_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                    ui_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+                    ui_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+                    desc.ui_event_desc = &ui_event_desc;
+                    desc.drag_type = drag_type;
+                    if (handler->on_event_notification(SCL_UINOTITYPE_GESTURE_FLICK, &desc)) {
+                        ended = TRUE;
+                    }
+                }
+            }
+        }
+
+        /* FIXME : We should consider this kind of action in general manner, not only specific to autopopup */
+        /* And also, this kind of implementation only selects button that was highlighted at least once. */
+        // {
+        //SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window, FALSE);
+        SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window);
+        if (pressed_window_context) {
+            utils->log("PRESSED CTX : %p %d %d\n", pressed_window,
+                pressed_window_context->geometry.x, pressed_window_context->geometry.y);
+            //if (pressedCtx->popuptype == POPUP_TYPE_AUTO_POPUP) {
+            sclboolean grab_event = FALSE;
+            const SclLayout *pressed_layout = cache->get_cur_layout(pressed_window);
+            if (pressed_layout) {
+                if (pressed_layout->style == LAYOUT_STYLE_POPUP_GRAB) {
+                    grab_event = TRUE;
+                }
+                /* If the topmost window has the POPUP_GRAB style, find the nearest button to the mouse pointer */
+                if (grab_event) {
+                    /* If the layout's addGrab* values are defined, process this event only if the event occured inside grab area */
+                    sclboolean in_grab_area = TRUE;
+                    if (pressed_layout->add_grab_left != NOT_USED &&
+                        x < (pressed_window_context->geometry.x - pressed_layout->add_grab_left)) {
+                        in_grab_area = FALSE;
+                    }
+                    if (pressed_layout->add_grab_right != NOT_USED &&
+                        x > (pressed_window_context->geometry.x + pressed_window_context->geometry.width
+                        + pressed_layout->add_grab_right)) {
+                        in_grab_area = FALSE;
+                    }
+                    if (pressed_layout->add_grab_top != NOT_USED &&
+                        y < (pressed_window_context->geometry.y - pressed_layout->add_grab_top)) {
+                        in_grab_area = FALSE;
+                    }
+                    if (pressed_layout->add_grab_bottom != NOT_USED &&
+                        y > (pressed_window_context->geometry.y + pressed_window_context->geometry.height
+                        + pressed_layout->add_grab_bottom)) {
+                        in_grab_area = FALSE;
+                    }
+                    if (in_grab_area) {
+                        SclLayoutKeyCoordinate *coord = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+                        if (coord) {
+                            x = coord->x + (coord->width / 2);
+                            y = coord->y + (coord->height / 2);
+
+                            for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+                                SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, loop);
+                                const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, loop);
+                                if (button_context && coordinate) {
+                                    if (!(button_context->used)) {
+                                        ended = TRUE;
+                                    } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                                                coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                                        if (process_button_release_event(pressed_window, x, y, loop, touch_id, actual_event)) {
+                                            ret = TRUE;
+                                            ended = TRUE;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        // }
+
+        SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
+        const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+        /* FIXME : The rule below would not be a general requirement. A policy is needed regarding this. */
+        /* Ignore base window's release event if a popup window is opened */
+        if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
+            if (windows->is_base_window(window)) {
+                ended = TRUE;
+                /* In case of direction button, the release event on other window should be processed */
+                if (coordinate && window_context && pressed_window_context) {
+                    if (coordinate->button_type == BUTTON_TYPE_DIRECTION || coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+                        sclint relx = (window_context->geometry.x + x) - pressed_window_context->geometry.x;
+                        sclint rely = (window_context->geometry.y + y) - pressed_window_context->geometry.y;
+                        if (process_button_release_event(pressed_window, relx, rely, pressed_key, touch_id, actual_event)) {
+                            button_index = pressed_key;
+                            ret = TRUE;
+                            x = coordinate->x + (coordinate->width / 2);
+                            y = coordinate->y + (coordinate->height / 2);
+                            skip_window = pressed_window;
+                        }
+                    }
+                }
+            }
+        }
+
+        sclboolean process_finished = FALSE;
+        do {
+            MultiTouchContext *multi_touch_context = context->find_multi_touch_context(touch_id);
+            if (multi_touch_context) {
+                if (!(multi_touch_context->is_sub_event)) {
+                    /* First check if the event occured in pressed key's threshold area */
+                    if (button_context && coordinate && !ended) {
+                        if (button_context->used && button_context->state != BUTTON_STATE_DISABLED) {
+                            if (process_button_release_event(pressed_window, x, y, pressed_key, touch_id, actual_event)) {
+                                button_index = pressed_key;
+                                ret = TRUE;
+                                x = coordinate->x + (coordinate->width / 2);
+                                y = coordinate->y + (coordinate->height / 2);
+                            }
+                        }
+                    }
+                    for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+                        SclButtonContext *cur_context = cache->get_cur_button_context(window, loop);
+                        const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+                        if (cur_context && cur_coordinate) {
+                            if (!(cur_context->used)) {
+                                ended = TRUE;
+                            } else if (cur_context->state != BUTTON_STATE_DISABLED &&
+                                        cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                                if (window != pressed_window || loop != pressed_key) {
+                                    if (process_button_release_event(window, x, y, loop, touch_id, actual_event)) {
+                                        button_index = loop;
+                                        ret = TRUE;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    process_finished = TRUE;
+
+                    SclUIEventDesc key_event_desc;
+                    key_event_desc.key_value = NULL;
+                    key_event_desc.key_event = NOT_USED;
+                    key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+                    key_event_desc.event_type = EVENT_TYPE_NONE;
+                    key_event_desc.touch_id = touch_id;
+                    key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                    key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                    key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                    key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                    handler->on_event_key_clicked(key_event_desc);
+                }
+            }
+
+            /* For covering a missing area about 1 pixel */
+            if (!ret) {
+                ended = FALSE;
+
+                if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
+                        state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
+                        state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
+                        state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
+                        state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
+                        state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
+                    if (windows->is_base_window(window)) {
+                        ended = TRUE;
+                    }
+                }
+
+                for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+                    SclButtonContext *cur_context = cache->get_cur_button_context(window, loop);
+                    if (cur_context && coordinate) {
+                        if (!(cur_context->used)) {
+                            ended = TRUE;
+                            break;
+                        } else if (cur_context->state != BUTTON_STATE_DISABLED &&
+                                    coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                            if (process_button_release_event(window, x+1, y+1, loop, touch_id)) {
+                                button_index = loop;
+                                ret = TRUE;
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            if (windows->is_base_window(window)) {
+                process_finished = TRUE;
+            } else if (button_index != NOT_USED) {
+                process_finished = TRUE;
+            } else {
+                if (layout && layout->use_sw_background && layout->bg_color.a == 0) {
+                    /* If we could not find appropriate button in this popup window and the popup is transparent */
+                    SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                    if (base_window_context && window_context) {
+                        x = (window_context->geometry.x + x - base_window_context->geometry.x);
+                        y = (window_context->geometry.y + y - base_window_context->geometry.y);
+                    }
+                    window = windows->get_base_window();
+                } else {
+                    process_finished = TRUE;
+                }
+            }
+        } while (!process_finished);
+
+        if (!ret) {
+            SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
+            const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+            SCLShiftState shift_index = context->get_shift_state();
+            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+            if (context->get_caps_lock_mode()) {
+                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+            }
+
+            SclUIEventDesc key_event_desc;
+            if (coordinate && button_context) {
+                key_event_desc.key_type = coordinate->key_type;
+
+                key_event_desc.key_value = coordinate->key_value[shift_index][button_context->multitap_index];
+                key_event_desc.key_event = coordinate->key_event[shift_index][button_context->multitap_index];
+            }
+            key_event_desc.key_modifier = context->get_cur_key_modifier(touch_id);;
+
+            key_event_desc.event_type = EVENT_TYPE_RELEASE;
+            key_event_desc.touch_id = touch_id;
+            key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+            key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+            key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+            handler->on_event_drag_state_changed(key_event_desc);
+        }
+
+        if (windows->is_base_window(window)) {
+            state->set_cur_action_state(ACTION_STATE_BASE_INIT);
+        } else {
+            state->set_cur_action_state(ACTION_STATE_POPUP_INIT);
+        }
+
+        /* Restore previously pressed button's context and redraw it */
+        if (button_context && coordinate) {
+            button_context->state = BUTTON_STATE_NORMAL;
+            /* Commented below line to postpone some of the feedback for releasing */
+            //windows->update_window(pressed_window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+        }
+
+        /* If there is postponed update of button, update it now */
+        sclwindow last_win = context->get_last_pressed_window();
+        scl8 last_key = context->get_last_pressed_key();
+        if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
+            const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(last_win, last_key);
+            if (coords) {
+                windows->update_window(last_win, coords->x, coords->y, coords->width, coords->height);
+            }
+        }
+
+        /* To postpone some of the feedback for releasing */
+        context->set_last_pressed_key(context->get_cur_pressed_key(touch_id));
+        context->set_last_pressed_window(context->get_cur_pressed_window(touch_id));
+
+        /* Do what has to be done when mouse gets released */
+        sclboolean signaled = FALSE;
+        if (coordinate) {
+            switch (coordinate->popup_type) {
+                case POPUP_TYPE_BTN_RELEASE_POPUP:
+                case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE:
+                case POPUP_TYPE_BTN_LONGPRESS_POPUP:
+                case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE:
+                    {
+                        /* Fix me : We should consider z-order */
+                        skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                        handle_engine_signal(SCL_SIG_MOUSE_RELEASE, skip_window);
+                        signaled = TRUE;
+                    }
+                    break;
+                case POPUP_TYPE_NONE: break;
+                case POPUP_TYPE_BTN_PRESS_POPUP_DRAG: break;
+                case POPUP_TYPE_AUTO_POPUP: break;
+                case MAX_POPUP_TYPE: break;
+                default: break;
+            }
+        }
+        if (!signaled) {
+            //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+            window_context = windows->get_window_context(window);
+            if (window_context) {
+                if (window_context->popup_type == POPUP_TYPE_BTN_RELEASE_POPUP ||
+                    window_context->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP) {
+                    /* Don't close window if the clicked button is a child of ReleasePopup window */
+                    skip_window = window;
+                    handle_engine_signal(SCL_SIG_MOUSE_RELEASE, window);
+                    signaled = TRUE;
+                }
+            }
+            if (!signaled) {
+                handle_engine_signal(SCL_SIG_MOUSE_RELEASE);
+            }
+        }
+
+        context->set_cur_pressed_key(touch_id, NOT_USED);
+        context->set_cur_pressed_window(touch_id, SCLWINDOW_INVALID);
+
+        if (ret && button_index != NOT_USED) {
+            const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, button_index);
+            if (cur_coordinate) {
+                if (cur_coordinate->dont_close_popup) {
+                    skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                }
+            }
+        } else {
+            if (pressed_window == windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP)) {
+                if (pressed_window_context) {
+                    if (pressed_window_context->popup_type != POPUP_TYPE_BTN_RELEASE_POPUP_ONCE &&
+                        pressed_window_context->popup_type != POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE &&
+                        pressed_window_context->popup_type != POPUP_TYPE_AUTO_POPUP &&
+                        pressed_window_context->popup_type != POPUP_TYPE_BTN_PRESS_POPUP_DRAG)
+                    {
+                        skip_window = pressed_window;
+                    }
+                }
+            }
+        }
+        windows->close_all_popups(skip_window);
+
+        /* Destroy key related timers */
+        events->destroy_timer(SCL_TIMER_AUTOPOPUP);
+        events->destroy_timer(SCL_TIMER_SHORT_LONGKEY);
+        events->destroy_timer(SCL_TIMER_LONGKEY);
+        events->destroy_timer(SCL_TIMER_REPEATKEY);
+
+        /* If there are more than 1 active multitouch ids, don't play button_delay trick */
+        if (context->get_multi_touch_context_num() == 1) {
+            /* To postpone some of the feedback for releasing */
+            events->create_timer(SCL_TIMER_BUTTON_DELAY, m_button_delay_duration, 0);
+        } else {
+            last_win = context->get_last_pressed_window();
+            last_key = context->get_last_pressed_key();
+
+            if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
+                const SclLayoutKeyCoordinate* last_coordinate = cache->get_cur_layout_key_coordinate(last_win, last_key);
+                if (last_coordinate) {
+                    windows->update_window(last_win,
+                        last_coordinate->x, last_coordinate->y, last_coordinate->width, last_coordinate->height);
+                }
+            }
+
+            windows->hide_window(windows->get_magnifier_window());
+            context->set_last_pressed_window(SCLWINDOW_INVALID);
+            context->set_last_pressed_key(NOT_USED);
+        }
+    }
+
+    if (context) {
+        if (touch_id == context->get_last_touch_device_id()) {
+            context->set_last_touch_device_id(SCLTOUCHDEVICE_INVALID);
+        }
+        context->destroy_multi_touch_context(touch_id);
+    }
+
+    return ret;
+}
+
+SCLDragState get_drag_state(sclint deltax, sclint deltay)
+{
+    SCLDragState ret = SCL_DRAG_STATE_MAX;
+
+    sclfloat ratio = fabs((sclfloat)deltay / (deltax ? deltax : 1));
+    /* If tan(theta) is smaller than our predefined value */
+    if (ratio <= (1 / SCL_DRAG_CURVE_4_DIRECTION_ANGLE_VALUE)) {
+        if (deltax > 0) {
+            ret = SCL_DRAG_STATE_RIGHT;
+        } else {
+            ret = SCL_DRAG_STATE_LEFT;
+        }
+    } else if (ratio >= SCL_DRAG_CURVE_4_DIRECTION_ANGLE_VALUE) {
+        /* If tan(theta) is bigger than our predefined value */
+        if (deltay > 0) {
+            ret = SCL_DRAG_STATE_DOWN;
+        } else {
+            ret = SCL_DRAG_STATE_UP;
+        }
+    } else {
+        ret = SCL_DRAG_STATE_INVALID;
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLController::mouse_move(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+
+    if (m_input_events_disabled) return FALSE;
+
+    //utils->log("Controller::mouse_move : %d %d\n", x, y);
+
+    /* Adjust x,y coordinate by touch offset */
+    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!sclres_manager) return FALSE;
+
+    PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
+    if (!sclres_modifier_decoration) return FALSE;
+
+    if (cache && state && windows && context && utils && adjustment && sclres_manager) {
+        const SclLayout *layout = cache->get_cur_layout(window);
+        if (layout) {
+            x += layout->mouse_manipulate_x;
+            y += layout->mouse_manipulate_y;
+        }
+
+        if (!(context->find_multi_touch_context(touch_id))) return FALSE;
+
+        PSclDefaultConfigure default_configure = sclres_manager->get_default_configure();
+        if (default_configure) {
+            SCLDisplayMode display_mode = context->get_display_mode();
+            adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
+        }
+
+        //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+        SclWindowContext *window_context = windows->get_window_context(window);
+        /* Adjust event x and y positions as relative position to the virtual window */
+        if (window_context) {
+            /*if (window_context->isVirtual) {
+                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                if (base_window_context) {
+                    x -= (window_context->x - base_window_context->x);
+                    y -= (window_context->y - base_window_context->y);
+                }
+            }*/
+            /* If the dim window is virtual and currently active, let's just skip this event */
+            if (windows->is_base_window(window)) {
+                SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
+                if (dim_window_context) {
+                    if (dim_window_context->is_virtual && !(dim_window_context->hidden)) {
+                        return FALSE;
+                    }
+                }
+            }
+            /* If the pressed event was occured in dim window, let's just skip this move event */
+            if (context->get_last_pressed_window() == windows->get_dim_window()) {
+                return FALSE;
+            }
+        }
+
+        sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+        scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+        SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
+        const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+        /* If the multitouch type is SETTLE_PREVIOUS and is not the last touch device, let's ignore move events */
+        if (coordinate) {
+            if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+                if (context->get_last_touch_device_id() != touch_id) {
+                    return FALSE;
+                }
+            }
+        }
+
+        context->set_cur_moving_point(touch_id, x, y);
+        context->set_cur_moving_window(touch_id, window);
+
+        /* If in longkey state, do not process, just return */
+        if (state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
+                state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY) {
+            return FALSE;
+        }
+        /* FIXME : The rule below would not be a general requirement. A policy is needed regarding this. */
+        /* And if the event occured in popup window, don't come back to base window */
+        if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
+            if (windows->is_base_window(window)) {
+                return FALSE;
+            }
+        }
+
+        SclUIEventDesc desc;
+        SCLShiftState shift_index = context->get_shift_state();
+        if (context->get_caps_lock_mode()) {
+            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+        }
+        if (coordinate) {
+            desc.key_type = coordinate->key_type;
+            desc.key_value = coordinate->key_value[shift_index][0];
+            desc.key_event = coordinate->key_event[shift_index][0];
+        }
+        desc.event_type = EVENT_TYPE_MOVE;
+        desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+        desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+        desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+        if (handler && handler->on_event_drag_state_changed(desc) != SCL_EVENT_PASS_ON) {
+            return FALSE;
+        }
+
+        /* FIXME : Add a condition to skip this code if longkey timer is not active */
+        /* If the mouse has moved out of threshold value of longkey keypress area, destroy longkey timer */
+        if (m_long_key_cancel_distance > 0) {
+            sclfloat dist = utils->get_distance(x, y,
+                context->get_cur_pressed_point(touch_id).x, context->get_cur_pressed_point(touch_id).y);
+            if (m_long_key_cancel_distance < dist) {
+                events->destroy_timer(SCL_TIMER_LONGKEY);
+            }
+        }
+
+        if (windows->is_base_window(window)) {
+            state->set_cur_action_state(ACTION_STATE_BASE_MOVING);
+        } else {
+            state->set_cur_action_state(ACTION_STATE_POPUP_MOVING);
+        }
+
+        /* Iterate all the buttons and inform the event */
+        sclboolean ended = FALSE;
+
+        /* Check farthest move point and update it */
+        sclint originx = x;
+        sclint originy = y;
+        if (pressed_window != window) {
+            //SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window, FALSE);
+            SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window);
+            if (window_context && pressed_window_context) {
+                originx = (window_context->geometry.x - pressed_window_context->geometry.x) + x;
+                originy = (window_context->geometry.y - pressed_window_context->geometry.y) + y;
+            }
+        }
+        sclint startx = originx;
+        sclint starty = originy;
+
+        /* Check if we should recognize drag curve */
+        if (coordinate) {
+            startx = context->get_cur_pressed_point(touch_id).x;
+            starty = context->get_cur_pressed_point(touch_id).y;
+            sclint deltax = originx - startx;
+            sclint deltay = originy - starty;
+            sclfloat approximate_dist = utils->get_approximate_distance(originx, originy, startx, starty);
+
+            sclboolean update_magnifier = FALSE;
+            sclboolean drag_state_changed = FALSE;
+            SCLDragState cur_drag_state = context->get_cur_drag_state(touch_id);
+            SCLDragState next_drag_state = SCL_DRAG_STATE_NONE;
+            sclfloat direction_recog_dist = SCL_DIRECTION_RECOG_DIST * utils->get_smallest_scale_rate();
+            if (coordinate->is_side_button) {
+                direction_recog_dist = SCL_DIRECTION_RECOG_DIST_SIDE * utils->get_smallest_scale_rate();
+            };
+
+            if (coordinate->button_type == BUTTON_TYPE_DIRECTION) {
+                /* Do not check farthest move point if current drag state is SCL_DRAG_STATE_RETURN */
+                if (context->get_cur_drag_state(touch_id) != SCL_DRAG_STATE_RETURN) {
+                    if (approximate_dist > context->get_farthest_move_dist(touch_id)) {
+                        context->set_farthest_move_point(touch_id, originx, originy);
+                    }
+                }
+
+                if (cur_drag_state == SCL_DRAG_STATE_RETURN) {
+                    direction_recog_dist *= SCL_DRAG_RETURN_RECOG_THRESHOLD_RETURN;
+                } else if (cur_drag_state != SCL_DRAG_STATE_NONE) {
+                    direction_recog_dist *= SCL_DRAG_RETURN_RECOG_THRESHOLD_OTHER;
+                }
+                if (approximate_dist > direction_recog_dist) {
+                    next_drag_state = get_drag_state(deltax, deltay);
+                    /* Disable longkey if dragging is recognized */
+                    events->destroy_timer(SCL_TIMER_LONGKEY);
+                }
+                if (cur_drag_state != next_drag_state) {
+                    drag_state_changed = TRUE;
+                }
+                if (cur_drag_state == SCL_DRAG_STATE_NONE) {
+                    //if (nextDragState != SCL_DRAG_STATE_INVALID) {
+                        cur_drag_state = next_drag_state;
+                    //}
+                } else if (cur_drag_state != next_drag_state) {
+                    if (next_drag_state == SCL_DRAG_STATE_NONE) {
+                        cur_drag_state = SCL_DRAG_STATE_RETURN;
+                    } else {
+                        cur_drag_state = next_drag_state;
+                    }
+                }
+
+                context->set_cur_drag_state(touch_id, cur_drag_state);
+                sclboolean check_farthest = FALSE;
+                sclshort display = context->get_display_mode();
+                if (!scl_check_arrindex(display, DISPLAYMODE_MAX)) display = 0;
+                sclfloat dist = utils->get_distance(originx, originy,
+                    context->get_cur_pressed_point(touch_id).x, context->get_cur_pressed_point(touch_id).y);
+                if (dist < direction_recog_dist && context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN) {
+                    if (coordinate->extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN ||
+                        coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN ||
+                        coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE) {
+                            deltax = context->get_farthest_move_point(touch_id).x -
+                                context->get_cur_pressed_point(touch_id).x;
+                            deltay = context->get_farthest_move_point(touch_id).y -
+                                context->get_cur_pressed_point(touch_id).y;
+                            dist = utils->get_distance(context->get_farthest_move_point(touch_id),
+                                context->get_cur_pressed_point(touch_id));
+                            check_farthest = TRUE;
+                    }
+                }
+                SCLKeyModifier key_modifier = get_drag_key_modifier(deltax, deltay, dist,
+                    check_farthest, touch_id, coordinate->extra_option);
+                if (dist > direction_recog_dist) {
+                    context->set_cur_key_modifier(touch_id, key_modifier);
+                }
+                /* If this button needs to be decorated when dragged */
+                if (coordinate->modifier_decorator) {
+                    const SclModifierDecoration *decoration = NULL;
+                    /* FIXME */
+                    /*if (scl_check_arrindex(coordinate->modifier_decorator,
+                        sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
+                    scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
+                    if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
+                        if (sclres_modifier_decoration[decoration_id].valid) {
+                            decoration = &(sclres_modifier_decoration[decoration_id]);
+                        }
+                    }
+                    /* Check if the button really needs to be redrawn (whether it has non-null bg_image_path information */
+                    if (decoration) {
+                        if (decoration->bg_image_path[display][key_modifier]) {
+                            windows->update_window(window,
+                                coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+                        }
+                    }
+                }
+                if (dist > direction_recog_dist) {
+                    if (context->get_magnifier_enabled()) {
+                        update_magnifier = TRUE;
+                    }
+                }
+            } else if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+                if (cur_drag_state != SCL_DRAG_STATE_NONE) {
+                    startx = context->get_prev_moving_point(touch_id).x;
+                    starty = context->get_prev_moving_point(touch_id).y;
+                    approximate_dist = utils->get_approximate_distance(originx, originy, startx, starty);
+                    direction_recog_dist = SCL_DIRECTION_RELATIVE_RECOG_DIST * utils->get_smallest_scale_rate();
+                }
+                deltax = originx - startx;
+                deltay = originy - starty;
+                //printf("DIST : %f, RECOG : %f\n", dist, direction_recog_dist);
+                if (approximate_dist > direction_recog_dist) {
+                    next_drag_state = get_drag_state(deltax, deltay);
+                    /* Disable longkey if dragging is recognized */
+                    events->destroy_timer(SCL_TIMER_LONGKEY);
+
+                    if (cur_drag_state != next_drag_state) {
+                        drag_state_changed = TRUE;
+                    }
+                    if (next_drag_state != SCL_DRAG_STATE_NONE) {
+                        cur_drag_state = next_drag_state;
+                    }
+                    context->set_cur_drag_state(touch_id, cur_drag_state);
+
+                    startx = context->get_farthest_move_point(touch_id).x;
+                    starty = context->get_farthest_move_point(touch_id).y;
+                    deltax = originx - startx;
+                    deltay = originy - starty;
+                    sclfloat dist_farthest = utils->get_approximate_distance(originx, originy, startx, starty);
+                    //printf("%d %d %d %d %f, %d %d\n", originx, originy, startx, starty, dist_farthest, cur_drag_state, next_drag_state);
+                    /* Let's see how much we are away from the last farthest point */
+                    sclfloat diffdir_recog_dist = SCL_DIRECTION_RELATIVE_DIFFDIR_RECOG_DIST * utils->get_smallest_scale_rate();
+                    /* If we moved certain amount from the point where direction changed, process drag state change routine */
+                    if (dist_farthest > diffdir_recog_dist || context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_NONE) {
+                        sclshort display = context->get_display_mode();
+                        SCLKeyModifier key_modifier = get_drag_key_modifier(deltax, deltay, dist_farthest,
+                            FALSE, touch_id, coordinate->extra_option);
+                        context->set_cur_key_modifier(touch_id, key_modifier);
+                        /* If this button needs to be decorated when dragged */
+                        if (coordinate->modifier_decorator) {
+                            const SclModifierDecoration  *decoration = NULL;
+                            /* FIXME */
+                            /*if (scl_check_arrindex(coordinate->modifier_decorator,
+                                sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
+                            scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
+                            if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
+                                if (sclres_modifier_decoration[decoration_id].valid) {
+                                    decoration = &(sclres_modifier_decoration[decoration_id]);
+                                }
+                            }
+                            /* Check if the button really needs to be redrawn (whether it has non-null bg_image_path information */
+                            if (decoration) {
+                                if (decoration->bg_image_path[display][key_modifier]) {
+                                    windows->update_window(window,
+                                        coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+                                }
+                            }
+                        }
+
+                        if (context->get_magnifier_enabled()) {
+                            update_magnifier = TRUE;
+                        }
+                    }
+                    context->set_prev_moving_point(touch_id, originx, originy);
+                }
+                if (drag_state_changed) {
+                    /* When the dragging direction changes, save the current position as farthest point for future comparison */
+                    context->set_farthest_move_point(touch_id, originx, originy);
+                    LOGD("SET_FARTHEST : %d %d %d", originx, originy, context->get_cur_drag_state(touch_id));
+                }
+            }
+
+            if (update_magnifier) {
+                PSclMagnifierWndConfigure magnifier_configure = NULL;
+                if (sclres_manager) {
+                    magnifier_configure = sclres_manager->get_magnifier_configure();
+                }
+
+                const SclLayout *base_layout = cache->get_cur_layout(windows->get_base_window());
+                if (base_layout && magnifier_configure) {
+                    SclPoint zoomwinpos = {0, 0};
+                    /* calculates x position to be set */
+                    zoomwinpos.x = (coordinate->x + (coordinate->width / 2)) -
+                        (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+                    /* calculates y position to be set */
+                    sclint scnWidth, scnHeight;
+                    utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+                    zoomwinpos.y =  coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
+                    if (window_context) {
+                        zoomwinpos.x += window_context->geometry.x;
+                        zoomwinpos.y += window_context->geometry.y;
+                    }
+                    if (zoomwinpos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+                        zoomwinpos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+                    }
+                    if (zoomwinpos.x > scnWidth +
+                        magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                        magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+                        zoomwinpos.x = scnWidth +
+                            magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                            magnifier_configure->width * utils->get_custom_scale_rate_x();
+                    }
+                    zoomwinpos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+
+                    zoomwinpos.x += coordinate->magnifier_offset_x;
+                    zoomwinpos.y += coordinate->magnifier_offset_y;
+                    windows->move_window(windows->get_magnifier_window(), zoomwinpos.x, zoomwinpos.y);
+                    windows->show_window(windows->get_magnifier_window(), 0);
+                }
+            }
+        }
+
+        sclboolean grab_event = FALSE;
+        if (layout) {
+            if (layout->style == LAYOUT_STYLE_POPUP_GRAB) {
+                grab_event = TRUE;
+            }
+            /* If the topmost window has the POPUP_GRAB style, find the nearest button to the mouse pointer */
+            if (grab_event && window_context) {
+                /* If the layout's addGrab* values are defined, process this event only if the event occured inside grab area */
+                sclboolean in_grab_area = TRUE;
+                if (layout->add_grab_left != NOT_USED && x < -(layout->add_grab_left)) {
+                    in_grab_area = FALSE;
+                }
+                if (layout->add_grab_right != NOT_USED && x >
+                    (window_context->geometry.width + layout->add_grab_right)) {
+                    in_grab_area = FALSE;
+                }
+                if (layout->add_grab_top != NOT_USED && y < -(layout->add_grab_top)) {
+                    in_grab_area = FALSE;
+                }
+                if (layout->add_grab_bottom != NOT_USED && y >
+                    (window_context->geometry.height + layout->add_grab_bottom)) {
+                    in_grab_area = FALSE;
+                }
+                if (in_grab_area) {
+                    float min_dist = (float)((unsigned int)(-1));
+                    int min_dist_index = NOT_USED;
+                    for (int loop = 0;loop < MAX_KEY && !ended && !ret;loop++) {
+                        button_context = cache->get_cur_button_context(window, loop);
+                        const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+                        if (button_context && cur_coordinate) {
+                            if (!(button_context->used)) {
+                                ended = TRUE;
+                            } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                                cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                                float dist = utils->get_approximate_distance(x, y,
+                                        cur_coordinate->x + (cur_coordinate->width / 2),
+                                        cur_coordinate->y + (cur_coordinate->height / 2));
+                                if (dist < min_dist) {
+                                    min_dist_index = loop;
+                                    min_dist = dist;
+                                }
+                            }
+                        }
+                    }
+                    /* When we found the nearest button, generate this event on the button */
+                    if (min_dist_index != NOT_USED) {
+                        const SclLayoutKeyCoordinate *min_coordinate =
+                            cache->get_cur_layout_key_coordinate(window, min_dist_index);
+                        if (min_coordinate) {
+                            x = min_coordinate->x + (min_coordinate->width / 2);
+                            y = min_coordinate->y + (min_coordinate->height / 2);
+                            if (process_button_move_event(window, x, y, min_dist_index, touch_id, actual_event)) {
+                                ret = TRUE;
+                            }
+                        }
+                    }
+                }
+            } else {
+                MultiTouchContext *multi_touch_context = context->find_multi_touch_context(touch_id);
+                if (multi_touch_context) {
+                    sclint button_index = NOT_USED;
+                    if (!(multi_touch_context->is_sub_event)) {
+                        sclboolean process_finished = FALSE;
+                        do {
+                            /* First check if the event occured in pressed key's threshold area */
+                            if (button_context && coordinate) {
+                                if (pressed_window == window) { // Check only when the window is the one initally pressed
+                                    if (button_context->used && button_context->state != BUTTON_STATE_DISABLED) {
+                                        if (process_button_move_event(pressed_window, x, y, pressed_key, touch_id, actual_event)) {
+                                            ret = TRUE;
+                                            x = coordinate->x + (coordinate->width / 2);
+                                            y = coordinate->y + (coordinate->height / 2);
+                                            button_index = pressed_key;
+                                        }
+                                    }
+                                }
+                            }
+                            for (int loop = 0;loop < MAX_KEY && !ended && !ret;loop++) {
+                                button_context = cache->get_cur_button_context(window, loop);
+                                const SclLayoutKeyCoordinate *cur_coordinate =
+                                    cache->get_cur_layout_key_coordinate(window, loop);
+                                if (button_context && cur_coordinate) {
+                                    if (!(button_context->used)) {
+                                        ended = TRUE;
+                                    } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                                                cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                                        if (window != pressed_window || loop != pressed_key) {
+                                            if (process_button_move_event(window, x, y, loop, touch_id, actual_event)) {
+                                                ret = TRUE;
+                                                button_index = loop;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+
+                            if (windows->is_base_window(window)) {
+                                process_finished = TRUE;
+                            } else if (button_index != NOT_USED) {
+                                process_finished = TRUE;
+                            } else {
+                                const SclLayout *cur_layout = cache->get_cur_layout(window);
+                                if (cur_layout && cur_layout->use_sw_background && cur_layout->bg_color.a == 0) {
+                                    /* If we could not find appropriate button in this popup window and the popup is transparent */
+                                    SclWindowContext *base_window_context =
+                                        windows->get_window_context(windows->get_base_window());
+                                    if (base_window_context && window_context) {
+                                        x = (window_context->geometry.x + x - base_window_context->geometry.x);
+                                        y = (window_context->geometry.y + y - base_window_context->geometry.y);
+                                    }
+                                    window = windows->get_base_window();
+                                } else {
+                                    process_finished = TRUE;
+                                }
+                            }
+                        } while (!process_finished);
+                    }
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLController::mouse_over(sclwindow window, sclint x, sclint y)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+
+    if (m_input_events_disabled)
+        return FALSE;
+
+    /* Adjust x,y coordinate by touch offset */
+    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+    /* Iterate all the buttons and inform the event */
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (cache && state && windows && context && utils && adjustment && sclres_manager) {
+        const SclLayout *layout = cache->get_cur_layout(window);
+        if (layout) {
+            x += layout->mouse_manipulate_x;
+            y += layout->mouse_manipulate_y;
+        }
+
+        SCLDisplayMode cur_display_mode = context->get_display_mode();
+
+        const SclDefaultConfigure *default_configure = sclres_manager->get_default_configure();
+        if (default_configure) {
+            adjustment->apply_touch_offset(default_configure->touch_offset_level[cur_display_mode], &x, &y);
+        }
+
+        /* Iterate all the buttons and inform the event */
+        sclboolean ended = FALSE;
+
+        for (int loop = 0; loop < MAX_KEY && !ended && !ret; loop++) {
+            SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
+            const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+            if (button_context && coordinate) {
+                if (!(button_context->used)) {
+                    ended = TRUE;
+                } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                            coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                    if (process_button_over_event(window, x, y, loop)) {
+                        ret = TRUE;
+                    }
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+
+/**
+ * Processes a timer event
+ * If return FALSE, the current timer will be stop
+ * ID : SCL_LOWORD(data)
+ * value : SCL_HIWORD(data)
+ */
+sclboolean
+CSCLController::timer_event(const scl32 data)
+{
+    SCL_DEBUG();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLEvents* events = CSCLEvents::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+
+    scl16 id = SCL_LOWORD(data); /* Timer ID */
+    scl16 value = SCL_HIWORD(data); /* event unique ID */
+
+    if (!windows || !context || !events || !state || !cache || !handler)
+        return FALSE;
+
+    switch (id) {
+    case SCL_TIMER_AUTOPOPUP: {
+        /* Checks whether my event id is availble */
+        if (context->get_cur_pressed_event_id(context->get_last_touch_device_id()) != value ||
+                state->get_cur_action_state() == ACTION_STATE_BASE_INIT ||
+                //state->get_cur_action_state() == ACTION_STATE_BASE_MOVING ||
+                state->get_cur_action_state() == ACTION_STATE_BASE_RELEASE ||
+                state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
+                state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
+                //state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY
+           ) {
+            /* Ignores if the event id is different */
+            events->destroy_timer(id);
+            return FALSE;
+        }
+
+        SclRectangle rect = {0, 0, 0, 0};
+        sclwindow window = context->get_cur_pressed_window(context->get_last_touch_device_id());
+        sclbyte key_index = context->get_cur_pressed_key(context->get_last_touch_device_id());
+
+        if (configure_autopopup_window(window, key_index, &rect)) {
+            /* Let's change out pressed button's state back to normal */
+            SclButtonContext *button_context = cache->get_cur_button_context(window, key_index);
+            const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+
+            if (button_context) {
+                if (button_context->state == BUTTON_STATE_PRESSED) {
+                    button_context->state = BUTTON_STATE_NORMAL;
+                    if (coordinate) {
+                        windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+                    }
+                }
+            }
+            /* Hide magnifier window when opening autopopup window */
+            windows->hide_window(windows->get_magnifier_window());
+
+            sclwindow popup_window = SCLWINDOW_INVALID;
+
+            SclNotiPopupOpeningDesc desc;
+            desc.ui_event_desc = NULL;
+            desc.input_mode = SCL_LAYOUT_AUTOPOPUP_NAME;
+            if (SCL_EVENT_PASS_ON ==
+                handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
+                    /* Currently, window does not support virtual window */
+                    SclWindowOpener opener;
+                    opener.window = window;
+                    opener.key = key_index;
+
+                    popup_window = windows->open_popup(
+                        opener,
+                        rect,
+                        NOT_USED,
+                        SCL_LAYOUT_AUTOPOPUP, POPUP_TYPE_AUTO_POPUP,
+                        FALSE,
+                        FALSE);
+
+                    SclNotiPopupOpenedDesc opened_desc;
+                    opened_desc.ui_event_desc = NULL;
+                    opened_desc.input_mode = desc.input_mode;
+                    opened_desc.window = popup_window;
+                    handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
+            }
+
+            windows->hide_window(windows->get_magnifier_window());
+            _play_tts_for_layout_autopopup_name();
+
+            sclwindow moving_window = context->get_cur_moving_window(context->get_last_touch_device_id());
+            SclPoint moving_point = context->get_cur_moving_point(context->get_last_touch_device_id());
+            SclWindowContext *moving_window_context = windows->get_window_context(moving_window);
+            SclWindowContext *popup_window_context = windows->get_window_context(popup_window);
+            if (moving_window_context && popup_window_context) {
+                moving_point.x = (moving_window_context->geometry.x - popup_window_context->geometry.x) + moving_point.x;
+                moving_point.y = (moving_window_context->geometry.y - popup_window_context->geometry.y) + moving_point.y;
+            }
+            //printf("AUTOPOPUP : %d %d\n", moving_point.x, moving_point.y);
+
+            if (coordinate) {
+                windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+            }
+        }
+        events->destroy_timer(id);
+
+        return FALSE;
+    }
+    break;
+
+    case SCL_TIMER_LONGKEY: {
+        /* Checks whether my event id is availble */
+        if (context->get_cur_pressed_event_id(context->get_last_touch_device_id()) != value ||
+                state->get_cur_action_state() == ACTION_STATE_BASE_INIT ||
+                //state->get_cur_action_state() == ACTION_STATE_BASE_MOVING ||
+                state->get_cur_action_state() == ACTION_STATE_BASE_RELEASE ||
+                state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
+                state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
+                //state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY
+           ) {
+            /* Ignores if the event id is different */
+            events->destroy_timer(id);
+            return FALSE;
+        }
+        /* Ignores if the event id is different */
+        sclwindow window = context->get_cur_pressed_window(context->get_last_touch_device_id());
+        sclbyte key_index = context->get_cur_pressed_key(context->get_last_touch_device_id());
+        if (process_button_long_pressed_event(window, key_index, context->get_last_touch_device_id())) {
+            /* The button processed long key event, now enter longkey mode not to fire any events before releasing */
+            handle_engine_signal(SCL_SIG_MOUSE_LONG_PRESS, window);
+            windows->update_window(windows->get_magnifier_window());
+/*
+            SclButtonContext *button_context = cache->get_cur_button_context(window, key_index);
+            if (button_context->state == BUTTON_STATE_PRESSED) {
+                button_context->state = BUTTON_STATE_NORMAL;
+                CSCLWindows *windows = CSCLWindows::get_instance();
+                if (windows) {
+                    const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+                    windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+                }
+            }
+            context->set_cur_pressed_window(context->get_last_touch_device_id(), SCLWINDOW_INVALID);
+            context->set_cur_pressed_key(context->get_last_touch_device_id(), NOT_USED);
+*/
+        } else {
+            /* Start the repeat key timer for NORMAL or GRAB buttons if longkey is not supported */
+            const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+
+            if (coordinate) {
+                /* This is for enabling backspace key in search layout*/
+                //if (coordinate->use_repeat_key) {
+                if (coordinate->use_repeat_key
+                        || coordinate->key_event[0][0] == MVK_BackSpace) {
+                    if (coordinate->button_type == BUTTON_TYPE_NORMAL ||
+                            coordinate->button_type == BUTTON_TYPE_GRAB ||
+                            coordinate->button_type == BUTTON_TYPE_SELFISH ||
+                            coordinate->button_type == BUTTON_TYPE_DIRECTION ||
+                            coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+                        m_key_repeated_num = 0;
+                        events->create_timer(SCL_TIMER_REPEATKEY, m_repeat_key_duration, value);
+                        if (windows->is_base_window(window)) {
+                            state->set_cur_action_state(ACTION_STATE_BASE_REPEATKEY);
+                        } else {
+                            state->set_cur_action_state(ACTION_STATE_POPUP_REPEATKEY);
+                        }
+                    }
+                }
+            }
+        }
+        events->destroy_timer(id);
+        return FALSE;
+    }
+    break;
+
+    case SCL_TIMER_REPEATKEY: {
+        /* Checks whether my event id is availble */
+        if (context->get_cur_pressed_event_id(context->get_last_touch_device_id()) != value ||
+                (state->get_cur_action_state() != ACTION_STATE_BASE_REPEATKEY &&
+                 state->get_cur_action_state() != ACTION_STATE_POPUP_REPEATKEY)
+           ) {
+            /* Ignores if the event id is different */
+            events->destroy_timer(id);
+            return FALSE;
+        }
+        sclwindow window = context->get_cur_pressed_window(context->get_last_touch_device_id());
+        sclbyte key_index = context->get_cur_pressed_key(context->get_last_touch_device_id());
+        scllong interval = m_repeat_key_duration - (m_key_repeated_num * SCL_REPEATKEY_ACCELERATION);
+        if (interval < SCL_REPEATKEY_MIN_DURATION) {
+            interval = SCL_REPEATKEY_MIN_DURATION;
+        }
+        process_button_repeat_pressed_event(window, key_index, context->get_last_touch_device_id());
+        events->destroy_timer(id);
+        events->create_timer(SCL_TIMER_REPEATKEY, interval, value);
+        m_key_repeated_num++;
+        return FALSE;
+    }
+    break;
+    case SCL_TIMER_BUTTON_DELAY: {
+        /* If there is postponed update of button, update it now */
+        sclwindow last_window = context->get_last_pressed_window();
+        scl8 last_key = context->get_last_pressed_key();
+
+        if (last_window != SCLWINDOW_INVALID && last_key != NOT_USED) {
+            const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(last_window, last_key);
+            if (coords) {
+                windows->update_window(last_window, coords->x, coords->y, coords->width, coords->height);
+            }
+        }
+
+        windows->hide_window(windows->get_magnifier_window());
+        context->set_last_pressed_window(SCLWINDOW_INVALID);
+        context->set_last_pressed_key(NOT_USED);
+        events->destroy_timer(id);
+        return FALSE;
+    }
+    break;
+    case SCL_TIMER_POPUP_TIMEOUT: {
+        windows->close_all_popups(SCLWINDOW_INVALID, TRUE);
+        events->destroy_timer(id);
+
+        return FALSE;
+    }
+    break;
+    case SCL_TIMER_MULTITAP: {
+        SclUIEventDesc key_event_desc;
+        key_event_desc.event_type = EVENT_TYPE_RELEASE;
+        key_event_desc.key_modifier = KEY_MODIFIER_MULTITAP_RELEASE;
+        handler->on_event_key_clicked(key_event_desc);
+
+        events->destroy_timer(id);
+
+        /* We have to reset multitap button state when MULTITAP timer expired */
+        sclboolean ended = FALSE;
+        sclwindow window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+        for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+            SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
+            if (button_context) {
+                if (!(button_context->used)) {
+                    ended = TRUE;
+                } else {
+                    const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+                    if (coordinate && coordinate->button_type == BUTTON_TYPE_MULTITAP) {
+                        button_context->multitap_index = 0;
+                    }
+                }
+            }
+        }
+
+        return FALSE;
+    }
+    break;
+    case SCL_TIMER_AUTOTEST: {
+        srand(time(NULL));
+
+        unsigned int seed = 0;
+        sclint rnd = rand_r(&seed) % 100;
+
+        const SclLayout *layout = cache->get_cur_layout(windows->get_base_window());
+
+        if (layout == NULL) {
+            return FALSE;
+        }
+        srand(time(NULL));
+        sclint x = (rand_r(&seed) % (layout->width));
+
+        srand(time(NULL));
+        sclint y = (rand_r(&seed) % (layout->height));
+
+        if (rnd < 80) {
+            events->generate_mouse_event(SCL_MOUSE_EVENT_PRESS, x, y);
+            events->generate_mouse_event(SCL_MOUSE_EVENT_RELEASE, x, y);
+        } else if (rnd < 90) {
+            events->generate_mouse_event(SCL_MOUSE_EVENT_MOVE, x, y);
+        } else if (rnd < 95) {
+            events->generate_mouse_event(SCL_MOUSE_EVENT_PRESS, x, y);
+        } else {
+            events->generate_mouse_event(SCL_MOUSE_EVENT_RELEASE, x, y);
+        }
+
+        m_debug_variable++;
+        if (m_debug_variable < SCL_AUTOTEST_NUM) events->create_timer(SCL_TIMER_AUTOTEST, SCL_AUTOTEST_TIMER_INTERVAL, 0, FALSE);
+        else m_debug_mode = DEBUGMODE_DISABLED;
+        return FALSE;
+    }
+    break;
+    case SCL_TIMER_ANIMATION: {
+        CSCLAnimator *animator = CSCLAnimator::get_instance();
+        if (animator) {
+            return animator->animator_timer();
+        }
+        return TRUE;
+    }
+
+    default: {
+        events->destroy_timer(id);
+    }
+    break;
+    }
+
+    return TRUE;
+}
+
+/* Handles signals to manage contexts mainly focusing on resetting variables and cleaning up states */
+void CSCLController::handle_engine_signal(SclInternalSignal signal, sclwindow targetWindow )
+{
+    SCL_DEBUG();
+
+    enum SIGACTIONS {
+        SIGACTION_RESIZE_RESOURCES,
+        SIGACTION_DESTROY_TIMERS,
+        SIGACTION_CLEAR_PRIVATEKEYS,
+        SIGACTION_RECOMPUTE_LAYOUT,
+        SIGACTION_FREE_IMAGES,
+        SIGACTION_CLOSE_POPUP,
+        SIGACTION_CLOSE_MAGNIFIER,
+        SIGACTION_UNSET_SHIFT,
+        SIGACTION_UNPRESS_KEYS,
+        SIGACTION_INIT_DISPLAY,
+        SIGACTION_INIT_INPUTMODE,
+
+        SIGACTION_MAXNUM
+    };
+    const sclboolean SIGNAL_TABLE[SIGACTION_MAXNUM][SCL_SIG_MAXNUM] = {
+        //     START,  SHOW,   HIDE,   INPCHNG,        DISPCHNG,       POPUPSHOW,      POPUPHIDE,      MOUSEPRES,      M-LONGPRES,     MOUSEREL,       KEYEVT, FOCUSCHNG
+        // SIGACTION_RESIZE_RESOURCES
+        {      TRUE,   0,              0,              0,                      0,                      0,                      0,                      0,                      0,                      0,                      0,              0               },
+        // SIGACTION_DESTROY_TIMERS
+        {      TRUE,   TRUE,   TRUE,   TRUE,           TRUE,           0,                      0,                      0,                      0,                      0,                      0,              TRUE    },
+        // SIGACTION_CLEAR_PRIVATEKEYS
+        {      TRUE,   0,              0,              0,                      0,                      0,                      0,                      0,                      0,                      0,                      0,              TRUE    },
+        // SIGACTION_RECOMPUTE_LAYOUT
+        {      0,              TRUE,   0,              TRUE,           TRUE,           TRUE,           0,                      0,                      0,                      0,                      0,              TRUE    },
+        // SIGACTION_FREE_IMAGES
+        {      TRUE,   0,              TRUE,   TRUE,           TRUE,           0,                      0,                      0,                      0,                      0,                      0,              0               },
+        // SIGACTION_CLOSE_POPUP
+        {      TRUE,   TRUE,   TRUE,   TRUE,           TRUE,           0,                      0,                      0,                      0,                      0,                      0,              TRUE    },
+        // SIGACTION_CLOSE_MAGNIFIER
+        {      TRUE,   TRUE,   TRUE,   TRUE,           TRUE,           0,                      0,                      0,                      0,                      0,                      0,              TRUE    },
+        // SIGACTION_UNSET_SHIFT
+        {      TRUE,   0       ,       0       ,       TRUE,           0,                      0,                      0,                      0,                      0,                      0,                      0,              TRUE    },
+        // SIGACTION_UNPRESS_KEYS
+        {      TRUE,   TRUE,   TRUE,   TRUE,           TRUE,           0,                      0,                      0,                      0,                      0,                      0,              TRUE    },
+        // SIGACTION_INIT_DISPLAY
+        {      TRUE,   0,              0,              0,                      0,                      0,                      0,                      0,                      0,                      0,                      0,              0               },
+        // SIGACTION_INIT_INPUTMODE
+        {      TRUE,   0,              0,              0,                      0,                      0,                      0,                      0,                      0,                      0,                      0,              TRUE    },
+    };
+
+    scl_assert_return(signal >= 0 && signal < SCL_SIG_MAXNUM);
+
+    CSCLEvents* events = CSCLEvents::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLImageProxy *proxy = CSCLImageProxy::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    if (!events || !windows || !context || !proxy || !cache) return;
+
+    switch (signal) {
+        case SCL_SIG_SHOW:
+            {
+                if (context)
+                    context->set_hidden_state(FALSE);
+            }
+            break;
+        case SCL_SIG_HIDE:
+            {
+                if (context)
+                    context->set_hidden_state(TRUE);
+
+                if (windows)
+                    windows->close_all_popups();
+            }
+            break;
+        case SCL_SIG_START:
+        case SCL_SIG_INPMODE_CHANGE:
+        case SCL_SIG_DISP_CHANGE:
+        case SCL_SIG_POPUP_SHOW:
+        case SCL_SIG_POPUP_HIDE:
+        case SCL_SIG_MOUSE_PRESS:
+        case SCL_SIG_MOUSE_LONG_PRESS:
+        case SCL_SIG_MOUSE_RELEASE:
+        case SCL_SIG_KEYEVENT:
+        default:
+            break;
+    }
+
+    int loop = 0;
+    for (loop = 0;loop < SIGACTION_MAXNUM;loop++) {
+        if (SIGNAL_TABLE[loop][signal] == TRUE) {
+            switch (loop) {
+            case SIGACTION_DESTROY_TIMERS:
+                events->destroy_all_timer();
+                break;
+            case SIGACTION_RECOMPUTE_LAYOUT: {
+                if (targetWindow != SCLWINDOW_INVALID) {
+                    if (cache)
+                        cache->recompute_layout(targetWindow);
+
+                    // EFL testing
+                    windows->update_window(targetWindow);
+                }
+            }
+            break;
+            case SIGACTION_FREE_IMAGES:
+                proxy->free_images();
+                break;
+            case SIGACTION_CLOSE_POPUP: {
+                /* If there is a popup still opened, don't destroy POPUP_TIMEOUT timer */
+                if (!(windows->close_all_popups(targetWindow))) {
+                    events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+                }
+            }
+            break;
+            case SIGACTION_CLOSE_MAGNIFIER: {
+                if (signal == SCL_SIG_HIDE) {
+                    windows->hide_window(windows->get_magnifier_window(), TRUE);
+                } else {
+                    windows->hide_window(windows->get_magnifier_window());
+                }
+            }
+            //events->create_timer(SCL_TIMER_BUTTON_DELAY, SCL_BUTTON_MIN_DURATION, 0);
+            break;
+            case SIGACTION_UNSET_SHIFT: {
+                CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+                if (handler) {
+                    SclNotiShiftStateChangeDesc desc;
+                    desc.ui_event_desc = NULL;
+                    desc.shift_state = SCL_SHIFT_STATE_OFF;
+
+                    if (SCL_EVENT_PASS_ON ==
+                        handler->on_event_notification(SCL_UINOTITYPE_SHIFT_STATE_CHANGE, &desc)) {
+                        if (context)
+                            context->set_shift_state(SCL_SHIFT_STATE_OFF);
+                    }
+                }
+            }
+            break;
+            case SIGACTION_UNPRESS_KEYS:
+                if (context) {
+                    context->set_cur_pressed_key(context->get_last_touch_device_id(), NOT_USED);
+                    context->set_cur_pressed_window(context->get_last_touch_device_id(), SCLWINDOW_INVALID);
+                }
+            break;
+            default:
+            break;
+            }
+        }
+    }
+}
+
+/**
+ * Sets the duration value for longkey
+ * If not set, it will use default longkey duration. see sclconfig
+ */
+sclboolean
+CSCLController::set_longkey_duration(scllong msc)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+    if (msc > 0) {
+        m_long_key_duration = msc;
+        ret = TRUE;
+    }
+    return ret;
+}
+
+/**
+* Sets the distance value for cancel longkey
+* If not set, it will use default longkey duration. see sclconfig
+*/
+sclboolean
+CSCLController::set_longkey_cancel_dist(sclshort dist)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+    if (dist > 0) {
+        m_long_key_cancel_distance = dist;
+        ret = TRUE;
+    }
+    return ret;
+}
+
+/**
+* Sets the duration value for repeatkey
+* If not set, it will use default repeatkey duration. see sclconfig
+*/
+sclboolean
+CSCLController::set_repeatkey_duration(scllong msc)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+    if (msc > 0) {
+        m_repeat_key_duration = msc;
+        ret = TRUE;
+    }
+    return ret;
+}
+
+/**
+ * Sets the duration value for autopopup key
+ * If not set, it will use default short longkey duration. see sclconfig
+ */
+sclboolean
+CSCLController::set_autopopup_key_duration(scllong msc)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+    if (msc > 0) {
+        m_autopopup_key_duration = msc;
+        ret = TRUE;
+    }
+    return ret;
+}
+
+/**
+ * Sets the amount value for button delay
+ * If not set, it will use default button delay amount. see sclconfig
+ */
+sclboolean
+CSCLController::set_button_delay_duration(scllong msc)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+    if (msc > 0) {
+        m_button_delay_duration = msc;
+        ret = TRUE;
+    }
+    return ret;
+}
+
+/**
+ * Configures the variables for auto-popup window
+ * It will return rectangle area
+ * @return FALSE It's not available popup key
+ */
+sclboolean
+CSCLController::configure_autopopup_window(sclwindow window, sclbyte key_index, SclRectangle* rect)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(window);
+    scl_assert_return_false(key_index >= 0);
+
+    sclboolean ret = TRUE;
+
+    sclbyte num_keys, num_columns, num_rows;
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+
+    if (cache) {
+        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+    }
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    PSclAutoPopupConfigure autopopup_configure = NULL;
+    if (sclres_manager) {
+        autopopup_configure = sclres_manager->get_autopopup_configure();
+    }
+
+    if (utils && context && windows && cache && coordinate && rect && autopopup_configure) {
+        SCLShiftState shift_index = context->get_shift_state();
+        if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+        if (context->get_caps_lock_mode()) {
+            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+        }
+
+        if (utils->get_autopopup_window_variables(coordinate->autopopup_key_labels[shift_index],
+                &num_keys, &num_columns, &num_rows, &rect->width, &rect->height)) {
+            /* There is no need for an autopopup window if number of keys are equal to or less than 0 */
+            if (!(num_keys > 0)) {
+                ret = FALSE;
+            }
+            /* calculates y position to be set */
+            SclRectangle baseWndRect;
+            int scrwidth, scrheight;
+            utils->get_screen_resolution(&scrwidth, &scrheight);
+
+            windows->get_window_rect(windows->get_base_window(), &baseWndRect);
+            /* Let the autopopup have its position right above the pressed button, with center alignment) */
+            rect->x = baseWndRect.x + coordinate->x + (coordinate->width / 2) - (rect->width / 2);
+            rect->y = baseWndRect.y + coordinate->y - rect->height +
+                autopopup_configure->decoration_size * utils->get_smallest_custom_scale_rate();
+            /* First check the growing direction of this autopopup window */
+            if (coordinate->x < baseWndRect.width / 2) {
+                /* We're growing left to right, calculate the left start point */
+                rect->x = baseWndRect.x + coordinate->x + (coordinate->width / 2) -
+                    (autopopup_configure->button_width * utils->get_custom_scale_rate_x() / 2) -
+                    autopopup_configure->bg_padding * utils->get_smallest_custom_scale_rate();
+                if (rect->x + rect->width > baseWndRect.x + baseWndRect.width) {
+                    sclint relocate_unit = autopopup_configure->button_width * utils->get_custom_scale_rate_x() +
+                        autopopup_configure->button_spacing * utils->get_smallest_custom_scale_rate();
+                    rect->x -= (((rect->x + rect->width - (baseWndRect.x + baseWndRect.width)) /
+                            relocate_unit) + 1) * relocate_unit;
+                }
+            } else {
+                /* We're growing right to left, calculate the right end point */
+                rect->x = baseWndRect.x + coordinate->x + (coordinate->width / 2) +
+                    (autopopup_configure->button_width * utils->get_custom_scale_rate_x() / 2) +
+                    autopopup_configure->bg_padding * utils->get_smallest_custom_scale_rate();
+                rect->x -= rect->width;
+                if (rect->x < baseWndRect.x) {
+                    sclint relocate_unit = autopopup_configure->button_width * utils->get_custom_scale_rate_x() +
+                        autopopup_configure->button_spacing * utils->get_smallest_custom_scale_rate();
+                    rect->x += (((baseWndRect.x - rect->x) /
+                            relocate_unit) + 1) * relocate_unit;
+                }
+            }
+            //rect->y = (scrheight - layout->height) + coordinate->y - rect->height + autopopup_configure->decoration_size;
+            /* Check if the window goes out of screen boundary */
+            //if (rect->x + rect->width > scrwidth + utils->get_scale_x(scl_autopopup_configure.decoration_size)) rect->x = (scrwidth + utils->get_scale_x(scl_autopopup_configure.decoration_size)) - rect->width;
+            if (rect->x + rect->width > scrwidth) rect->x = (scrwidth) - rect->width;
+            if (rect->y + rect->height > scrheight) rect->y = scrheight - rect->height;
+            if (rect->x < 0 - autopopup_configure->decoration_size * utils->get_smallest_custom_scale_rate())
+                rect->x = 0 - autopopup_configure->decoration_size * utils->get_smallest_custom_scale_rate();
+            // restrict to 0
+            if (rect->x < 0) rect->x = 0;
+            if (rect->y < 0) rect->y = 0;
+        } else {
+            ret = FALSE;
+        }
+    }
+    return ret;
+}
+
+/**
+ * If the mouse was pressed on the button A and moved to B without releasing,
+ * this function decides whether we should allow event transition, meaning
+ * button A gets restored to its initial state and B gets pressed instead.
+ */
+sclboolean
+CSCLController::check_event_transition_enabled(const SclLayoutKeyCoordinate *btn_from, const SclLayoutKeyCoordinate *btn_to)
+{
+    sclboolean ret = FALSE;
+    sclbyte type_from = BUTTON_TYPE_NORMAL; /* To enable event transition even if no button is pressed currently */
+    sclbyte type_to = MAX_BUTTON_TYPE;
+
+    const sclboolean TRANSITION_TABLE[MAX_BUTTON_TYPE][MAX_BUTTON_TYPE] = {
+        //     NORMAL  GRAB    SELFISH DRAG    MULTITAP        ROTATION        DIRECTION       R_DIRECTION     TOGGLE  UIITEM
+        //     From : NORMAL
+        {      TRUE,   0,      0,              TRUE,   TRUE,           TRUE,           0,                      0,                      TRUE,           0},
+        //     From : GRAB
+        {      0,              0,      0,              0,              0,                      0,                      0,                      0,                      0,                      0},
+        //     From : SELFISH
+        {      0,              0,      0,              0,              0,                      0,                      0,                      0,                      0,                      0},
+        //     From : DRAG
+        {      TRUE,   0,      0,              TRUE,   TRUE,           TRUE,           0,                      0,                      TRUE,           0},
+        //     From : MULTITAP
+        {      TRUE,   0,      0,              TRUE,   TRUE,           TRUE,           0,                      0,                      TRUE,           0},
+        //     From : ROTATION
+        {      TRUE,   0,      0,              TRUE,   TRUE,           TRUE,           0,                      0,                      TRUE,           0},
+        //     From : DIRECTION
+        {      0,              0,      0,              0,              0,                      0,                      0,                      0,                      0,                      0},
+        //     From : R_DIRECTION
+        {      0,              0,      0,              0,              0,                      0,                      0,                      0,                      0,                      0},
+        //     From : UIITEM
+        {      0,              0,      0,              0,              0,                      0,                      0,                      0,                      0,                      0},
+        //     From : TOGGLE
+        {      TRUE,   0,      0,              TRUE,   TRUE,           TRUE,           0,                      0,                      TRUE,           0},
+    };
+
+    if (btn_from) type_from = btn_from->button_type;
+    if (btn_to) type_to = btn_to->button_type;
+
+    scl_assert_return_false(type_from >= 0 && type_from < MAX_BUTTON_TYPE);
+    scl_assert_return_false(type_to >= 0 && type_to < MAX_BUTTON_TYPE);
+
+    if (type_from < MAX_BUTTON_TYPE && type_to < MAX_BUTTON_TYPE) {
+        ret = TRANSITION_TABLE[type_from][type_to];
+    }
+
+    return ret;
+}
+
+SCLDebugMode
+CSCLController::get_debug_mode()
+{
+#ifdef SCL_DEBUG_ON
+    return m_debug_mode;
+#else
+    return m_debug_mode;
+    return DEBUGMODE_DISABLED;
+#endif
+}
+
+void
+CSCLController::set_debug_mode(SCLDebugMode mode)
+{
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    m_debug_mode = mode;
+    m_debug_variable = 0;
+
+    if (m_debug_mode == DEBUGMODE_AUTOTEST) {
+        srand(time(NULL));
+        if (events && utils) {
+            events->create_timer(SCL_TIMER_AUTOTEST, SCL_AUTOTEST_TIMER_INITIAL_INTERVAL, 0, FALSE);
+            utils->log("mode : %d\n", mode);
+        }
+    }
+}
+
+void
+CSCLController::disable_input_events(sclboolean disabled)
+{
+    m_input_events_disabled = disabled;
+}
diff --git a/scl/sclcontroller.h b/scl/sclcontroller.h
new file mode 100644 (file)
index 0000000..cbb2eba
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012 - 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 "sclgwes.h"
+#include "sclutils.h"
+#include "sclcontext.h"
+
+#ifndef __SCL_CONTROLLER_H__
+#define __SCL_CONTROLLER_H__
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+enum SclInternalSignal {
+    SCL_SIG_START,
+    SCL_SIG_SHOW,
+    SCL_SIG_HIDE,
+    SCL_SIG_INPMODE_CHANGE,
+    SCL_SIG_DISP_CHANGE,
+    SCL_SIG_POPUP_SHOW,
+    SCL_SIG_POPUP_HIDE,
+    SCL_SIG_MOUSE_PRESS,
+    SCL_SIG_MOUSE_LONG_PRESS,
+    SCL_SIG_MOUSE_RELEASE,
+    SCL_SIG_KEYEVENT,
+    SCL_SIG_FOCUS_CHANGE,
+
+    SCL_SIG_MAXNUM
+};
+
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class EXAPI CSCLController
+{
+private:
+    CSCLController();
+public:
+    virtual ~CSCLController();
+
+    static CSCLController* get_instance();
+    void init();
+
+private:
+    sclboolean process_button_pressed_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+        scltouchdevice touch_id, sclboolean actual_event = TRUE);
+    sclboolean process_button_long_pressed_event(sclwindow window, sclbyte key_index,
+        scltouchdevice touch_id, sclboolean actual_event = TRUE);
+    sclboolean process_button_repeat_pressed_event(sclwindow window, sclbyte key_index,
+        scltouchdevice touch_id, sclboolean actual_event = TRUE);
+    sclboolean process_button_move_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+        scltouchdevice touch_id, sclboolean actual_event = TRUE);
+    sclboolean process_button_over_event(sclwindow window, sclint x, sclint y, sclbyte key_index);
+    sclboolean process_button_release_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+        scltouchdevice touch_id, sclboolean actual_event = TRUE);
+
+    sclboolean configure_autopopup_window(sclwindow window, sclbyte key_index, SclRectangle* rect);
+
+    sclboolean check_event_transition_enabled(const SclLayoutKeyCoordinate *btnFrom, const SclLayoutKeyCoordinate *btnTo);
+    sclboolean check_magnifier_available(sclwindow window, sclbyte key_index, scltouchdevice touch_id);
+
+    SCLKeyModifier get_drag_key_modifier(sclint deltax, sclint deltay, sclfloat dist,
+        sclboolean check_farthest, scltouchdevice touch_id, sclbyte extra_option);
+
+public:
+    void handle_engine_signal(SclInternalSignal signal, sclwindow skip_window = SCLWINDOW_INVALID);
+    sclboolean process_input_mode_change(const sclbyte mode);
+    sclboolean process_rotation_change(const SCLRotation rotation);
+
+    sclboolean mouse_press(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
+    sclboolean mouse_release(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
+    sclboolean mouse_move(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
+    sclboolean mouse_over(sclwindow window, sclint x, sclint y);
+    sclboolean timer_event(const scl32 id);
+
+    sclboolean set_longkey_duration(scllong msc);
+    sclboolean set_longkey_cancel_dist(sclshort dist);
+    sclboolean set_repeatkey_duration(scllong msc);
+    sclboolean set_autopopup_key_duration(scllong msc);
+
+    sclboolean set_button_delay_duration(scllong msc);
+
+    SCLDebugMode get_debug_mode();
+    void set_debug_mode(SCLDebugMode mode);
+
+    void disable_input_events(sclboolean disabled);
+
+protected:
+    /* Interval time(msc) for checking long key event */
+    scllong m_long_key_duration;
+    sclshort m_long_key_cancel_distance;
+    scllong m_repeat_key_duration;
+    scllong m_autopopup_key_duration;
+
+    scllong m_button_delay_duration;
+    scllong m_multitap_delay_duration;
+
+    SCLDebugMode m_debug_mode;
+    sclint m_debug_variable;
+
+    /* Better to move this variable to CSCLContext */
+    sclint m_key_repeated_num;
+
+    sclboolean m_input_events_disabled;
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_CONTROLLER_H__
diff --git a/scl/scldebug.cpp b/scl/scldebug.cpp
new file mode 100644 (file)
index 0000000..28bab82
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012 - 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 "scldebug.h"
+#include <sys/time.h>
+#include <string.h>
+
+
+#ifdef SCL_DEBUG_ON
+
+/* Measure elapased time */
+static float
+_SCL_DEBUG_ELAPSED_TIME(const char* str, struct timeval t0, struct timeval t1);
+
+/* Measure elapased time */
+float SCL_DEBUG_TIME(const char* fileStr, int line, const char* str)
+{
+    float etime = 0.0;
+    static struct timeval t0 = {
+        0,
+    };
+    static struct timeval t1;
+    char *pFileStr = const_cast<char*>(fileStr);
+    if (pFileStr) {
+        if (strlen(fileStr) > 20) {
+            pFileStr += (strlen(fileStr) - 20);
+        }
+        gettimeofday(&t1, NULL);
+        if (t0.tv_usec != 0) {
+            etime = ((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec))/1000000.0;
+        }
+        if (strncmp(str, "get_", 4) == 0) {
+            //printf("[%-20.20s]%04d [T:%u][E:" mc_red "%f" mc_normal "]" mc_normal " %s" mc_normal "\n", pFileStr, line, (t1.tv_sec * 1000000 + t1.tv_usec), etime, str);
+        } else {
+            printf("[%-20.20s]%04d [T:%lu][E:" mc_red "%f" mc_normal "]" mc_blue " %s" mc_normal "\n", pFileStr, line, (t1.tv_sec * 1000000 + t1.tv_usec), etime, str);
+        }
+        t0 = t1;
+    }
+    return etime;
+}
+
+/* Measure elapsed time */
+static float _SCL_DEBUG_ELAPSED_TIME(const char* str, struct timeval t0, struct timeval t1)
+{
+    float etime;
+    etime = ((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec))/1000000.0;
+
+    printf("[%s] elap-time = " mc_green "%f ms" mc_normal " (%lu~%lu) \n", str, etime*1000, (t0.tv_sec * 1000000 + t0.tv_usec), (t1.tv_sec * 1000000 + t1.tv_usec));
+    return etime;
+}
+
+/* Measure elapsed time */
+float SCL_DEBUG_ELAPSED_TIME(const char* fileStr, int line, const char* str, int type)
+{
+    static struct timeval s_tv1;
+    static struct timeval s_tv2;
+    static int s_start_line = 0;
+    static int s_end_line = 0;
+    float etime = 0.0;
+    if (type == MEASURE_START) {
+        gettimeofday(&s_tv1, NULL);
+        s_start_line = line;
+        printf("[%-20.20s]%04d [T:%lu]" mc_blue " %s" mc_normal "\n", fileStr, line, (s_tv1.tv_sec * 1000000 + s_tv1.tv_usec), str);
+    } else if (type == MEASURE_END) {
+        gettimeofday(&s_tv2, NULL);
+        s_end_line = line;
+        char printStr[100];
+        snprintf(printStr, 100, "%s(Line:%d~%d)", str, s_start_line, s_end_line);
+        etime = _SCL_DEBUG_ELAPSED_TIME(printStr, s_tv1, s_tv2);
+    }
+    return etime;
+}
+#endif
diff --git a/scl/scldebug.h b/scl/scldebug.h
new file mode 100644 (file)
index 0000000..b221628
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_DEBUG_H__
+#define __SCL_DEBUG_H__
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#if 1
+#define SCL_DEBUG_ON
+    /* Definition for debug message trace */
+#define scldebugc(m_code)                                              "\x1b[" # m_code
+#define scldebug_sync()                                                        (void)fflush(stdout)
+#define scldebug_puts(m_code)                                  (void)fputs(m_code, stdout)
+#define scldebug_clear_screen()                                        scldebug_puts(scldebugc(H) scldebugc(J))
+#define scldebug_move(m_x, m_y)                                        scldebug_puts(scldebugc(m_y;m_x ## H))
+#define scldebug_move_x(m_y)                                   scldebug_puts(scldebugc(;m_y ## H))
+#define scldebug_move_y(m_y)                                   scldebug_puts(scldebugc(m_y ## d))
+#define scldebug_puts_xy(m_x, m_y, m_message)  scldebug_puts(scldebugc(m_y;m_x ## H) m_message)
+#define mc_normal              scldebugc(0m)
+#define mc_black               scldebugc(1;30m)
+#define mc_red                 scldebugc(1;31m)
+#define mc_green               scldebugc(1;32m)
+#define mc_yellow              scldebugc(1;33m)
+#define mc_blue                        scldebugc(1;34m)
+#define mc_magenta             scldebugc(1;35m)
+#define mc_cyan                scldebugc(1;36m)
+#define mc_white               scldebugc(1;37m)
+
+#define MEASURE_START  0
+#define MEASURE_END    1
+
+    /* assert macro */
+#define scl_assert(_e) \
+       if (!(_e)) printf(mc_red "scl assert!(%s) failed at file :%s, line %04d, func: %s" mc_normal "\n", #_e, __FILE__, __LINE__, __FUNCTION__);
+
+#define scl_assert_return(_e) \
+       if (!(_e)) { printf(mc_red "scl assert!(%s) failed at file :%s, line %04d, func: %s" mc_normal "\n", #_e, __FILE__, __LINE__, __FUNCTION__); \
+       return;}
+
+#define scl_assert_return_false(_e) \
+       if (!(_e)) {printf(mc_red "scl assert!(%s) failed at file :%s, line %04d, func: %s" mc_normal "\n", #_e, __FILE__, __LINE__, __FUNCTION__); \
+       return 0;}
+
+#define scl_assert_return_null scl_assert_return_false
+
+    /* Measure elapsed time */
+    float
+    SCL_DEBUG_TIME(const char* fileStr, int line, const char* str);
+
+    /* Measure elapsed time */
+    float
+    SCL_DEBUG_ELAPSED_TIME(const char* fileStr, int line, const char* str, int type);
+
+#define SCL_DEBUG_ELAPSED_TIME_START() SCL_DEBUG_ELAPSED_TIME(__FILE__, __LINE__, __FUNCTION__, MEASURE_START);
+
+#define SCL_DEBUG_ELAPSED_TIME_END() SCL_DEBUG_ELAPSED_TIME(__FILE__, __LINE__, __FUNCTION__, MEASURE_END);
+
+//#define SCL_DEBUG() SCL_DEBUG_TIME(__FILE__, __LINE__, __FUNCTION__ );
+#define SCL_DEBUG()
+
+#define SCL_DEBUG_START() \
+    static struct timeval t0;\
+    static struct timeval t1;\
+    gettimeofday(&t0, NULL);\
+    printf("[%-20.20s][%04d][" mc_blue "%s" mc_normal "]\n", __FILE__, __LINE__, __FUNCTION__);
+
+#define SCL_DEBUG_END() \
+    gettimeofday(&t1, NULL);\
+    float etime;\
+    etime = ((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec))/1000000.0;\
+    printf("[%-20.20s][%04d][%s] E: " mc_green "%f" mc_normal " (S:%lu) \n", __FILE__, __LINE__, __FUNCTION__, etime, (t0.tv_sec * 1000000 + t0.tv_usec) );
+
+#define IO_TEST
+
+#else
+#define SCL_DEBUG_ELAPSED_TIME_START()
+#define SCL_DEBUG_ELAPSED_TIME_END()
+#define SCL_DEBUG()
+#define SCL_DEBUG_START()
+#define SCL_DEBUG_END()
+//#define IO_TEST
+
+#define scl_assert(_e)
+#define scl_assert_return(_e)
+#define scl_assert_return_false(_e)
+#define scl_assert_return_null scl_assert_return_false
+
+#endif
+
+#define scl_check_arrindex(idx, arrsize) (((idx) >= 0) && ((idx) < (arrsize)))
+#define scl_check_arrindex_unsigned(idx, arrsize) ((idx) < (arrsize))
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __SCL_DEBUG_H__ */
diff --git a/scl/scleffect.cpp b/scl/scleffect.cpp
new file mode 100644 (file)
index 0000000..f5202af
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2012 - 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.
+ *
+ */
+
diff --git a/scl/scleffect.h b/scl/scleffect.h
new file mode 100644 (file)
index 0000000..f5202af
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2012 - 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.
+ *
+ */
+
diff --git a/scl/sclerroradjustment.cpp b/scl/sclerroradjustment.cpp
new file mode 100644 (file)
index 0000000..e046e69
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+
+#include "sclerroradjustment.h"
+#include "scldebug.h"
+#include "sclresourcecache.h"
+#include "sclutils.h"
+
+#define OFFSET_MAX                     10
+#define TWO                            2
+
+using namespace scl;
+
+CSCLErrorAdjustment* CSCLErrorAdjustment::get_instance()
+{
+    static CSCLErrorAdjustment instance;
+    return &instance;
+}
+
+CSCLErrorAdjustment::CSCLErrorAdjustment()
+{
+    SCL_DEBUG();
+
+    m_enabled = TRUE;
+}
+
+CSCLErrorAdjustment::~CSCLErrorAdjustment()
+{
+    SCL_DEBUG();
+}
+
+void CSCLErrorAdjustment::enable_touch_offset(sclboolean enabled)
+{
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    if (utils) {
+        utils->log("TOUCH_OFFSET is %s!!!!\n", (enabled ? "enabled" : "disabled"));
+    }
+    m_enabled = enabled;
+}
+
+sclboolean
+CSCLErrorAdjustment::apply_touch_offset(SCLTouchOffsetLevel level, sclint *x, sclint *y)
+{
+    SCL_DEBUG();
+    CSCLEvents* events = CSCLEvents::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    SclPoint *pos;
+    pos = events->get_touch_event_offset();
+
+    if (m_enabled && utils) {
+        if (level == TOUCH_OFFSET_LEVEL_1) {
+            *x = *x + utils->get_scaled_x(pos->x);
+        } else if (level == TOUCH_OFFSET_LEVEL_2) {
+            *x = *x + utils->get_scaled_x(pos->x);
+            ///* CODE for landscape     CODE for landscape*/
+            //if (*x < utils->get_scale_x(scl_layout[LYT_LANDSCAPE_QTY_DEFAULT].width/TWO)) {
+            //    *x = *x + utils->get_scale_x(OFFSET_MAX +((*x - utils->get_scale_x(scl_layout[LYT_LANDSCAPE_QTY_DEFAULT].width/TWO)) /(utils->get_scale_x(scl_layout[LYT_LANDSCAPE_QTY_DEFAULT].width/TWO)/OFFSET_MAX)));
+            //} else {
+            //    *x = *x - utils->get_scale_x(OFFSET_MAX -((*x - utils->get_scale_x(scl_layout[LYT_LANDSCAPE_QTY_DEFAULT].width/TWO)) /(utils->get_scale_x(scl_layout[LYT_LANDSCAPE_QTY_DEFAULT].width/TWO)/OFFSET_MAX)));
+            //}
+        }
+        *y = *y + utils->get_scaled_y(pos->y);
+    }
+
+    return TRUE;
+}
+
+
diff --git a/scl/sclerroradjustment.h b/scl/sclerroradjustment.h
new file mode 100644 (file)
index 0000000..343db68
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012 - 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 "scltypes.h"
+#include "sclstructs.h"
+
+#ifndef __SCL_ERRORADJUSTMENT_H__
+#define __SCL_ERRORADJUSTMENT_H__
+
+//SCL_BEGIN_DECLS
+
+#define DEFAULT_VIBE_DURATION 100
+
+namespace scl
+{
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLErrorAdjustment
+{
+public:
+    CSCLErrorAdjustment();
+    CSCLErrorAdjustment(sclwindow parent);
+
+    virtual ~CSCLErrorAdjustment();
+    static CSCLErrorAdjustment* get_instance();
+
+private:
+public:
+    void enable_touch_offset(sclboolean enable);
+    sclboolean apply_touch_offset(SCLTouchOffsetLevel level, sclint *x, sclint *y);
+
+private:
+    sclboolean m_enabled;
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_ERRORADJUSTMENT_H__
diff --git a/scl/scleventcallback.h b/scl/scleventcallback.h
new file mode 100644 (file)
index 0000000..234d4e0
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_EVENTCALLBACK_H__
+#define __SCL_EVENTCALLBACK_H__
+
+//SCL_BEGIN_DECLS
+/* FIXME : Need to check the dependency cause by the next include statement */
+
+#include "scltypes.h"
+#include "sclconfig.h"
+#include "sclstructs.h"
+
+namespace scl
+{
+
+struct SclUIEventDesc {
+    SclUIEventDesc() {
+        key_value = NULL;
+        key_event = 0;
+        key_type = KEY_TYPE_NONE;
+        key_modifier = KEY_MODIFIER_NONE;
+        touch_id = 0;
+        touch_event_order = 0;
+        mouse_pressed_point.x = 0;
+        mouse_pressed_point.y = 0;
+        mouse_current_point.x = 0;
+        mouse_current_point.y = 0;
+        mouse_farthest_point.x = 0;
+        mouse_farthest_point.y = 0;
+        event_type = EVENT_TYPE_NONE;
+        mouse_pressed_point.x = 0;
+        mouse_pressed_point.y = 0;
+        mouse_current_point.x = 0;
+        mouse_current_point.y = 0;
+        mouse_farthest_point.x = 0;
+        mouse_farthest_point.y = 0;
+    }
+    const sclchar *key_value;
+    sclulong key_event;
+    SCLKeyType key_type;
+    SCLKeyModifier key_modifier;
+
+    /* Extra information for advanced event processing */
+    scltouchdevice touch_id;
+    sclint touch_event_order;
+
+    SclPoint mouse_pressed_point;
+    SclPoint mouse_current_point;
+    SclPoint mouse_farthest_point;
+
+    SCLEventType event_type;
+};
+
+struct SclNotiDesc {
+    SclUIEventDesc *ui_event_desc;
+};
+
+struct SclNotiPopupOpeningDesc : SclNotiDesc {
+    const char *input_mode;
+}; // SCL_UINOTITYPE_POPUP_OPENING
+
+struct SclNotiPopupOpenedDesc : SclNotiDesc {
+    sclwindow window;
+    const char *input_mode;
+}; // SCL_UINOTITYPE_POPUP_OPENED
+
+struct SclNotiPopupClosingDesc : SclNotiDesc {
+    sclwindow window;
+    const char *input_mode;
+    sclboolean timed_out;
+}; // SCL_UINOTITYPE_POPUP_CLOSING
+
+struct SclNotiPopupClosedDesc : SclNotiDesc {
+    sclwindow window;
+    const char *input_mode;
+    sclboolean timed_out;
+}; // SCL_UINOTITYPE_POPUP_CLOSED
+
+struct SclNotiGestureFlickDesc : SclNotiDesc {
+    SCLDragType drag_type;
+}; // SCL_UINOTITYPE_GESTURE_FLICK
+
+struct SclNotiShiftStateChangeDesc : SclNotiDesc {
+    SCLShiftState shift_state;
+}; // SCL_UINOTITYPE_SHIFT_STATE_CHANGE
+
+struct SclNotiInputModeChangeDesc : SclNotiDesc {
+    const char *input_mode;
+}; // SCL_UINOTITYPE_INPUT_MODE_CHANGE
+
+struct SclNotiHighlightNavigateDesc : SclNotiDesc {
+    SCLHighlightNavigationDirection direction;
+    sclwindow window_from;
+    scl8 key_from;
+    sclwindow window_to;
+    scl8 key_to;
+}; // SCL_UINOTITYPE_HIGHLIGHT_NAVIGATE
+
+/**
+* @brief The callback interface to handle SCL events
+*
+* ISE developers can inherit this interface and register it to the SCLCore class
+* to handle SCL events as they want.
+*/
+struct ISCLUIEventCallback {
+    virtual SCLEventReturnType on_event_key_clicked(SclUIEventDesc ui_event_desc) { return SCL_EVENT_PASS_ON; }
+    virtual SCLEventReturnType on_event_drag_state_changed(SclUIEventDesc ui_event_desc) { return SCL_EVENT_PASS_ON; }
+    virtual SCLEventReturnType on_event_notification(SCLUINotiType noti_type, SclNotiDesc *etc_info) { return SCL_EVENT_PASS_ON; }
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_EVENTCALLBACK_H__
diff --git a/scl/scleventhandler.cpp b/scl/scleventhandler.cpp
new file mode 100644 (file)
index 0000000..0f280c7
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2012 - 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 "sclresourcecache.h"
+#include "scleventhandler.h"
+#include "scldebug.h"
+#include "sclkeydefines.h"
+#include "scluiimpl.h"
+
+using namespace scl;
+
+CSCLEventHandler::CSCLEventHandler()
+{
+    SCL_DEBUG();
+
+    m_default_event_callback = NULL;
+    m_cur_input_mode_event_callback = NULL;
+}
+
+CSCLEventHandler::~CSCLEventHandler()
+{
+    SCL_DEBUG();
+}
+
+CSCLEventHandler*
+CSCLEventHandler::get_instance()
+{
+    static CSCLEventHandler instance;
+    return &instance;
+}
+
+static void handle_shift_button_click_event(SclUIEventDesc ui_event_desc)
+{
+    CSCLUIImpl *uiimpl = CSCLUIImpl::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+
+    if (uiimpl && context) {
+        if (ui_event_desc.key_type == KEY_TYPE_CONTROL && ui_event_desc.key_event == MVK_Shift_L) {
+            switch (uiimpl->get_shift_state()) {
+                case SCL_SHIFT_STATE_OFF: {
+                    uiimpl->set_shift_state(SCL_SHIFT_STATE_ON);
+                }
+                break;
+                case SCL_SHIFT_STATE_ON: {
+                    /* The default next state should be LOCK state */
+                    SCLShiftState next_state = SCL_SHIFT_STATE_LOCK;
+                    if (context->get_shift_multi_touch_enabled()) {
+                        if (context) {
+                            if (context->get_shift_multi_touch_state() == SCL_SHIFT_MULTITOUCH_ON_PRESSED) {
+                                /* If the shift multi touch state is ON_PRESSED, don't leave ON state now */
+                                next_state = SCL_SHIFT_STATE_ON;
+                            } else if (context->get_shift_multi_touch_state() == SCL_SHIFT_MULTITOUCH_ON_KEY_ENTERED) {
+                                /* If some keys were already entered while shift key was in pressed state, move to OFF */
+                                next_state = SCL_SHIFT_STATE_OFF;
+                            }
+                        }
+                    }
+                    uiimpl->set_shift_state(next_state);
+                }
+                break;
+                case SCL_SHIFT_STATE_LOCK: {
+                    uiimpl->set_shift_state(SCL_SHIFT_STATE_OFF);
+                }
+                break;
+                case SCL_SHIFT_STATE_MAX:
+                default:
+                    break;
+            }
+        }
+    }
+}
+
+static void handle_shift_state_on_button_click_event(SclUIEventDesc ui_event_desc)
+{
+    CSCLUIImpl *uiimpl = CSCLUIImpl::get_instance();
+
+    /* do not need the libscl-ui auto-captial the shift state  */
+    if (FALSE == uiimpl->get_autocapital_shift_state()) {
+        return;
+    }
+
+    CSCLContext *context = CSCLContext::get_instance();
+
+    sclboolean turn_shift_off = TRUE;
+    if (ui_event_desc.key_event == MVK_Shift_L || ui_event_desc.key_event == MVK_Caps_Lock) {
+        turn_shift_off = FALSE;
+    }
+    if (ui_event_desc.key_type == KEY_TYPE_MODECHANGE) {
+        turn_shift_off = FALSE;
+    }
+    if (ui_event_desc.key_modifier == KEY_MODIFIER_MULTITAP_START ||
+        ui_event_desc.key_modifier == KEY_MODIFIER_MULTITAP_REPEAT) {
+        turn_shift_off = FALSE;
+    }
+    /* If we are in ON_PRESSED or ON_KEY_ENTERED mode of shift multi touch state, do not turn it off now */
+    if (context) {
+        if (context->get_shift_multi_touch_enabled() && turn_shift_off) {
+            if (context->get_shift_multi_touch_state() == SCL_SHIFT_MULTITOUCH_ON_PRESSED) {
+                context->set_shift_multi_touch_state(SCL_SHIFT_MULTITOUCH_ON_KEY_ENTERED);
+                turn_shift_off = FALSE;
+            } else if (context->get_shift_multi_touch_state() == SCL_SHIFT_MULTITOUCH_ON_KEY_ENTERED) {
+                turn_shift_off = FALSE;
+            }
+        }
+    }
+    if (turn_shift_off) {
+        if (uiimpl->get_shift_state() == SCL_SHIFT_STATE_ON) {
+            uiimpl->set_shift_state(SCL_SHIFT_STATE_OFF);
+        }
+    }
+}
+
+static void handle_mode_change_button_click_event(SclUIEventDesc ui_event_desc)
+{
+    CSCLUIImpl *uiimpl = CSCLUIImpl::get_instance();
+
+    if (uiimpl) {
+        if (ui_event_desc.key_type == KEY_TYPE_MODECHANGE) {
+            uiimpl->set_input_mode(ui_event_desc.key_value);
+        }
+    }
+}
+
+SCLEventReturnType
+CSCLEventHandler::on_event_key_clicked(SclUIEventDesc ui_event_desc)
+{
+    SCLEventReturnType ret = SCL_EVENT_PASS_ON;
+
+    pre_process_ui_event(ui_event_desc);
+
+    if (m_cur_input_mode_event_callback) {
+        ret = m_cur_input_mode_event_callback->on_event_key_clicked(ui_event_desc);
+    }
+    if (ret == SCL_EVENT_PASS_ON) {
+        if (m_default_event_callback) {
+            ret = m_default_event_callback->on_event_key_clicked(ui_event_desc);
+        }
+    }
+
+    if (ret == SCL_EVENT_PASS_ON) {
+        /* Here we can put the fallback processing of this UIEvent */
+
+        /* General requirement - 1 */
+        /* When the SHIFT button was clicked, we change the shift state to OFF -> ON -> LOCK -> OFF ... */
+        handle_shift_button_click_event(ui_event_desc);
+
+        /* General requirement - 2 */
+        /* If a key was clicked but it is neither a SHIFT nor a CAPSLOCK, we just turn the shift off, if it is on */
+        handle_shift_state_on_button_click_event(ui_event_desc);
+
+        /* General requirement - 3 */
+        /* If the key type is KEY_TYPE_MODECHANGE, change the current input mode to given key_value */
+        handle_mode_change_button_click_event(ui_event_desc);
+    }
+
+    return ret;
+}
+
+SCLEventReturnType
+CSCLEventHandler::on_event_drag_state_changed(SclUIEventDesc ui_event_desc)
+{
+    SCLEventReturnType ret = SCL_EVENT_PASS_ON;
+
+    pre_process_ui_event(ui_event_desc);
+
+    if (m_cur_input_mode_event_callback) {
+        ret = m_cur_input_mode_event_callback->on_event_drag_state_changed(ui_event_desc);
+    }
+    if (ret == SCL_EVENT_PASS_ON) {
+        if (m_default_event_callback) {
+            ret = m_default_event_callback->on_event_drag_state_changed(ui_event_desc);
+        }
+    }
+
+    if (ret == SCL_EVENT_PASS_ON) {
+        /* Here we can put the fallback processing of this UIEvent */
+        CSCLUIImpl *uiimpl = CSCLUIImpl::get_instance();
+        CSCLContext *context = CSCLContext::get_instance();
+
+        /* General requirement - 1 */
+        /* When the SHIFT button was 'pressed' and shift button multitouch action is enabled,
+           we change the current shift multitouch state to 'ON_PRESSED' */
+        if (uiimpl && context) {
+            if (context->get_shift_multi_touch_enabled()) {
+                if (ui_event_desc.event_type == EVENT_TYPE_PRESS) {
+                    if (context) {
+                        if (ui_event_desc.key_event == MVK_Shift_L) {
+                            if (context->get_shift_multi_touch_state() == SCL_SHIFT_MULTITOUCH_OFF) {
+                                uiimpl->set_shift_state(SCL_SHIFT_STATE_ON);
+                                context->set_shift_multi_touch_state(SCL_SHIFT_MULTITOUCH_ON_PRESSED);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+SCLEventReturnType
+CSCLEventHandler::on_event_notification(SCLUINotiType noti_type, SclNotiDesc *etc_info)
+{
+    SCLEventReturnType ret = SCL_EVENT_PASS_ON;
+
+    if (m_cur_input_mode_event_callback) {
+        ret = m_cur_input_mode_event_callback->on_event_notification(noti_type, etc_info);
+    }
+    if (ret == SCL_EVENT_PASS_ON) {
+        if (m_default_event_callback) {
+            ret = m_default_event_callback->on_event_notification(noti_type, etc_info);
+        }
+    }
+
+    if (ret == SCL_EVENT_PASS_ON) {
+        /* Here we can put the fallback processing of this UIEvent */
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLEventHandler::set_input_mode(const sclchar *input_mode)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+    SclNotiInputModeChangeDesc desc;
+    desc.input_mode = input_mode;
+    if (SCL_EVENT_PASS_ON == on_event_notification(SCL_UINOTITYPE_INPUT_MODE_CHANGE, &desc)) {
+        m_cur_input_mode_event_callback = NULL;
+
+        if (input_mode) {
+            std::string id = input_mode;
+            std::map<std::string, ISCLUIEventCallback*>::iterator iter = m_input_mode_event_callbacks.find(input_mode);
+            if (iter != m_input_mode_event_callbacks.end()) {
+                m_cur_input_mode_event_callback = (iter->second);
+            }
+        }
+
+        ret = TRUE;
+    }
+
+    return ret;
+}
+
+void
+CSCLEventHandler::set_event_callback(ISCLUIEventCallback *callback, const sclchar *input_mode)
+{
+    SCL_DEBUG();
+
+    scl_assert_return(callback);
+
+    if (input_mode) {
+        std::string id = input_mode;
+        m_input_mode_event_callbacks[id] = callback;
+    } else {
+        m_default_event_callback = callback;
+    }
+}
+
+void
+CSCLEventHandler::pre_process_ui_event(SclUIEventDesc &ui_event_desc)
+{
+    SCL_DEBUG();
+
+    typedef struct {
+        const sclchar *key_value;
+        sclulong key_event;
+    } KEY_VALUE_EVENT_CONVERT_TABLE;
+
+    KEY_VALUE_EVENT_CONVERT_TABLE control_keys[] = {
+        {"Space",       MVK_space       },
+        {"BackSpace",   MVK_BackSpace   },
+        {"Shift",       MVK_Shift_L     },
+        {"CapsLock",    MVK_Caps_Lock   },
+        {"Enter",       MVK_Return      },
+        {"Left",        MVK_Left        },
+        {"Right",       MVK_Right       },
+        {"Up",          MVK_Up          },
+        {"Down",        MVK_Down        },
+        {"Escape",      MVK_Escape      },
+    };
+
+    /* Translate key_values only when key_event is 0 and key_value is not NULL */
+    if (ui_event_desc.key_value && ui_event_desc.key_event == 0) {
+        if (ui_event_desc.key_type == KEY_TYPE_CHAR) {
+            /* If the key_value is a string with length 1, and the first character has value between
+               SCL_ISCHAR range, provide the corresponding ASCII code in key_event field */
+            if (ui_event_desc.key_value[0] != '\0' && ui_event_desc.key_value[1] == '\0') {
+                if (SCL_ISCHAR(ui_event_desc.key_value[0])) {
+                    ui_event_desc.key_event = static_cast<sclulong>(ui_event_desc.key_value[0]);
+                }
+            }
+        } else if (ui_event_desc.key_type == KEY_TYPE_CONTROL) {
+            const scluint control_keys_size = sizeof(control_keys) / sizeof(KEY_VALUE_EVENT_CONVERT_TABLE);
+
+            for (scluint loop = 0;loop < control_keys_size;loop++) {
+                if (strncmp(control_keys[loop].key_value, ui_event_desc.key_value, strlen(control_keys[loop].key_value)) == 0) {
+                    ui_event_desc.key_event = control_keys[loop].key_event;
+                }
+            }
+        } else if (ui_event_desc.key_type == KEY_TYPE_STRING) {
+            CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+            if (cache) {
+                ui_event_desc.key_value = cache->find_substituted_string(ui_event_desc.key_value);
+            }
+        }
+    }
+}
diff --git a/scl/scleventhandler.h b/scl/scleventhandler.h
new file mode 100644 (file)
index 0000000..6823279
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 - 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 "sclgwes.h"
+#include "sclutils.h"
+#include "sclcontext.h"
+#include "scleventcallback.h"
+
+#ifndef __SCL_EVENT_HANDLER_H__
+#define __SCL_EVENT_HANDLER_H__
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+/**
+ * @brief The default event handler class
+ *
+ */
+class CSCLEventHandler : public ISCLUIEventCallback
+{
+private:
+    CSCLEventHandler();
+public:
+    virtual ~CSCLEventHandler();
+
+    static CSCLEventHandler* get_instance();
+
+    sclboolean set_input_mode(const sclchar *input_mode);
+    void set_event_callback(ISCLUIEventCallback *callback, const sclchar *input_mode);
+
+    SCLEventReturnType on_event_key_clicked(SclUIEventDesc ui_event_desc);
+    SCLEventReturnType on_event_drag_state_changed(SclUIEventDesc ui_event_desc);
+    SCLEventReturnType on_event_notification(SCLUINotiType noti_type, SclNotiDesc *etc_info);
+
+    void pre_process_ui_event(SclUIEventDesc &ui_event_desc);
+
+protected:
+    ISCLUIEventCallback* m_default_event_callback;
+    ISCLUIEventCallback* m_cur_input_mode_event_callback;
+
+    std::map<std::string, ISCLUIEventCallback*> m_input_mode_event_callbacks;
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_EVENT_HANDLER_H__
diff --git a/scl/sclevents-nui.cpp b/scl/sclevents-nui.cpp
new file mode 100644 (file)
index 0000000..5b4427e
--- /dev/null
@@ -0,0 +1,1249 @@
+/*
+ * Copyright (c) 2012 - 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 "sclevents-nui.h"
+#include "scldebug.h"
+#include "sclcontroller.h"
+#include "sclgraphics.h"
+#include "scluibuilder.h"
+#include "sclerroradjustment.h"
+#include "sclresource.h"
+#include "sclresourcecache.h"
+#include "sclres_manager.h"
+
+#include <Elementary.h>
+#include <Eldbus.h>
+#include <dlog.h>
+#ifdef WAYLAND
+#define EFL_BETA_API_SUPPORT
+#include <Ecore_Wl2.h>
+#else
+#include <Ecore_X.h>
+#endif
+
+#include "sclkeyfocushandler.h"
+
+using namespace scl;
+
+#ifdef USING_KEY_GRAB
+#define HANDLE_KEY_EVENTS
+#endif
+
+#define E_PROP_TOUCH_INPUT "X_TouchInput"
+
+#ifdef WAYLAND
+#define E_KEYBOARD_SERVICE_BUS_NAME "org.tizen.keyboard"
+#define E_KEYBOARD_SERVICE_NAVI_IFC_NAME "org.tizen.KBGestureNavigation"
+#define E_KEYBOARD_SERVICE_NAVI_OBJ_PATH "/org/tizen/KBGestureNavigation"
+static Eldbus_Connection *eldbus_conn = NULL;
+static Eldbus_Object *eldbus_bus_obj = NULL;
+
+typedef enum _Gesture {
+     ONE_FINGER_HOVER = 0,
+     ONE_FINGER_SINGLE_TAP = 15,
+     ONE_FINGER_DOUBLE_TAP = 16
+} Gesture;
+
+typedef struct
+{
+   Gesture type;         // Type of recognized gesture
+   int x;
+   int y;
+} Gesture_Info;
+#endif
+
+static sclboolean mouse_pressed = FALSE; /* Checks whether mouse is pressed or not */
+static sclwindow pressed_window = SCLWINDOW_INVALID;
+
+/* If the gap between two timestamps are bigger than 1 sec, do not compare */
+const unsigned int _touch_event_timestamp_compare_range = 1000;
+/* If the gap between two timestamps are smaller than 50 msec, do not process */
+const unsigned int _touch_event_timestamp_valid_threshold = 50;
+extern unsigned int g_timestamp_last_base_window_resized;
+
+#define MIN_XY_DIFF 14
+
+static Eina_Bool mouse_press(void *data, int type, void *event_info);
+static Eina_Bool mouse_move(void *data, int type, void *event_info);
+static Eina_Bool mouse_release(void *data, int type, void *event_info);
+
+#ifndef WAYLAND
+static Eina_Bool client_message_cb(void *data, int type, void *event);
+#endif
+
+#ifdef HANDLE_KEY_EVENTS
+static Eina_Bool key_pressed(void *data, int type, void *event_info);
+#endif
+
+static sclboolean get_window_rect(const sclwindow window, SclRectangle *rect)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    if (windows && context && utils && rect) {
+        SclWindowContext *window_context = windows->get_window_context(window);
+        sclint scr_w, scr_h;
+        /* get window size */
+        if (window_context && utils->get_screen_resolution(&scr_w, &scr_h)) {
+            switch (context->get_rotation()) {
+                case ROTATION_90_CW:
+                    {
+                        rect->height = window_context->geometry.width;
+                        rect->width = window_context->geometry.height;
+                        rect->y = scr_w - rect->height - window_context->geometry.x;
+                        rect->x = window_context->geometry.y;
+                    }
+                    break;
+                case ROTATION_180:
+                    {
+                        rect->width = window_context->geometry.width;
+                        rect->height = window_context->geometry.height;
+                        rect->x = scr_w - window_context->geometry.x - rect->width;
+                        rect->y = scr_h - window_context->geometry.y - rect->height;
+                    }
+                    break;
+                case ROTATION_90_CCW:
+                    {
+                        rect->height = window_context->geometry.width;
+                        rect->width = window_context->geometry.height;
+                        rect->y = window_context->geometry.x;
+                        rect->x = scr_h - window_context->geometry.y - rect->width;
+                    }
+                    break;
+                default:
+                    {
+                        rect->x = window_context->geometry.x;
+                        rect->y = window_context->geometry.y;
+                        rect->width = window_context->geometry.width;
+                        rect->height = window_context->geometry.height;
+                    }
+                    break;
+            }
+            ret = TRUE;
+        } else {
+            rect->x = rect->y = rect->width = rect->height = 0;
+        }
+    }
+    return ret;
+}
+
+#ifdef WAYLAND
+/* In wayland, root.x / root.y is not available, so need to apply virtual offset
+   when event occurred on a virtual window */
+static void apply_virtual_offset(SclRectangle rect, int *adjustx, int *adjusty)
+{
+    int virtual_offset_x = 0;
+    int virtual_offset_y = 0;
+    SclRectangle base_rect = {0, 0, 0, 0};
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    if (windows) {
+        if (get_window_rect(windows->get_base_window(), &base_rect)) {
+            virtual_offset_x = rect.x - base_rect.x;
+            virtual_offset_y = rect.y - base_rect.y;
+        }
+        if (adjustx && adjusty) {
+            *adjustx -= virtual_offset_x;
+            *adjusty -= virtual_offset_y;
+        }
+    }
+}
+#endif
+
+/**
+ * Constructor
+ */
+CSCLEventsImplNui::CSCLEventsImplNui()
+{
+    SCL_DEBUG();
+
+    m_mouse_down_handler = NULL;
+    m_mouse_move_handler = NULL;
+    m_mouse_up_handler = NULL;
+
+#ifndef WAYLAND
+    m_xclient_msg_handler = NULL;
+#endif
+    m_key_pressed_handler = NULL;
+}
+
+#ifdef WAYLAND
+static void gesture_cb(void *data, const Eldbus_Message *msg)
+{
+    LOGD("GestureDetected callback");
+    int g_type;
+    static int last_pos_x = -1;
+    static int last_pos_y = -1;
+
+    if (!msg) {
+        LOGD("Incoming message is empty");
+        return;
+    }
+    CSCLController *controller = CSCLController::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+
+    if (!windows || !controller) return;
+
+    sclwindow base_window = windows->get_base_window();
+    SclWindowContext *window_context = windows->get_window_context(base_window);
+
+    if (!window_context) return;
+    if (window_context->hidden) return;
+
+    LOGD("window_context->geometry.x=%d y=%d w=%d h=%d",
+            window_context->geometry.x, window_context->geometry.y,
+            window_context->geometry.width, window_context->geometry.height);
+
+    Gesture_Info *info = (Gesture_Info *)calloc(sizeof(Gesture_Info), 1);
+    if (!info) {
+        LOGD("Memory alloc failed for Gesture_Info");
+        return;
+    }
+    if (!eldbus_message_arguments_get(msg, "iii", &g_type, &info->x,
+                                      &info->y)) {
+        LOGD("Getting message arguments failed");
+        free(info);
+        return;
+    }
+
+    info->type = (Gesture)g_type;
+    LOGD("Incoming gesture name is %d : %d %d", info->type, info->x, info->y);
+
+    if (info->type == ONE_FINGER_HOVER || info->type == ONE_FINGER_SINGLE_TAP) {
+        if (info->y >= window_context->geometry.y) {
+            last_pos_x = info->x;
+            last_pos_y = info->y - window_context->geometry.y;
+            LOGD("hover last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
+            controller->mouse_over(base_window, last_pos_x, last_pos_y);
+        }
+    } else if (info->type == ONE_FINGER_DOUBLE_TAP) {
+        if (info->y >= window_context->geometry.y) {
+            last_pos_x = info->x;
+            last_pos_y = info->y - window_context->geometry.y;
+            LOGD("double last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
+            controller->mouse_press(base_window, last_pos_x, last_pos_y);
+            controller->mouse_release(base_window, last_pos_x, last_pos_y);
+        }
+    }
+    free(info);
+}
+
+static void gestures_tracker_register()
+{
+    Eldbus_Proxy *proxy = NULL;
+
+    if (eldbus_conn)
+        return;
+
+    eldbus_init();
+    LOGD("Registering callback for GestureDetected signal");
+    if (!(eldbus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION))) {
+        LOGW("Error: Unable to get session bus");
+        return;
+    }
+
+    eldbus_bus_obj = eldbus_object_get(eldbus_conn, E_KEYBOARD_SERVICE_BUS_NAME, E_KEYBOARD_SERVICE_NAVI_OBJ_PATH);
+    if (!eldbus_bus_obj) {
+        LOGW("Error: Getting object failed");
+        goto obj_err;
+    }
+
+    proxy = eldbus_proxy_get(eldbus_bus_obj, E_KEYBOARD_SERVICE_NAVI_IFC_NAME);
+    if (!proxy) {
+        LOGW("Error: Getting proxy failed");
+        goto proxy_err;
+    }
+
+    if (!eldbus_proxy_signal_handler_add(proxy, "KBGestureDetected", gesture_cb, NULL))
+        LOGW("No signal handler returned");
+
+    LOGD("Callback registration successful");
+    return;
+
+proxy_err:
+    eldbus_object_unref(eldbus_bus_obj);
+    eldbus_bus_obj = NULL;
+obj_err:
+    eldbus_connection_unref(eldbus_conn);
+    eldbus_conn = NULL;
+}
+
+static void gestures_tracker_unregister()
+{
+    if (eldbus_bus_obj) {
+        eldbus_object_unref(eldbus_bus_obj);
+        eldbus_bus_obj = NULL;
+    }
+
+    if (eldbus_conn) {
+        eldbus_connection_unref(eldbus_conn);
+        eldbus_conn = NULL;
+
+        eldbus_shutdown();
+    }
+}
+#endif
+/**
+ * De-constructor
+ */
+CSCLEventsImplNui::~CSCLEventsImplNui()
+{
+    SCL_DEBUG();
+
+    fini();
+}
+
+void CSCLEventsImplNui::init()
+{
+    /* Initializes all window resources */
+    m_mouse_down_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, mouse_press, NULL);
+    m_mouse_move_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, mouse_move, NULL);
+    m_mouse_up_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, mouse_release, NULL);
+
+#ifndef WAYLAND
+    m_xclient_msg_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, client_message_cb, NULL);
+#else
+    gestures_tracker_register();
+#endif
+
+#ifdef HANDLE_KEY_EVENTS
+    m_key_pressed_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, key_pressed, NULL);
+#endif
+}
+
+void CSCLEventsImplNui::fini()
+{
+    if (m_mouse_down_handler) ecore_event_handler_del(m_mouse_down_handler);
+    m_mouse_down_handler = NULL;
+    if (m_mouse_move_handler) ecore_event_handler_del(m_mouse_move_handler);
+    m_mouse_move_handler = NULL;
+    if (m_mouse_up_handler) ecore_event_handler_del(m_mouse_up_handler);
+    m_mouse_up_handler = NULL;
+#ifdef HANDLE_KEY_EVENTS
+    if (m_key_pressed_handler) ecore_event_handler_del(m_key_pressed_handler);
+#endif
+    m_key_pressed_handler = NULL;
+#ifndef WAYLAND
+    if (m_xclient_msg_handler) ecore_event_handler_del(m_xclient_msg_handler);
+#else
+    gestures_tracker_unregister();
+#endif
+}
+
+/**  Here x and y contains "actual" x and y position relative to portrait root window,
+     and window_context->width,height contains the window's orientation dependant width and height */
+SclPoint get_rotated_local_coords(sclint x, sclint y, SCLRotation rotation, SclRectangle *rect) {
+    SclPoint ret = {0, 0};
+
+    if (rect) {
+        switch (rotation) {
+            case ROTATION_90_CW:
+                {
+                    ret.x = (rect->y + rect->width) - y;
+                    ret.y = x - rect->x;
+                }
+                break;
+            case ROTATION_180:
+                {
+                    ret.x = (rect->x + rect->width) - x;
+                    ret.y = (rect->y + rect->height) - y;
+                }
+                break;
+            case ROTATION_90_CCW:
+                {
+                    ret.x = y - rect->y;
+                    ret.y = (rect->x + rect->height) - x;
+                }
+                break;
+            default:
+                {
+                    ret.x = x - rect->x;
+                    ret.y = y - rect->y;
+                }
+                break;
+        }
+    }
+    return ret;
+}
+
+static Eina_Bool check_timestamp_outdated(unsigned int timestamp)
+{
+    /* Skip events that were generated nearly at the same time when our base window resized */
+    timestamp -= _touch_event_timestamp_valid_threshold;
+    unsigned int gap = (g_timestamp_last_base_window_resized > timestamp) ?
+        (g_timestamp_last_base_window_resized - timestamp) :
+        (timestamp - g_timestamp_last_base_window_resized);
+    if (gap < _touch_event_timestamp_compare_range) {
+        if (g_timestamp_last_base_window_resized > timestamp) {
+            /* This event was generated before the base window resize event, ignore */
+            LOGD("Skipping event since turned out to be outdated : %u, %u",
+                    g_timestamp_last_base_window_resized, timestamp);
+            return EINA_TRUE;
+        }
+    }
+    return EINA_FALSE;
+}
+
+//void mouse_press (void *data, Evas *e, Evas_Object *object, void *event_info)
+static Eina_Bool mouse_press(void *data, int type, void *event_info)
+{
+    SCL_DEBUG();
+#ifdef WAYLAND
+    Ecore_Wl2_Window *wl_base_window;
+    Ecore_Wl2_Window *wl_magnifier_window;
+    Ecore_Wl2_Window *wl_window;
+#endif
+
+    CSCLController *controller = CSCLController::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+
+    Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info;
+
+    if (ev && check_timestamp_outdated(ev->timestamp)) {
+        return TRUE;
+    }
+
+    if (controller && windows && context && utils && adjustment && ev) {
+        LOGD("mouse_press : %d %d, %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y,
+                g_timestamp_last_base_window_resized, ev->timestamp);
+
+        sclbyte index = 0;
+        sclboolean processed = FALSE;
+        sclwindow window = SCLWINDOW_INVALID;
+
+#ifndef WAYLAND
+        Ecore_X_Window inputWindow = 0;
+        Ecore_X_Atom inputAtom = ecore_x_atom_get("DeviceMgr Input Window");
+        ecore_x_window_prop_xid_get(ecore_x_window_root_first_get(),
+            inputAtom, ECORE_X_ATOM_WINDOW, &inputWindow, 1);
+        if (inputWindow == 0) {
+            utils->log("Error : input window NULL!");
+        }
+
+        unsigned int touch_input = 0;
+        int res = ecore_x_window_prop_card32_get(inputWindow,
+            ecore_x_atom_get(E_PROP_TOUCH_INPUT), &touch_input, 1);
+
+        utils->log("E_PROP_TOUCH_INPUT : %d %d\n", res, touch_input);
+
+        if (1 == res) {
+            if (1 == touch_input) {
+                adjustment->enable_touch_offset(TRUE);
+            } else if (0 == touch_input) {
+                adjustment->enable_touch_offset(FALSE);
+            }
+        }
+#endif
+        sclboolean is_scl_window = FALSE;
+#ifdef WAYLAND
+        sclboolean is_magnifier_window = FALSE;
+        wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
+        wl_magnifier_window = (Ecore_Wl2_Window*)(elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
+        if (wl_base_window && (unsigned int)ecore_wl2_window_id_get(wl_base_window) == ev->window) {
+            is_scl_window = TRUE;
+        } else if (wl_magnifier_window && (unsigned int)ecore_wl2_window_id_get(wl_magnifier_window) == ev->window) {
+            is_scl_window = TRUE;
+            is_magnifier_window = TRUE;
+#else
+        if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window())) == ev->window) {
+            is_scl_window = TRUE;
+        } else if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_magnifier_window())) == ev->window) {
+            is_scl_window = TRUE;
+#endif
+        } else {
+            do {
+                window = windows->get_nth_window_in_Z_order_list(index);
+                SclWindowContext *window_context = windows->get_window_context(window);
+                if (window_context) {
+                    if (window_context->is_virtual) {
+                        is_scl_window  = TRUE;
+#ifdef WAYLAND
+                    } else if ((wl_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast<Evas_Object*>(window)))) {
+                        if ((unsigned int)ecore_wl2_window_id_get(wl_window) == ev->window)
+                            is_scl_window = TRUE;
+#else
+                    } else if (elm_win_xwindow_get(static_cast<Evas_Object*>(window)) == ev->window) {
+                        is_scl_window = TRUE;
+#endif
+                    }
+                }
+                index++;
+            } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID);
+            index = 0;
+        }
+        if (!is_scl_window) return TRUE;
+
+        SclRectangle rect = {0, 0, 0, 0};
+        do {
+            window = windows->get_nth_window_in_Z_order_list(index);
+            if (window) {
+                // Update the position of the target window
+                //windows->get_window_context(window, TRUE);
+                SclWindowContext *window_context = windows->get_window_context(window);
+                if (window_context) {
+                    windows->get_window_rect(window, &(window_context->geometry));
+                    if (get_window_rect(window, &rect)) {
+#ifdef WAYLAND
+                        int root_x = 0;
+                        int root_y = 0;
+                        if (is_magnifier_window) {
+                            SclRectangle magnifier_rect = { 0, 0, 0, 0 };
+                            if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
+                                root_x = ev->x + magnifier_rect.x;
+                                root_y = ev->y + magnifier_rect.y;
+                            }
+                        } else {
+                            root_x = ev->x + rect.x;
+                            root_y = ev->y + rect.y;
+                        }
+                        if (window_context->is_virtual) {
+                            apply_virtual_offset(rect, &root_x, &root_y);
+                        }
+#else
+                        int root_x = ev->root.x;
+                        int root_y = ev->root.y;
+#endif
+                        int adjust_x = root_x;
+                        int adjust_y = root_y;
+
+                        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+                        PSclDefaultConfigure default_configure = NULL;
+                        if (sclres_manager) {
+                            default_configure = sclres_manager->get_default_configure();
+                        }
+
+                        if (default_configure) {
+                            SCLDisplayMode display_mode = context->get_display_mode();
+                            if (scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+                                adjustment->apply_touch_offset(
+                                        default_configure->touch_offset_level[display_mode],
+                                        &adjust_x, &adjust_y);
+                            }
+                        }
+
+                        sclint win_width = rect.width;
+                        sclint win_height = rect.height;
+                        if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
+                            rect.height = win_width;
+                            rect.width = win_height;
+                        }
+
+                        /* Check whether will-be-adjusted coordinate is within the window area */
+                        sclboolean process_event = FALSE;
+                        if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
+                            (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
+                                process_event = TRUE;
+                        }
+                        if (process_event) {
+                            /* Now convert the global coordinate to appropriate local coordinate */
+                            SclPoint coords = get_rotated_local_coords(
+                                    root_x, root_y, context->get_rotation(), &rect);
+                            controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
+                            mouse_pressed = TRUE;
+                            processed = TRUE;
+                            pressed_window = window;
+                        }
+                    }
+                }
+            }
+            index++;
+        } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
+
+        if (!processed) {
+            window = pressed_window;
+            SclWindowContext *window_context = windows->get_window_context(window);
+            if (window_context && get_window_rect(window, &rect)) {
+                if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
+                    sclint temp = rect.width;
+                    rect.width = rect.height;
+                    rect.height = temp;
+                }
+
+                // Now convert the global coordinate to appropriate local coordinate
+#ifdef WAYLAND
+                int root_x = ev->x + rect.x;
+                int root_y = ev->y + rect.y;
+                if (window_context->is_virtual) {
+                    apply_virtual_offset(rect, &root_x, &root_y);
+                }
+#else
+                int root_x = ev->root.x;
+                int root_y = ev->root.y;
+#endif
+
+                SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
+                controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
+                mouse_pressed = TRUE;
+                processed = TRUE;
+            }
+        }
+    }
+
+    return TRUE;
+
+    /*CSCLContext *context = CSCLContext::get_instance();
+    controller->mouse_press((sclwindow)data, ev->output.x, ev->output.y);
+    mouse_pressed = TRUE;*/
+
+    //LOGD("=-=-=-=- mouse_press : %p %d %d\n", data, ev->output.x, ev->output.y);
+}
+
+//void mouse_release (void *data, Evas *e, Evas_Object *object, void *event_info)
+static Eina_Bool mouse_release(void *data, int type, void *event_info)
+{
+    SCL_DEBUG();
+
+    CSCLController *controller = CSCLController::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+
+    //Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up*)event_info;
+    Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info;
+
+    //if (!mouse_pressed) return FALSE;
+    if (ev && check_timestamp_outdated(ev->timestamp)) {
+        return TRUE;
+    }
+
+    if (controller && windows && context && ev) {
+        LOGD("mouse_release : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
+
+        sclbyte index = 0;
+        sclboolean processed = FALSE;
+        sclwindow window = SCLWINDOW_INVALID;
+        SclRectangle rect;
+        sclboolean dimwinevent = FALSE;
+        SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
+        if (dim_window_context) {
+            if (!(dim_window_context->is_virtual)) {
+                if (elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_dim_window())) == ev->window) {
+                    dimwinevent = TRUE;
+                }
+            }
+        }
+        if (dimwinevent) {
+            controller->mouse_press(windows->get_dim_window(), ev->root.x, ev->root.y, ev->multi.device);
+        } else {
+            do {
+                window = windows->get_nth_window_in_Z_order_list(index);
+                if (window) {
+                    SclWindowContext *window_context = windows->get_window_context(window);
+                    if (window_context) {
+                        windows->get_window_rect(window, &(window_context->geometry));
+                        if (get_window_rect(window, &rect)) {
+#ifdef WAYLAND
+                            int root_x = 0;
+                            int root_y = 0;
+                            Ecore_Wl2_Window *wl_magnifier_window =
+                                (Ecore_Wl2_Window*)(elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
+                            if (wl_magnifier_window &&
+                                (unsigned int)ecore_wl2_window_id_get(wl_magnifier_window) == ev->window) {
+                                SclRectangle magnifier_rect = { 0, 0, 0, 0 };
+                                if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
+                                    root_x = ev->x + magnifier_rect.x;
+                                    root_y = ev->y + magnifier_rect.y;
+                                }
+                            } else {
+                                root_x = ev->x + rect.x;
+                                root_y = ev->y + rect.y;
+                            }
+                            if (window_context->is_virtual) {
+                                apply_virtual_offset(rect, &root_x, &root_y);
+                            }
+#else
+                            int root_x = ev->root.x;
+                            int root_y = ev->root.y;
+#endif
+                            int adjust_x = root_x;
+                            int adjust_y = root_y;
+
+                            SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+                            PSclDefaultConfigure default_configure = NULL;
+                            if (sclres_manager) {
+                                default_configure = sclres_manager->get_default_configure();
+                            }
+
+                            if (default_configure) {
+                                SCLDisplayMode display_mode = context->get_display_mode();
+                                CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+                                if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+                                    adjustment->apply_touch_offset(
+                                            default_configure->touch_offset_level[display_mode],
+                                            &adjust_x, &adjust_y);
+                                }
+                            }
+
+                            sclint win_width = rect.width;
+                            sclint win_height = rect.height;
+                            if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
+                                rect.height = win_width;
+                                rect.width = win_height;
+                            }
+
+                            /* Check whether will-be-adjusted coordinate is within the window area */
+                            sclboolean process_event = FALSE;
+                            if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
+                                (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
+                                    process_event = TRUE;
+                            }
+                            if (process_event) {
+                                /* Now convert the global coordinate to appropriate local coordinate */
+                                SclPoint coords = get_rotated_local_coords(
+                                        root_x, root_y, context->get_rotation(), &rect);
+                                controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
+                                processed = TRUE;
+                            }
+                        }
+                    }
+                }
+                index++;
+            } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
+        }
+
+        if (!processed) {
+            window = pressed_window;
+            SclWindowContext *window_context = windows->get_window_context(window);
+            if (window_context && get_window_rect(window, &rect)) {
+                if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
+                    sclint temp = rect.width;
+                    rect.width = rect.height;
+                    rect.height = temp;
+                }
+
+                /* Now convert the global coordinate to appropriate local coordinate */
+#ifdef WAYLAND
+                int root_x = ev->x + rect.x;
+                int root_y = ev->y + rect.y;
+                if (window_context->is_virtual) {
+                    apply_virtual_offset(rect, &root_x, &root_y);
+                }
+#else
+                int root_x = ev->root.x;
+                int root_y = ev->root.y;
+#endif
+
+                SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
+                controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
+                processed = TRUE;
+            }
+        }
+
+        mouse_pressed = FALSE;
+    }
+
+    return TRUE;
+    //CSCLController *controller = CSCLController::get_instance();
+    //CSCLWindows *windows = CSCLWindows::get_instance();
+    //controller->mouse_release((sclwindow)data, (int)ev->output.x, (int)ev->output.y);
+    //controller->mouse_release((sclwindow)data, (int)ev->x, (int)ev->y);
+}
+
+#ifdef HANDLE_KEY_EVENTS
+static Eina_Bool key_pressed(void *data, int type, void *event_info)
+{
+    LOGD("=-=-=-=- key_pressed \n");
+    CSCLController *controller = CSCLController::get_instance();
+    Ecore_Event_Key *ev = (Ecore_Event_Key *)event_info;
+    const char *ckey_val = ev->key;
+    LOGD("=-=-=-=- ev->key(char) = %c \n", ev->key);
+    LOGD("=-=-=-=- ev->key(string) = %s \n", ev->key);
+    LOGD("=-=-=-=- ev->keyname(char) = %c \n", ev->keyname);
+    LOGD("=-=-=-=- ev->keyname(string) = %s \n", ev->keyname);
+    LOGD("=-=-=-=- ev->string(char) = %c \n", ev->string);
+    LOGD("=-=-=-=- ev->string(string) = %s \n", ev->string);
+
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    SclButtonContext *prev_button_context = NULL;
+    const SclLayoutKeyCoordinate *prevcoordinate = NULL;
+    SclButtonContext *button_context = NULL;
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    sclwindow window = windows->get_base_window();
+    CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+
+    sclbyte current_key_index = focus_handler->get_current_key_index();
+    sclbyte key_index = current_key_index;
+
+    if (strcmp(ev->keyname, "Right") == 0) {
+        key_index = focus_handler->get_next_key_index(NAVIGATE_RIGHT);
+    } else if (strcmp(ev->keyname, "Left") == 0) {
+        key_index = focus_handler->get_next_key_index(NAVIGATE_LEFT);
+    } else if (strcmp(ev->keyname, "Up") == 0) {
+        key_index = focus_handler->get_next_key_index(NAVIGATE_UP);
+    } else if (strcmp(ev->keyname, "Down") == 0) {
+        key_index = focus_handler->get_next_key_index(NAVIGATE_DOWN);
+    } else if ((strcmp(ev->keyname, "Return") == 0) || (strcmp(ev->keyname, "Enter") == 0)) {
+        button_context = cache->get_cur_button_context(window, current_key_index);
+        coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
+        button_context->state = BUTTON_STATE_NORMAL;
+        controller->mouse_press(window, coordinate->x, coordinate->y, TRUE);
+        controller->mouse_release(window, coordinate->x, coordinate->y, TRUE);
+        if (KEY_TYPE_MODECHANGE != coordinate->key_type) {
+            button_context->state = BUTTON_STATE_PRESSED;
+            windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+        } else {
+            focus_handler->init_key_index();
+        }
+        return TRUE;
+    }
+
+    if (current_key_index != key_index) {
+        button_context = cache->get_cur_button_context(window, key_index);
+        prev_button_context = cache->get_cur_button_context(window, current_key_index);
+        prevcoordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
+        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+        prev_button_context->state = BUTTON_STATE_NORMAL;
+        button_context->state = BUTTON_STATE_PRESSED;
+        sclshort x, y, width, height;
+        if (prevcoordinate->x < coordinate->x) {
+            x = prevcoordinate->x;
+        } else {
+            x = coordinate->x;
+        }
+
+        if (prevcoordinate->y < coordinate->y) {
+            y = prevcoordinate->y;
+        } else {
+            y = coordinate->y;
+        }
+
+        if (prevcoordinate->x + prevcoordinate->width > coordinate->x + coordinate->width) {
+            width = prevcoordinate->x + prevcoordinate->width - x;
+        } else {
+            width = coordinate->x + coordinate->width - x;
+        }
+
+        if (prevcoordinate->y + prevcoordinate->height > coordinate->y + coordinate->height) {
+            height = prevcoordinate->y + prevcoordinate->height - y;
+        } else {
+            height = coordinate->y + coordinate->height - y;
+        }
+        windows->update_window(window, x, y, width, height);
+
+    } else {
+    }
+
+    return TRUE;
+}
+#endif /*HANDLE_KEY_EVENTS*/
+
+//int mouse_move (void *data, Evas *e, Evas_Object *object, void *event_info)
+static Eina_Bool mouse_move(void *data, int type, void *event_info)
+{
+    SCL_DEBUG();
+
+    CSCLController *controller = CSCLController::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    //Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move*)event_info;
+    Ecore_Event_Mouse_Move *ev = (Ecore_Event_Mouse_Move*)event_info;
+
+    //if (!mouse_pressed) return FALSE;
+    if (ev && check_timestamp_outdated(ev->timestamp)) {
+        return TRUE;
+    }
+
+    if (controller && windows && context && cache && ev) {
+        sclbyte index = 0;
+        sclboolean processed = FALSE;
+        sclwindow window = SCLWINDOW_INVALID;
+        SclRectangle rect;
+
+        LOGD("mouse_move : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
+
+        if (context->get_cur_pressed_window(ev->multi.device) != SCLWINDOW_INVALID &&
+            get_window_rect(context->get_cur_pressed_window(ev->multi.device), &rect)) {
+            sclint winwidth = rect.width;
+            sclint winheight = rect.height;
+            if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
+                rect.height = winwidth;
+                rect.width = winheight;
+            }
+#ifdef WAYLAND
+            int root_x = 0;
+            int root_y = 0;
+
+            Ecore_Wl2_Window *wl_base_window =
+                (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
+            Ecore_Wl2_Window  *wl_magnifier_window =
+                (Ecore_Wl2_Window*)(elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_magnifier_window())));
+            if (wl_base_window && (unsigned int)ecore_wl2_window_id_get(wl_base_window) == ev->window) {
+                SclRectangle base_rect;
+                if (get_window_rect(windows->get_base_window(), &base_rect)) {
+                    root_x = ev->x + base_rect.x;
+                    root_y = ev->y + base_rect.y;
+                }
+            } else if (wl_magnifier_window && (unsigned int)ecore_wl2_window_id_get(wl_magnifier_window) == ev->window) {
+                SclRectangle magnifier_rect = { 0, 0, 0, 0 };
+                if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) {
+                    root_x = ev->x + magnifier_rect.x;
+                    root_y = ev->y + magnifier_rect.y;
+                }
+            } else {
+                root_x = ev->x + rect.x;
+                root_y = ev->y + rect.y;
+            }
+#else
+            int root_x = ev->root.x;
+            int root_y = ev->root.y;
+#endif
+
+            SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
+
+            controller->mouse_move(context->get_cur_pressed_window(ev->multi.device), coords.x, coords.y, ev->multi.device);
+            processed = TRUE;
+        } else {
+            do {
+                window = windows->get_nth_window_in_Z_order_list(index);
+                if (window) {
+                    SclWindowContext *window_context = windows->get_window_context(window);
+                    if (window_context) {
+                        windows->get_window_rect(window, &(window_context->geometry));
+                        if (get_window_rect(window, &rect)) {
+#ifdef WAYLAND
+                            int root_x = ev->x + rect.x;
+                            int root_y = ev->y + rect.y;
+                            if (window_context->is_virtual) {
+                                apply_virtual_offset(rect, &root_x, &root_y);
+                            }
+#else
+                            int root_x = ev->root.x;
+                            int root_y = ev->root.y;
+#endif
+                            int adjust_x = root_x;
+                            int adjust_y = root_y;
+
+                            SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+                            PSclDefaultConfigure default_configure = NULL;
+                            if (sclres_manager) {
+                                default_configure = sclres_manager->get_default_configure();
+                            }
+                            if (default_configure) {
+                                SCLDisplayMode display_mode = context->get_display_mode();
+                                CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+                                if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+                                    adjustment->apply_touch_offset(
+                                            default_configure->touch_offset_level[display_mode],
+                                            &adjust_x, &adjust_y);
+                                }
+                            }
+
+                            sclint win_width = rect.width;
+                            sclint win_height = rect.height;
+                            if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) {
+                                rect.height = win_width;
+                                rect.width = win_height;
+                            }
+
+                            sclboolean process_event = FALSE;
+                            if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) &&
+                                (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) {
+                                    process_event = TRUE;
+                            }
+                            /* Process this event regardless of the coordinate if the top window has the POPUP_GRAB layout style */
+                            if (index == SCL_WINDOW_Z_TOP) {
+                                const SclLayout *layout = cache->get_cur_layout(window);
+                                if (layout) {
+                                    if (layout->style == LAYOUT_STYLE_POPUP_GRAB) {
+                                        process_event = TRUE;
+                                    }
+                                }
+                            }
+                            if (process_event) {
+                                /* Now convert the global coordinate to appropriate local coordinate */
+                                SclPoint coords = get_rotated_local_coords(
+                                        root_x, root_y, context->get_rotation(), &rect);
+                                controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
+                                processed = TRUE;
+                            }
+                        }
+                    }
+                }
+                index++;
+            } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed);
+        }
+
+        if (!processed) {
+            window = pressed_window;
+            SclWindowContext *window_context = windows->get_window_context(window);
+            if (window_context && get_window_rect(window, &rect)) {
+                /* Now convert the global coordinate to appropriate local coordinate */
+#ifdef WAYLAND
+                int root_x = ev->x + rect.x;
+                int root_y = ev->y + rect.y;
+                if (window_context->is_virtual) {
+                    apply_virtual_offset(rect, &root_x, &root_y);
+                }
+#else
+                int root_x = ev->root.x;
+                int root_y = ev->root.y;
+#endif
+
+                SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
+                controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
+                processed = TRUE;
+            }
+        }
+    }
+    //CSCLController *controller = CSCLController::get_instance();
+    //CSCLWindows *windows = CSCLWindows::get_instance();
+    //controller->mouse_move((sclwindow)data, (int)ev->cur.output.x, (int)ev->cur.output.y);
+    //controller->mouse_move((sclwindow)data, (int)ev->x, (int)ev->y);
+
+    return TRUE;
+}
+
+/**
+ * Regists a event callback func to given window.
+ * In this function, it should call several event functions of CSCLController class whenever an event has occurred
+ * The below list shows what event function should be called.
+ * - mouse_press (when the user presses mouse button)
+ * - mouse_release (when the user releases mouse button)
+ * - mouse_move (when the user drags mouse button)
+ * - show_base_layout (when the expost event has occurred)
+ */
+void
+CSCLEventsImplNui::connect_window_events(const sclwindow wnd, const sclint evt)
+{
+    SCL_DEBUG();
+
+    //evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, NULL);
+    /*evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_UP, mouse_release, NULL);
+    evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, NULL);*/
+}
+
+#ifndef WAYLAND
+static Eina_Bool
+client_message_cb(void *data, int type, void *event)
+{
+    Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *)event;
+    if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL) {
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        CSCLController *controller = CSCLController::get_instance();
+
+        static int last_pos_x = -10000;
+        static int last_pos_y = -10000;
+
+        if (windows && controller) {
+            Evas_Object *base_win = (Evas_Object *)windows->get_base_window();
+            if (base_win == NULL) return FALSE;
+
+            if ((unsigned int)ev->data.l[0] == elm_win_xwindow_get(base_win)) {
+                if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE) {
+                // 1 finger double tap
+                controller->mouse_press(base_win, last_pos_x, last_pos_y);
+                controller->mouse_release(base_win, last_pos_x, last_pos_y);
+                } else if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ) {
+                    // 1 finger tap
+                    // 1 finger touch & move
+                    last_pos_x = ev->data.l[2];
+                    last_pos_y = ev->data.l[3];
+                    controller->mouse_over(base_win, last_pos_x, last_pos_y);
+                }
+            }
+        }
+    }
+    return ECORE_CALLBACK_PASS_ON;
+}
+#endif
+
+Eina_Bool timer_event(void *data)
+{
+    SCL_DEBUG();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLController *controller = CSCLController::get_instance();
+
+    scl32 sendData = static_cast<scl32>(reinterpret_cast<uintptr_t>(data) & 0xffffffff);
+
+    if (controller && utils) {
+        scl16 id = SCL_LOWORD(sendData); /* Timer ID */
+        Eina_Bool ret = controller->timer_event(sendData);
+        if (!ret) {
+            utils->log("Returning Timer : %d %d\n", id, ret);
+        }
+        return ret;
+    }
+    return TRUE;
+}
+
+/**
+ * Creates a timer
+ * In this function, it should call timer_event of CSCLController class
+ */
+void
+CSCLEventsImplNui::create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap)
+{
+    SCL_DEBUG();
+    sclint data = SCL_MAKELONG(id, value);
+    Ecore_Timer *pTimer = ecore_timer_add((double)interval / 1000.0, timer_event, (void*)(uintptr_t)data);
+    if (pTimer) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        if (utils) {
+            utils->log("Created Timer : %d %p\n", id, pTimer);
+        }
+        if (addToMap) {
+            idMap[id] = pTimer;
+        }
+    }
+}
+
+/**
+ * Destroys the given ID's timer
+ */
+void
+CSCLEventsImplNui::destroy_timer(const scl32 id)
+{
+    SCL_DEBUG();
+    //for ( std::map<int, Ecore_Timer*>::iterator idx = idMap.begin(); idx != idMap.end(); ++idx) {
+        std::map<int, Ecore_Timer*>::iterator idx = idMap.find(id);
+        //if ((*idx).first == id) {
+        if (idx != idMap.end()) {
+            CSCLUtils *utils = CSCLUtils::get_instance();
+            if (utils) {
+                utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second);
+            }
+            ecore_timer_del((*idx).second);
+            idMap.erase((*idx).first);
+            //break;
+        }
+    //}
+}
+
+/**
+ * Destroys all of created timer
+ */
+void
+CSCLEventsImplNui::destroy_all_timer()
+{
+    SCL_DEBUG();
+    for ( std::map<int, Ecore_Timer*>::iterator idx = idMap.begin(); idx != idMap.end(); ++idx ) {
+        ecore_timer_del((*idx).second);
+
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        if (utils) {
+            utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second);
+        }
+    }
+    idMap.clear();
+}
+
+void
+CSCLEventsImplNui::generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y)
+{
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    SclWindowContext *window_context = NULL;
+
+    static const sclint MAX_DEVICES = 100;
+    static sclboolean pressed[MAX_DEVICES] = { FALSE };
+    if (windows) {
+        switch (type) {
+            case SCL_MOUSE_EVENT_PRESS:
+            {
+                sclboolean generated = FALSE;
+                for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
+                    if (pressed[loop] != TRUE) {
+                        pressed[loop] = TRUE;
+                        Ecore_Event_Mouse_Button evt;
+#ifdef WAYLAND
+                        Ecore_Wl2_Window *wl_base_window;
+                        wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
+                        if (wl_base_window)
+                            evt.window = (unsigned int)ecore_wl2_window_id_get(wl_base_window);
+#else
+                        evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
+#endif
+                        //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
+                        window_context = windows->get_window_context(windows->get_base_window());
+                        if (window_context) {
+                            evt.x = evt.root.x = x + window_context->geometry.x;
+                            evt.y = evt.root.y = y + window_context->geometry.y;
+                            evt.multi.device = loop;
+                            mouse_press(NULL, 0, &evt);
+                        }
+                        generated = TRUE;
+                    }
+                }
+            }
+            break;
+            case SCL_MOUSE_EVENT_RELEASE:
+            {
+                sclboolean generated = FALSE;
+                for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
+                    if (pressed[loop] == TRUE) {
+                        pressed[loop] = FALSE;
+                        Ecore_Event_Mouse_Button evt;
+#ifdef WAYLAND
+                        Ecore_Wl2_Window *wl_base_window;
+                        wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
+                        if (wl_base_window)
+                            evt.window = (unsigned int)ecore_wl2_window_id_get(wl_base_window);
+#else
+                        evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
+#endif
+                        //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
+                        window_context = windows->get_window_context(windows->get_base_window());
+                        if (window_context) {
+                            evt.x = evt.root.x = x + window_context->geometry.x;
+                            evt.y = evt.root.y = y + window_context->geometry.y;
+                            evt.multi.device = loop;
+                            mouse_release(NULL, 0, &evt);
+                        }
+                        generated = TRUE;
+                    }
+                }
+            }
+            break;
+            case SCL_MOUSE_EVENT_MOVE:
+            {
+                sclboolean generated = FALSE;
+                for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) {
+                    if (pressed[loop] == TRUE) {
+                        Ecore_Event_Mouse_Move evt;
+#ifdef WAYLAND
+                        Ecore_Wl2_Window *wl_base_window;
+                        wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast<Evas_Object*>(windows->get_base_window()));
+                        if (wl_base_window)
+                            evt.window = (unsigned int)ecore_wl2_window_id_get(wl_base_window);
+#else
+                        evt.window = elm_win_xwindow_get(static_cast<Evas_Object*>(windows->get_base_window()));
+#endif
+                        //window_context = windows->get_window_context(windows->get_base_window(), FALSE);
+                        window_context = windows->get_window_context(windows->get_base_window());
+                        if (window_context) {
+                            evt.x = evt.root.x = x + window_context->geometry.x;
+                            evt.y = evt.root.y = y + window_context->geometry.y;
+                            evt.multi.device = loop;
+                            mouse_move(NULL, 0, &evt);
+                        }
+                        generated = TRUE;
+                    }
+                }
+            }
+            break;
+            default:
+            break;
+        }
+    }
+}
diff --git a/scl/sclevents-nui.h b/scl/sclevents-nui.h
new file mode 100644 (file)
index 0000000..663b2dd
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012 - 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 "sclevents.h"
+#include <Ecore_Evas.h>
+#include <Ecore.h>
+#include <map>
+
+
+#ifndef __SCL_EVENTS_NUI_H__
+#define __SCL_EVENTS_NUI_H__
+
+namespace scl
+{
+class CSCLEventsImplNui : public CSCLEventsImpl
+{
+public :
+    CSCLEventsImplNui();
+    ~CSCLEventsImplNui();
+
+    void init();
+    void fini();
+
+    /* Implementation about interface functions */
+    void connect_window_events(const sclwindow wnd, const sclint evt);
+    void create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap);
+    void destroy_timer(const scl32 id);
+    void destroy_all_timer();
+
+    void generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y);
+
+private:
+    std::map<int, Ecore_Timer*> idMap;
+
+    Ecore_Event_Handler *m_mouse_down_handler;
+    Ecore_Event_Handler *m_mouse_move_handler;
+    Ecore_Event_Handler *m_mouse_up_handler;
+    Ecore_Event_Handler *m_key_pressed_handler;
+};
+} /* End of scl namespace */
+#endif
diff --git a/scl/sclevents.cpp b/scl/sclevents.cpp
new file mode 100644 (file)
index 0000000..aea5d23
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2012 - 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 "sclevents.h"
+#ifdef  __WIN32__
+#include "sclevents-win32.h"
+#elif defined(__EFL__)
+#include "sclevents-efl.h"
+#elif defined(__NUI__)
+#include "sclevents-nui.h"
+#else
+#include "sclevents-gtk.h"
+#endif
+#include "scldebug.h"
+#include "sclwindows.h"
+
+#include "sclcontroller.h"
+#include "sclresourcecache.h"
+#include "sclkeyfocushandler.h"
+#include <dlog.h>
+
+using namespace scl;
+
+CSCLEvents::CSCLEvents()
+{
+    SCL_DEBUG();
+    m_impl = 0;
+    m_touch_event_offset.x = m_touch_event_offset.y = 0;
+}
+
+CSCLEvents::~CSCLEvents()
+{
+    SCL_DEBUG();
+
+    if (m_impl) {
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+
+void CSCLEvents::init()
+{
+    CSCLEventsImpl *impl = get_scl_events_impl();
+    if (impl) {
+        impl->init();
+    }
+}
+
+void CSCLEvents::fini()
+{
+    CSCLEventsImpl *impl = get_scl_events_impl();
+    if (impl) {
+        impl->fini();
+    }
+}
+
+CSCLEventsImpl* CSCLEvents::get_scl_events_impl()
+{
+    SCL_DEBUG();
+    if (m_impl == 0) {
+#ifdef  __WIN32__
+        m_impl = new CSCLEventsImplWin32;
+#elif defined(__EFL__)
+        m_impl = new CSCLEventsImplEfl;
+#elif defined(__NUI__)
+        m_impl = new CSCLEventsImplNui;
+#else
+        m_impl = new CSCLEventsImplGtk;
+#endif
+    }
+    return m_impl;
+}
+
+CSCLEvents* CSCLEvents::get_instance()
+{
+    static CSCLEvents instance;
+    return &instance;
+}
+
+void
+CSCLEvents::connect_window_events(sclwindow wnd, const sclint evt )
+{
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    if (!windows) return;
+
+    //SclWindowContext *window_context = windows->get_window_context(wnd, FALSE);
+    SclWindowContext *window_context = windows->get_window_context(wnd);
+    if (window_context) {
+        if (!(window_context->is_virtual)) {
+            get_scl_events_impl()->connect_window_events(wnd, evt);
+        }
+    }
+}
+
+void
+CSCLEvents::set_touch_event_offset(const SclPoint pos)
+{
+    m_touch_event_offset = pos;
+}
+
+SclPoint*
+CSCLEvents::get_touch_event_offset()
+{
+    return &m_touch_event_offset;
+}
+
+sclboolean
+CSCLEvents::process_key_event(const char *key)
+{
+    CSCLContext *context = CSCLContext::get_instance();
+    if (context && !(context->get_highlight_ui_enabled()))
+        return FALSE;
+
+    const char *keyname = key;
+    LOGD("=-=-=-=- key_pressed \n");
+    CSCLController *controller = CSCLController::get_instance();
+    LOGD("=-=-=-=- keyname(char) = %s \n", keyname);
+
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    const SclLayoutKeyCoordinate *prevcoordinate = NULL;
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+
+    if (!windows || !focus_handler || !cache || !controller) return FALSE;
+
+    sclwindow current_focus_window = focus_handler->get_current_focus_window();
+    scl8 current_key_index = focus_handler->get_current_focus_key();
+    sclwindow focus_window = current_focus_window;
+    scl8 key_index = current_key_index;
+
+    if (strcmp(keyname, "Right") == 0) {
+        focus_handler->process_navigation(HIGHLIGHT_NAVIGATE_RIGHT);
+        focus_window = focus_handler->get_current_focus_window();
+        key_index = focus_handler->get_current_focus_key();
+    } else if (strcmp(keyname, "Left") == 0) {
+        focus_handler->process_navigation(HIGHLIGHT_NAVIGATE_LEFT);
+        focus_window = focus_handler->get_current_focus_window();
+        key_index = focus_handler->get_current_focus_key();
+    } else if (strcmp(keyname, "Up") == 0) {
+        focus_handler->process_navigation(HIGHLIGHT_NAVIGATE_UP);
+        focus_window = focus_handler->get_current_focus_window();
+        key_index = focus_handler->get_current_focus_key();
+        if ((current_key_index == key_index) && (current_focus_window == focus_window))
+        {
+            return false;
+        }
+    } else if (strcmp(keyname, "Down") == 0) {
+        focus_handler->process_navigation(HIGHLIGHT_NAVIGATE_DOWN);
+        focus_window = focus_handler->get_current_focus_window();
+        key_index = focus_handler->get_current_focus_key();
+    } else if ((strcmp(keyname, "Return") == 0) || (strcmp(keyname, "Enter") == 0)) {
+        if (cache)
+            coordinate = cache->get_cur_layout_key_coordinate(current_focus_window, current_key_index);
+        //button_context->state = BUTTON_STATE_NORMAL;
+        if (coordinate && controller) {
+            controller->mouse_press(current_focus_window, coordinate->x, coordinate->y, TRUE);
+            controller->mouse_release(current_focus_window, coordinate->x, coordinate->y, TRUE);
+            if (KEY_TYPE_MODECHANGE != coordinate->key_type) {
+                //button_context->state = BUTTON_STATE_PRESSED;
+                //windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+            } else {
+                focus_handler->init_key_index();
+            }
+            return TRUE;
+        } else {
+            return FALSE;
+        }
+    } else {
+        return FALSE;
+    }
+
+    sclboolean ret = FALSE;
+    if (current_key_index != key_index || current_focus_window != focus_window) {
+        if (cache) {
+            prevcoordinate = cache->get_cur_layout_key_coordinate(current_focus_window, current_key_index);
+            coordinate = cache->get_cur_layout_key_coordinate(focus_window, key_index);
+        }
+        //prev_button_context->state = BUTTON_STATE_NORMAL;
+        //button_context->state = BUTTON_STATE_PRESSED;
+        if (coordinate && prevcoordinate) {
+            if (current_focus_window == focus_window) {
+                sclshort x, y, width, height;
+                if (prevcoordinate->x < coordinate->x) {
+                    x = prevcoordinate->x;
+                } else {
+                    x = coordinate->x;
+                }
+
+                if (prevcoordinate->y < coordinate->y) {
+                    y = prevcoordinate->y;
+                } else {
+                    y = coordinate->y;
+                }
+
+                if (prevcoordinate->x + prevcoordinate->width > coordinate->x + coordinate->width) {
+                    width = prevcoordinate->x + prevcoordinate->width - x;
+                } else {
+                    width = coordinate->x + coordinate->width - x;
+                }
+
+                if (prevcoordinate->y + prevcoordinate->height > coordinate->y + coordinate->height) {
+                    height = prevcoordinate->y + prevcoordinate->height - y;
+                } else {
+                    height = coordinate->y + coordinate->height - y;
+                }
+                windows->update_window(focus_window, x, y, width, height);
+            } else {
+                windows->update_window(focus_window,
+                    coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+                windows->update_window(current_focus_window,
+                    prevcoordinate->x, prevcoordinate->y, prevcoordinate->width, prevcoordinate->height);
+            }
+        }
+        ret = TRUE;
+    }
+    return ret;
+}
+
diff --git a/scl/sclevents.h b/scl/sclevents.h
new file mode 100644 (file)
index 0000000..487a66c
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "scltypes.h"
+#include "sclconfig.h"
+
+#ifndef __SCL_EVENTS_H__
+#define __SCL_EVENTS_H__
+
+#ifdef __cplusplus
+//SCL_BEGIN_DECLS
+#endif
+
+namespace scl
+{
+
+/**@brief window event definition */
+typedef enum _SCLCbEvent {
+    SCL_EVENT_MOUSE = 1 << 1, /**< for mouse event */
+    SCL_EVENT_EXPOSE = 1 << 2 /**< for expose */
+}SCLCbEvent;
+
+/**@brief window event definition */
+typedef enum _SCLMouseEvent {
+    SCL_MOUSE_EVENT_PRESS,
+    SCL_MOUSE_EVENT_MOVE,
+    SCL_MOUSE_EVENT_RELEASE,
+}SCLMouseEvent;
+
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLEventsImpl
+{
+public :
+    CSCLEventsImpl() {}
+    virtual ~CSCLEventsImpl() {}
+
+    virtual void init() = 0;
+    virtual void fini() = 0;
+
+    virtual void connect_window_events(const sclwindow wnd, const sclint evt) = 0;
+    virtual void create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap) = 0;
+    virtual void destroy_timer(const scl32 id) = 0;
+    virtual void destroy_all_timer() = 0;
+
+    virtual void generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y) = 0;
+};
+
+class CSCLEvents
+{
+public :
+    CSCLEvents();
+    virtual ~CSCLEvents();
+
+    static CSCLEvents* get_instance();
+
+    void init();
+    void fini();
+
+    void connect_window_events(sclwindow wnd, const sclint evt);
+
+    void create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap = TRUE) {
+        get_scl_events_impl()->destroy_timer(id);
+        get_scl_events_impl()->create_timer(id, interval, value, addToMap);
+    }
+
+    void destroy_timer(const scl32 id) {
+        get_scl_events_impl()->destroy_timer(id);
+    }
+
+    void destroy_all_timer() {
+        get_scl_events_impl()->destroy_all_timer();
+    }
+
+    void set_touch_event_offset(const SclPoint pos);
+    SclPoint* get_touch_event_offset();
+
+    virtual void generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y) {
+        get_scl_events_impl()->generate_mouse_event(type, x, y);
+    }
+
+    sclboolean process_key_event(const char *key);
+
+protected :
+    CSCLEventsImpl* get_scl_events_impl();
+
+private :
+    CSCLEventsImpl* m_impl;
+    SclPoint m_touch_event_offset;
+};
+
+
+} /* End of scl namespace */
+
+#ifdef __cplusplus
+//SCL_END_DECLS
+#endif
+
+#endif //__SCL_EVENTS_H__
diff --git a/scl/sclfeedback.cpp b/scl/sclfeedback.cpp
new file mode 100644 (file)
index 0000000..2829999
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+
+#include "sclfeedback.h"
+#include "scldebug.h"
+#include "sclresourcecache.h"
+#include "sclutils.h"
+#include "sclcontext.h"
+
+using namespace scl;
+
+CSCLFeedback* CSCLFeedback::get_instance()
+{
+    static CSCLFeedback instance;
+    return &instance;
+}
+
+CSCLFeedback::CSCLFeedback()
+{
+    SCL_DEBUG();
+}
+
+CSCLFeedback::~CSCLFeedback()
+{
+    SCL_DEBUG();
+}
+
+sclboolean
+CSCLFeedback::show_feedback(SCLFeedbackStyle style)
+{
+    SCL_DEBUG();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+
+    if (utils && context) {
+        switch (style) {
+            case FEEDBACK_STYLE_SOUND:
+                if (context->get_sound_enabled()) {
+                    utils->play_sound(DEFAULT_SOUND_STYLE);
+                }
+                break;
+            case FEEDBACK_STYLE_VIBRATION:
+                if (context->get_vibration_enabled()) {
+                    utils->play_vibration(DEFAULT_VIBRATION_STYLE, DEFAULT_VIBRATION_DURATION);
+                }
+                break;
+            default:
+                break;
+        }
+    }
+    return TRUE;
+}
+
+sclboolean
+CSCLFeedback::button_pressed(sclwindow window, sclbyte key_index)
+{
+    SCL_DEBUG();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    if (cache) {
+        const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        CSCLContext *context = CSCLContext::get_instance();
+        if (utils && context && coordinate) {
+            if (coordinate->sound_style) {
+                if (context->get_sound_enabled()) {
+                    utils->play_sound(coordinate->sound_style);
+                }
+            }
+            if (coordinate->vibe_style) {
+                if (context->get_vibration_enabled()) {
+                    utils->play_vibration(coordinate->vibe_style, DEFAULT_VIBRATION_DURATION);
+                }
+            }
+        }
+    }
+    return TRUE;
+}
+
+sclboolean
+CSCLFeedback::button_moved(sclwindow window, sclbyte key_index)
+{
+    SCL_DEBUG();
+    return TRUE;
+}
+
+sclboolean
+CSCLFeedback::button_released(sclwindow window, sclbyte key_index)
+{
+    SCL_DEBUG();
+    return TRUE;
+}
+
diff --git a/scl/sclfeedback.h b/scl/sclfeedback.h
new file mode 100644 (file)
index 0000000..426c870
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012 - 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 "scltypes.h"
+#include "sclstructs.h"
+
+#ifndef __SCL_FEEDBACK_H__
+#define __SCL_FEEDBACK_H__
+
+//SCL_BEGIN_DECLS
+
+#define DEFAULT_VIBRATION_DURATION 100
+#define DEFAULT_VIBRATION_STYLE "DEFAULT_VIBRATION"
+#define DEFAULT_SOUND_STYLE "DEFAULT_SOUND"
+
+namespace scl
+{
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLFeedback
+{
+public:
+    CSCLFeedback();
+    CSCLFeedback(sclwindow parent);
+
+    virtual ~CSCLFeedback();
+    static CSCLFeedback* get_instance();
+
+private:
+    sclboolean show_feedback(SCLFeedbackStyle style);
+
+public:
+    sclboolean button_pressed(sclwindow window, sclbyte key_index);
+    sclboolean button_moved(sclwindow window, sclbyte key_index);
+    sclboolean button_released(sclwindow window, sclbyte key_index);
+protected:
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_FEEDBACK_H__
diff --git a/scl/sclfontproxy.cpp b/scl/sclfontproxy.cpp
new file mode 100644 (file)
index 0000000..218f63a
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012 - 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 "sclgraphics.h"
+#include "sclfontproxy.h"
+#include "scldebug.h"
+
+using namespace scl;
+
+/**
+* Constructor
+*/
+CSCLFontProxy::CSCLFontProxy()
+{
+    SCL_DEBUG();
+
+    for (int loop = 0;loop < FONT_PROXY_SIZE;loop++) {
+        m_font_cache_items[loop].font = NULL;
+        memset(m_font_cache_items[loop].font_name, 0x00, sizeof(m_font_cache_items[loop].font_name));
+        m_font_cache_items[loop].font_size = 0;
+        m_font_cache_items[loop].is_italic = FALSE;
+        m_font_cache_items[loop].is_bold = FALSE;
+    }
+}
+
+/**
+* De-constructor
+*/
+CSCLFontProxy::~CSCLFontProxy()
+{
+    SCL_DEBUG();
+    free_fonts();
+}
+
+CSCLFontProxy* CSCLFontProxy::get_instance()
+{
+    static CSCLFontProxy instance;
+    return &instance;
+}
+
+sclfont
+CSCLFontProxy::get_font(const SclFontInfo& info)
+{
+    SCL_DEBUG();
+
+    sclfont ret = NULL;
+
+    for (int loop = 0;loop < FONT_PROXY_SIZE && ret == NULL;loop++) {
+        if (
+            strcmp(info.font_name, m_font_cache_items[loop].font_name) == 0 &&
+            info.font_size == m_font_cache_items[loop].font_size &&
+            info.is_italic == m_font_cache_items[loop].is_italic &&
+            info.is_bold == m_font_cache_items[loop].is_bold
+        ) {
+            ret = m_font_cache_items[loop].font;
+            break;
+        }
+    }
+
+    if (ret == NULL) {
+        sclboolean isEmpty = FALSE;
+        CSCLGraphics *graphics = CSCLGraphics::get_instance();
+        ret = graphics->create_font(info);
+
+        if (ret) {
+            for (int loop = 0;loop < FONT_PROXY_SIZE && !isEmpty;loop++) {
+                if (m_font_cache_items[loop].font == NULL) {
+                    isEmpty = TRUE;
+                    strncpy(m_font_cache_items[loop].font_name, info.font_name, MAX_FONT_NAME_LEN);
+                    m_font_cache_items[loop].font_name[MAX_FONT_NAME_LEN] = '\0';
+                    m_font_cache_items[loop].font_size = info.font_size;
+                    m_font_cache_items[loop].is_italic = info.is_italic;
+                    m_font_cache_items[loop].is_bold = info.is_bold;
+                    m_font_cache_items[loop].font = ret;
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+void
+CSCLFontProxy::free_fonts()
+{
+    SCL_DEBUG();
+
+    for (int loop = 0;loop < FONT_PROXY_SIZE;loop++) {
+        if (m_font_cache_items[loop].font) {
+            CSCLGraphics *graphics = CSCLGraphics::get_instance();
+            graphics->destroy_font(m_font_cache_items[loop].font);
+            m_font_cache_items[loop].font = NULL;
+        }
+    }
+}
diff --git a/scl/sclfontproxy.h b/scl/sclfontproxy.h
new file mode 100644 (file)
index 0000000..ecaeb96
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_FONT_PROXY_H__
+#define __SCL_FONT_PROXY_H__
+
+#include "sclgraphics.h"
+
+namespace scl
+{
+class CSCLFontProxy
+{
+private:
+    CSCLFontProxy();
+public :
+    virtual ~CSCLFontProxy();
+
+    static CSCLFontProxy* get_instance();
+
+    sclfont get_font(const SclFontInfo& info);
+    void free_fonts();
+
+private:
+    typedef struct _SclFontCacheItem {
+        sclchar font_name[MAX_FONT_NAME_LEN + 1];
+        sclshort font_size;
+        sclboolean is_italic;
+        sclboolean is_bold;
+        sclfont font;
+    } SclFontCacheItem;
+
+    static const sclint FONT_PROXY_SIZE = 128;
+    SclFontCacheItem m_font_cache_items[FONT_PROXY_SIZE];
+};
+} /* End of scl namespace */
+#endif
diff --git a/scl/sclgraphics-nui.cpp b/scl/sclgraphics-nui.cpp
new file mode 100644 (file)
index 0000000..60a46cb
--- /dev/null
@@ -0,0 +1,1157 @@
+/*
+ * Copyright (c) 2012 - 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 "sclgraphics-nui.h"
+#include "sclimageproxy.h"
+#include "sclfontproxy.h"
+#include "scldebug.h"
+#include "sclwindows.h"
+#include "sclresourcecache.h"
+#include "sclwindows-nui.h"
+#include "sclutils.h"
+
+#include <Ecore_Evas.h>
+#include <Ecore.h>
+#include <Elementary.h>
+//#include <list>
+#include <vector>
+#include <dlog.h>
+
+//#define EXTRACT_PARTIMAGE
+
+#ifdef TEST_NEWBACKEND
+std::vector<ImageCache> g_ImageCache;
+std::vector<TextCache> g_TextCache;
+sclint hash_string(const sclchar* str) {
+    sclint ret = 0;
+    sclint len = strlen(str);
+    for (sclint loop = 0;loop < len && str[loop];loop++) {
+        ret = ((loop + 1) * str[loop]);
+    }
+
+    return ret;
+}
+#else
+#endif
+using namespace scl;
+
+extern void mouse_press(void *data, Evas *e, Evas_Object *object, void *event_info);
+extern void mouse_release(void *data, Evas *e, Evas_Object *object, void *event_info);
+extern void mouse_move(void *data, Evas *e, Evas_Object *object, void *event_info);
+
+static std::map<std::string, SclNinePatchInfo> _nine_patch_map;
+
+/**
+ * Constructor
+ */
+CSCLGraphicsImplNui::CSCLGraphicsImplNui()
+{
+    SCL_DEBUG();
+    /* Initializes all window resources */
+    m_highlight_ui_object = NULL;
+    m_backend_callback = NULL;
+    m_backend_callback_data = NULL;
+}
+
+/**
+ * De-constructor
+ */
+CSCLGraphicsImplNui::~CSCLGraphicsImplNui()
+{
+    SCL_DEBUG();
+
+    fini();
+}
+
+void CSCLGraphicsImplNui::init()
+{
+    m_highlight_ui_object = NULL;
+    m_backend_callback = NULL;
+    m_backend_callback_data = NULL;
+}
+
+void CSCLGraphicsImplNui::fini()
+{
+    if (m_highlight_ui_object) {
+        evas_object_del(m_highlight_ui_object);
+        m_highlight_ui_object = NULL;
+    }
+
+    m_backend_callback = NULL;
+    m_backend_callback_data = NULL;
+}
+
+Evas_Object* extract_partimage_from_fullimage(
+    Evas_Object* fullimage,
+    int img_x, int img_y,
+    int cell_x, int cell_y,
+    int cell_cx, int cell_cy)
+{
+    unsigned int *data;
+    unsigned int *t_data;
+    int i, j;
+    int w, h;
+    Evas_Object *image_ob;
+
+    if (fullimage == NULL) {
+        return NULL;
+    }
+    evas_object_image_size_get(fullimage, &w, &h);
+
+    data = (unsigned int*)evas_object_image_data_get(fullimage, 0);
+    if (data == NULL) {
+        return NULL;
+    }
+
+    t_data = (unsigned int*)malloc(sizeof(unsigned int)*cell_cx*cell_cy);
+    if (t_data == NULL) {
+        return NULL;
+    }
+
+    for (i=img_y; i < img_y+cell_cy; i++) {
+        for (j=img_x; j < img_x+cell_cx; j++) {
+            t_data[(i-img_y)*cell_cx+(j-img_x)] = data[i*w+j];
+        }
+    }
+
+    image_ob = evas_object_image_add(evas_object_evas_get(fullimage));
+    if (image_ob == NULL) {
+        free(t_data);
+        return NULL;
+    }
+    evas_object_image_size_set(image_ob, cell_cx, cell_cy);
+    evas_object_image_data_set(image_ob, t_data);
+    evas_object_image_fill_set(image_ob, 0, 0, cell_cx, cell_cy);
+    evas_object_resize(image_ob, cell_cx, cell_cy);
+
+    evas_object_show(image_ob);
+
+    return image_ob;
+}
+
+static sclboolean check_nine_patch_png_file(const char *image_path)
+{
+    sclboolean found = FALSE;
+    for (sclint loop = strlen(image_path);!found && loop > 0;loop--) {
+        if (image_path[loop] == '.') {
+            found = TRUE;
+            if (loop >= 2) { // for checking prefix ".#" and ".9"
+                if (strcasecmp(image_path + loop - 2, ".#.png") == 0 ||
+                    strcasecmp(image_path + loop - 2, ".9.png") == 0) {
+                    return TRUE;
+                }
+            }
+        }
+    }
+    return FALSE;
+}
+
+SclNinePatchInfo get_nine_patch_info_from_png_file(Evas_Object *image_data, sclint w, sclint h)
+{
+    /* FIXME : Assuming we're dealing with 32bit image, need to check if there's any other cases */
+    SclNinePatchInfo ret = {0};
+    unsigned int *data = (unsigned int*)evas_object_image_data_get(image_data, EINA_FALSE);
+    if (data) {
+        int x, y;
+        sclboolean found;
+        found = FALSE;
+        for (x = 0;x < w && !found;x++) {
+            if (data[x] > 0) {
+                found = TRUE;
+                ret.left = x;
+            }
+        }
+        found = FALSE;
+        for (x = w - 1;x >= 0 && !found;x--) {
+            if (data[x] > 0) {
+                found = TRUE;
+                ret.right = w - (x + 1);
+            }
+        }
+        found = FALSE;
+        for (y = 0;y < h && !found;y++) {
+            if (data[y * w] > 0) {
+                found = TRUE;
+                ret.top = y;
+            }
+        }
+        found = FALSE;
+        for (y = h - 1;y >= 0 && !found;y--) {
+            if (data[y * w] > 0) {
+                found = TRUE;
+                ret.bottom = h - (y + 1);
+            }
+        }
+    }
+    return ret;
+}
+
+#if 0
+/**
+ * Returns Evas_Object representing window
+ */
+static Evas_Object *get_evas_window_object(sclwindow window)
+{
+    SclWindowContext *window_context = NULL;
+    CSCLWindows *windows = CSCLWindows::get_instance();
+
+    if (!window || !windows)
+        return NULL;
+
+    Evas_Object *window_object = (Evas_Object*)window;
+
+    window_context = windows->get_window_context(window);
+
+    if (window_context && window_context->is_virtual) {
+        window_object = static_cast<Evas_Object*>(windows->get_base_window());
+    }
+
+    return window_object;
+}
+
+/**
+ * Callback called on accessibility action
+ */
+static Eina_Bool access_action(void *data, Evas_Object *obj, Elm_Access_Action_Info *action_info) {
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLEvents* events = CSCLEvents::get_instance();
+
+    if (!windows || !events || !obj)
+        return EINA_FALSE;
+
+    Evas_Coord ex, ey, ew, eh;
+    evas_object_geometry_get(obj, &ex, &ey, &ew, &eh);
+    scl16 x = ex + ew / 2;
+    scl16 y = ey + eh / 2;
+
+    LOGD("access_action callback x: %d, y: %d", x, y);
+
+    SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());;
+    if (window_context) {
+        x -= window_context->geometry.x;
+        y -= window_context->geometry.y;
+    }
+
+    //simulate button press
+    events->generate_mouse_event(SCL_MOUSE_EVENT_PRESS, x, y);
+    events->generate_mouse_event(SCL_MOUSE_EVENT_RELEASE, x, y);
+    return EINA_TRUE;
+}
+#endif
+
+/**
+ * Register drawing as atspi object
+ */
+void CSCLGraphicsImplNui::register_atspi_object(sclwindow window, scldrawing drawing, const sclchar* name)
+{
+    SCL_DEBUG();
+
+    // FIXME
+#if 0
+    Evas_Object *window_object = get_evas_window_object(window);
+    Evas_Object *drawing_object = static_cast<Evas_Object*>(drawing);
+
+    if (!drawing_object || !window_object || !name)
+        return;
+
+    Evas_Object * access_object = elm_access_object_register(drawing_object, window_object);
+    if (!access_object)
+        return;
+
+    elm_atspi_accessible_name_set(access_object, name);
+    elm_atspi_accessible_role_set(access_object, ELM_ATSPI_ROLE_PUSH_BUTTON);
+    elm_access_action_cb_set(access_object, ELM_ACCESS_ACTION_ACTIVATE, access_action, name);
+#endif
+}
+
+extern sclint magnifierx, magnifiery;
+scldrawing
+CSCLGraphicsImplNui::draw_image(sclwindow window, const scldrawctx draw_ctx, sclchar* image_path, SclImageCachedInfo *cachedinfo,
+                                sclint dest_x, sclint dest_y, sclint dest_width, sclint dest_height,
+                                sclint src_x, sclint src_y, sclint src_width, sclint src_height, sclboolean extrace_image)
+{
+    SCL_DEBUG();
+
+    scl_assert_return_null(image_path);
+
+    LOGI("image path(%s), x(%d), y(%d), w(%d), h(%d)", image_path, dest_x, dest_y, dest_width, dest_height);
+
+    if (m_backend_callback) {
+        LOGI("call draw image callback");
+        SCL_DEBUG_ELAPSED_TIME_START();
+        m_backend_callback->on_draw_image(image_path, dest_x, dest_y, dest_width, dest_height, src_x, src_y, src_width, src_height, m_backend_callback_data);
+        SCL_DEBUG_ELAPSED_TIME_END();
+    }
+    else {
+        LOGW("### No draw image callback ###");
+    }
+
+    return NULL;
+
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    SclWindowContext *window_context = NULL;
+    SclWindowContext *target_window_context = NULL;
+    if (windows && window) {
+        //window_context = windows->get_window_context(window, FALSE);
+        window_context = windows->get_window_context(window);
+        //target_window_context = windows->get_window_context(draw_ctx, FALSE);
+        target_window_context = windows->get_window_context(draw_ctx);
+    }
+
+    if (window_context && target_window_context && image_path && utils && cache && windows) {
+        sclboolean is_highlight_ui = FALSE;
+        sclchar buf[_POSIX_PATH_MAX] = {0};
+        utils->get_decomposed_path(buf, IMG_PATH_PREFIX, image_path);
+        if (strcmp(buf, SCL_HIGHLIGHT_UI_IMAGE) == 0) {
+            is_highlight_ui = TRUE;
+        }
+
+        if (strlen(image_path) > 0) {
+#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW
+            if (window == windows->get_magnifier_window()) {
+                dest_x += magnifierx;
+                dest_y += magnifiery;
+            }
+#endif
+#ifdef TEST_NEWBACKEND
+            sclboolean bFound = FALSE;
+            sclboolean bOrgSizeMinusOne = (src_width == -1 && src_height == -1);
+            sclint hashval = hash_string(image_path);
+            /*for(std::list<ImageCache>::iterator iter = g_ImageCache.begin();
+                bFound && iter != g_ImageCache.end();std::advance(iter, 1)) {*/
+            for (sclint loop = 0;loop < (sclint)g_ImageCache.size() && !bFound;loop++) {
+                if (
+                    /*  (*iter).used &&
+                        window == (*iter).window &&
+                        hashval == (*iter).imgPathHash &&
+                        dest_x == (*iter).dest_x &&
+                        dest_y == (*iter).dest_y &&
+                        dest_width == (*iter).dest_width &&
+                        dest_height == (*iter).dest_height &&
+                        src_x == (*iter).src_x &&
+                        src_y == (*iter).src_y &&
+                        src_width == (*iter).src_width &&
+                        src_height == (*iter).src_height &&
+                        extrace_image == (*iter).extrace_image*/
+                        g_ImageCache[loop].used &&
+                        window == g_ImageCache[loop].window &&
+                        hashval == g_ImageCache[loop].imgPathHash &&
+                        dest_x == g_ImageCache[loop].dest_x &&
+                        dest_y == g_ImageCache[loop].dest_y &&
+                        dest_width == g_ImageCache[loop].dest_width &&
+                        dest_height == g_ImageCache[loop].dest_height &&
+                        src_x == g_ImageCache[loop].src_x &&
+                        src_y == g_ImageCache[loop].src_y &&
+                        src_width == g_ImageCache[loop].src_width &&
+                        src_height == g_ImageCache[loop].src_height &&
+                        extrace_image == g_ImageCache[loop].extrace_image
+                        )
+                    {
+                        //if (strcmp(image_path, (*iter).image_path) == 0) {
+                        if (strcmp(image_path, g_ImageCache[loop].image_path) == 0) {
+                            bFound = TRUE;
+                            //evas_object_show((*iter).image);
+                            evas_object_show(g_ImageCache[loop].image);
+                            evas_object_raise(g_ImageCache[loop].image);
+                            if (g_ImageCache[loop].clipper) {
+                                evas_object_show(g_ImageCache[loop].clipper);
+                                evas_object_raise(g_ImageCache[loop].clipper);
+                            }
+                        }
+                    }
+            }
+            if (!bFound) {
+#endif
+            EFLObject *clip_object = NULL;
+
+            Evas_Object *window_object = (Evas_Object*)window;
+            if (window_context->is_virtual) {
+                window_object = static_cast<Evas_Object*>(windows->get_base_window());
+            }
+
+            Evas *evas = evas_object_evas_get(window_object);
+            Evas_Object *image_object = NULL;
+            if (is_highlight_ui && m_highlight_ui_object) {
+                image_object = m_highlight_ui_object;
+                const SclNinePatchInfo *nine_patch_info = utils->get_nine_patch_info(image_path);
+                if (nine_patch_info) {
+                    evas_object_image_border_set(image_object,
+                            nine_patch_info->left, nine_patch_info->right, nine_patch_info->top, nine_patch_info->bottom);
+                }
+                evas_object_move(image_object, dest_x, dest_y);
+                evas_object_raise(image_object);
+                evas_object_show(image_object);
+            } else {
+                EFLObject *object = new EFLObject;
+                if (object) {
+                    image_object = evas_object_image_add(evas);
+                    object->extracted = FALSE;
+
+                    if (image_object) {
+                        int image_width = 0;
+                        int image_height = 0;
+                        evas_object_image_file_set(image_object, image_path, NULL);
+                        evas_object_image_size_get(image_object, &image_width, &image_height);
+
+                        sclboolean is_nine_patch_png = check_nine_patch_png_file(image_path);
+                        if (is_nine_patch_png) {
+                            std::map<std::string, SclNinePatchInfo>::iterator it = _nine_patch_map.find(image_path);
+                            if (it != _nine_patch_map.end()) {
+                                evas_object_image_border_set(image_object,
+                                    (*it).second.left, (*it).second.right, (*it).second.top, (*it).second.bottom);
+                            } else {
+                                SclNinePatchInfo info = get_nine_patch_info_from_png_file(image_object, image_width, image_height);
+                                evas_object_image_border_set(image_object, info.left, info.right, info.top, info.bottom);
+                                _nine_patch_map[std::string(image_path)] = info;
+                            }
+                        } else if (cachedinfo) {
+                            evas_object_image_border_set(image_object,
+                                    cachedinfo->nine_patch_left,
+                                    cachedinfo->nine_patch_right,
+                                    cachedinfo->nine_patch_top,
+                                    cachedinfo->nine_patch_bottom);
+                        } else {
+                            const SclNinePatchInfo *nine_patch_info = utils->get_nine_patch_info(image_path);
+                            if (nine_patch_info) {
+                                evas_object_image_border_set(image_object,
+                                        nine_patch_info->left, nine_patch_info->right, nine_patch_info->top, nine_patch_info->bottom);
+                            }
+                        }
+                        const SclLayout *layout = cache->get_cur_layout(window);
+                        if (layout) {
+                            if (layout->display_mode == DISPLAYMODE_PORTRAIT) {
+                                image_width = utils->get_scaled_x(image_width);
+                                image_height = utils->get_scaled_y(image_height);
+                            } else {
+                                image_width = utils->get_scaled_y(image_width);
+                                image_height = utils->get_scaled_x(image_height);
+                            }
+                        }
+                        if (src_width == -1 && src_height == -1) {
+                            src_width = image_width;
+                            src_height = image_height;
+                        }
+                        if ((src_width > 0 && src_height > 0) &&
+                            (image_width != dest_width || image_height != dest_height) && extrace_image) {
+    #ifdef EXTRACT_PARTIMAGE
+                            Evas_Object *newobj = extract_partimage_from_fullimage(image_object, src_x, src_y, 0, 0, src_width, src_height);
+                            object->extracted = TRUE;
+                            evas_object_del(image_object);
+                            image_object = newobj;
+                            evas_object_move(image_object, dest_x, dest_y);
+                            if (dest_width > 0 && dest_height > 0) {
+                                evas_object_image_fill_set(image_object, 0, 0, dest_width, dest_height);
+                                evas_object_resize(image_object, dest_width, dest_height);
+                            }
+    #else
+                            //evas_object_move(image_object, src_x - dest_x, src_y - dest_y);
+                            evas_object_move(image_object, dest_x - src_x, dest_y - src_y);
+                            evas_object_image_fill_set(image_object, 0, 0, image_width, image_height);
+                            evas_object_resize(image_object, image_width, image_height);
+
+                            Evas_Object *clipper = evas_object_rectangle_add(evas);
+                            evas_object_color_set(clipper, 255, 255, 255, 255);
+                            //evas_object_color_set(clipper, 0, 0, 0, 0);
+                            evas_object_move(clipper, dest_x, dest_y);
+                            evas_object_resize(clipper, dest_width, dest_height);
+                            evas_object_clip_set(image_object, clipper);
+                            evas_object_show(clipper);
+
+                            clip_object = new EFLObject;
+                            if (clip_object) {
+                                clip_object->object = clipper;
+                                clip_object->type = EFLOBJECT_CLIPOBJECT;
+                                clip_object->position.x = dest_x;
+                                clip_object->position.y = dest_y;
+                                clip_object->position.width = dest_width;
+                                clip_object->position.height = dest_height;
+                                clip_object->etc_info = image_path;
+                                clip_object->extracted = FALSE;
+                                clip_object->data = NULL;
+                            }
+    #endif
+                        } else {
+                            evas_object_move(image_object, dest_x, dest_y);
+                            if (dest_width > 0 && dest_height > 0) {
+                                if (is_nine_patch_png) {
+                                    evas_object_image_fill_set(image_object, -1, -1, dest_width + 2, dest_height + 2);
+                                } else {
+                                    evas_object_image_fill_set(image_object, 0, 0, dest_width, dest_height);
+                                }
+                                evas_object_resize(image_object, dest_width, dest_height);
+                            }
+                        }
+                        evas_object_raise(image_object);
+                        evas_object_show(image_object);
+
+                        //evas_object_event_callback_add((Evas_Object*)image_object, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, window);
+                        /*evas_object_event_callback_add((Evas_Object*)image_object, EVAS_CALLBACK_MOUSE_UP, mouse_release, window);
+                        evas_object_event_callback_add((Evas_Object*)image_object, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, window);*/
+
+                        object->object = image_object;
+                        object->type = EFLOBJECT_IMAGE;
+                        object->position.x = dest_x;
+                        object->position.y = dest_y;
+                        object->position.width = dest_width;
+                        object->position.height = dest_height;
+                        object->etc_info = image_path;
+                        object->data = clip_object;
+
+                        if (is_highlight_ui) {
+                            delete object;
+                        } else {
+                            target_window_context->etc_info =
+                                eina_list_append((Eina_List*)(target_window_context->etc_info), object);
+                            if (clip_object) {
+                                target_window_context->etc_info =
+                                    eina_list_append((Eina_List*)(target_window_context->etc_info), clip_object);
+                            }
+                        }
+
+                        /* FIXME : this is for placing the background image at the lowest depth */
+                        sclint window_layer = 29000;
+                        if (!windows->is_base_window(reinterpret_cast<sclwindow>(draw_ctx))) {
+                            window_layer = 29010;
+                        }
+                        //SclRectangle rt;
+                        //windows->get_window_rect(window, &rt);
+                        //if (rt.width == dest_width && rt.height == dest_height) {
+                        if (window_context->geometry.width == dest_width &&
+                            window_context->geometry.height == dest_height) {
+                            //evas_object_lower(image_object);
+                            evas_object_layer_set(image_object, window_layer + 0);
+                        } else {
+                            evas_object_layer_set(image_object, window_layer + 1);
+                        }
+                        return image_object;
+                    } else {
+                        delete object;
+                        object = NULL;
+                    }
+                }
+            }
+#ifdef TEST_NEWBACKEND
+                ImageCache cache;
+                cache.used = true;
+                cache.window = window;
+                strncpy(cache.image_path, image_path, sizeof(cache.image_path));
+                cache.imgPathHash = hashval;
+                cache.dest_x = dest_x;
+                cache.dest_y = dest_y;
+                cache.dest_width = dest_width;
+                cache.dest_height = dest_height;
+                cache.src_x = src_x;
+                cache.src_y = src_y;
+                if (bOrgSizeMinusOne) {
+                    cache.src_width = -1;
+                    cache.src_height = -1;
+                } else {
+                    cache.src_width = src_width;
+                    cache.src_height = src_height;
+                }
+                cache.extrace_image = extrace_image;
+                cache.image = object->object;
+                if (clip_object) {
+                    cache.clipper = clip_object->object;
+                } else {
+                    cache.clipper = NULL;
+                }
+
+                //g_ImageCache.insert(g_ImageCache.end(), cache);
+                sclboolean bInserted = FALSE;
+                for (sclint loop = 0;loop < (sclint)g_ImageCache.size() && !bInserted;loop++) {
+                    if (!g_ImageCache[loop].used) {
+                        g_ImageCache[loop] = cache;
+                    }
+                }
+                if (!bInserted) {
+                    g_ImageCache.push_back(cache);
+                }
+            }
+#endif
+        }
+    }
+    return NULL;
+}
+
+sclimage
+CSCLGraphicsImplNui::load_image(const sclchar *image_path)
+{
+    SCL_DEBUG();
+    return NULL;
+}
+
+void
+CSCLGraphicsImplNui::unload_image(sclimage image_data)
+{
+    SCL_DEBUG();
+}
+
+/**
+ * Initializes the drawing context for double-buffering.
+ * This func should be called before using a drawing primitive at first.
+ */
+scldrawctx
+CSCLGraphicsImplNui::begin_paint(const sclwindow window, const sclboolean force_draw /* = FALSE */)
+{
+    SCL_DEBUG();
+
+    scldrawctx drawctx = reinterpret_cast<scldrawctx>(window);
+    LOGD("");
+
+    return drawctx;
+}
+
+/**
+ * Notices that drawing tasks have done.
+ */
+void
+CSCLGraphicsImplNui::end_paint(const sclwindow window, scldrawctx draw_ctx)
+{
+    //Evas_Object *window_object = (Evas_Object*)window;
+    //Evas *evas = evas_object_evas_get(window_object);
+    //evas_render_idle_flush(evas);
+
+    LOGD("");
+}
+
+sclfont
+CSCLGraphicsImplNui::create_font(const SclFontInfo& info)
+{
+    return NULL;
+}
+
+void
+CSCLGraphicsImplNui::destroy_font(sclfont font)
+{
+}
+
+/**
+ * Draws the given text on cairo-surface
+ */
+scldrawing
+CSCLGraphicsImplNui::draw_text(sclwindow window, const scldrawctx draw_ctx, const SclFontInfo& font_info, const SclColor& color,
+                               const sclchar *str, SclTextCachedInfo *cachedinfo, sclint pos_x, sclint pos_y, sclint width, sclint height,
+                               SCLLabelAlignment align, sclint padding_x, sclint padding_y,
+                               sclint inner_width, sclint inner_height)
+{
+    SCL_DEBUG();
+    /*
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    SclWindowContext *window_context = NULL;
+    SclWindowContext *target_window_context = NULL;
+    */
+
+    LOGD("str(%s), x(%d), y(%d), w(%d), h(%d), pad_x(%d), pad_y(%d), fontsize(%d)", str, pos_x, pos_y, width, height, padding_x, padding_y, font_info.font_size);
+
+    if (m_backend_callback) {
+        LOGI("call draw text callback");
+        SCL_DEBUG_ELAPSED_TIME_START();
+        m_backend_callback->on_draw_text(font_info, color, str, pos_x, pos_y, width, height, align, padding_x, padding_y, inner_width, inner_height, m_backend_callback_data); //draw_text_cb_data);
+        SCL_DEBUG_ELAPSED_TIME_END();
+    }
+    else {
+        LOGW("### No draw text callback ###");
+    }
+
+    /*
+    if (draw_text_cb) {
+        LOGI("call draw text callback");
+        draw_text_cb(str, pos_x, pos_y, width, height, font_info.font_size, draw_text_cb_data);
+    }
+    else
+        LOGW("### No draw text callback ###");
+    */
+
+#if 0
+    if (windows && window) {
+        //window_context = windows->get_window_context(window, FALSE);
+        window_context = windows->get_window_context(window);
+        //target_window_context = windows->get_window_context(draw_ctx, FALSE);
+        target_window_context = windows->get_window_context(draw_ctx);
+    }
+
+    if (window_context && target_window_context && str && windows) {
+        if (strlen(str) > 0) {
+#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW
+            if (window == windows->get_magnifier_window()) {
+                pos_x += magnifierx;
+                pos_y += magnifiery;
+            }
+#endif
+#ifdef TEST_NEWBACKEND
+            sclboolean bFound = FALSE;
+            sclint hashval = hash_string(str);
+            sclint org_posx = pos_x;
+            sclint org_posy = pos_y;
+            /*for(std::list<TextCache>::iterator iter = g_TextCache.begin();
+                bFound && iter != g_TextCache.end();std::advance(iter, 1)) {*/
+            for (sclint loop = 0;loop < (sclint)g_TextCache.size() && !bFound;loop++) {
+                    if (
+                        /*
+                        (*iter).used &&
+                        window == (*iter).window &&
+                        strncmp(font_info.font_name, (*iter).font_info.font_name, MAX_FONT_NAME_LEN) == 0 &&
+                        font_info.font_size == (*iter).font_info.font_size &&
+                        font_info.is_bold == (*iter).font_info.is_bold &&
+                        font_info.is_italic == (*iter).font_info.is_italic &&
+                        memcmp(&color, &((*iter).color), sizeof(SclColor)) == 0 &&
+                        hashval == (*iter).strHash &&
+                        pos_x == (*iter).pos_x&&
+                        pos_y == (*iter).pos_y &&
+                        width == (*iter).width &&
+                        height == (*iter).height &&
+                        align == (*iter).align &&
+                        padding_x == (*iter).padding_x &&
+                        padding_y == (*iter).padding_y &&
+                        inner_width == (*iter).inner_width &&
+                        inner_height == (*iter).inner_height */
+
+                        g_TextCache[loop].used &&
+                        window == g_TextCache[loop].window &&
+                        strncmp(font_info.font_name, g_TextCache[loop].font_info.font_name, MAX_FONT_NAME_LEN) == 0 &&
+                        font_info.font_size == g_TextCache[loop].font_info.font_size &&
+                        font_info.is_bold == g_TextCache[loop].font_info.is_bold &&
+                        font_info.is_italic == g_TextCache[loop].font_info.is_italic &&
+                        memcmp(&color, &(g_TextCache[loop].color), sizeof(SclColor)) == 0 &&
+                        hashval == g_TextCache[loop].strHash &&
+                        pos_x == g_TextCache[loop].pos_x&&
+                        pos_y == g_TextCache[loop].pos_y &&
+                        width == g_TextCache[loop].width &&
+                        height == g_TextCache[loop].height &&
+                        align == g_TextCache[loop].align &&
+                        padding_x == g_TextCache[loop].padding_x &&
+                        padding_y == g_TextCache[loop].padding_y &&
+                        inner_width == g_TextCache[loop].inner_width &&
+                        inner_height == g_TextCache[loop].inner_height
+                        )
+                    {
+                        //if (strcmp(str, (*iter).str) == 0) {
+                        if (strcmp(str, g_TextCache[loop].str) == 0) {
+                            bFound = TRUE;
+                            //evas_object_show((*iter).text);
+                            evas_object_show(g_TextCache[loop].text);
+                            evas_object_raise(g_TextCache[loop].text);
+                        }
+                    }
+            }
+            if (!bFound) {
+#endif
+
+            EFLObject *object = new EFLObject;
+            if (object) {
+                object->extracted = FALSE;
+                Evas_Object *window_object = (Evas_Object*)window;
+                if (window_context->is_virtual) {
+                    window_object = static_cast<Evas_Object*>(windows->get_base_window());
+                }
+                Evas *evas = evas_object_evas_get(window_object);
+                Evas_Object *text_object = evas_object_textblock_add(evas);
+
+                if (text_object) {
+                    if (inner_width > 0 || inner_height > 0) {
+                        SclPoint bottom_right;
+                        bottom_right.x = pos_x + width;
+                        bottom_right.y = pos_y + height;
+
+                        /* The inner width and height value should be bigger than 0 */
+                        if (inner_width <= 0) inner_width = width;
+                        if (inner_height <= 0) inner_height = height;
+
+                        /* The inner width and height value should not exceed the actual width and height */
+                        if (inner_width > width) inner_width = width;
+                        if (inner_height > height) inner_height = height;
+
+                        /* We need to make a inner rectangle if inner_width and inner_height are not 0 */
+                        if (align == LABEL_ALIGN_CENTER_TOP ||
+                            align == LABEL_ALIGN_CENTER_MIDDLE ||
+                            align == LABEL_ALIGN_CENTER_BOTTOM) {
+                                pos_x = pos_x + ((width - inner_width) / 2) + padding_x;
+                        } else if (align == LABEL_ALIGN_RIGHT_TOP ||
+                            align == LABEL_ALIGN_RIGHT_MIDDLE ||
+                            align == LABEL_ALIGN_RIGHT_BOTTOM) {
+                                pos_x = pos_x + (width - inner_width) - padding_x;
+                        } else {
+                            pos_x += padding_x;
+                        }
+                        if (align == LABEL_ALIGN_LEFT_MIDDLE ||
+                            align == LABEL_ALIGN_CENTER_MIDDLE ||
+                            align == LABEL_ALIGN_RIGHT_MIDDLE) {
+                                pos_y = pos_y + ((height - inner_height) / 2) + padding_y;
+                        } else if (align == LABEL_ALIGN_LEFT_BOTTOM ||
+                            align == LABEL_ALIGN_CENTER_BOTTOM ||
+                            align == LABEL_ALIGN_RIGHT_BOTTOM) {
+                                pos_y = pos_y + (height - inner_height) - padding_y;
+                        } else {
+                            pos_y += padding_y;
+                        }
+
+                        /* Make sure the inner bounding box does not exceed the original bounding box */
+                        if (pos_x + inner_width > bottom_right.x) {
+                            width = bottom_right.x - pos_x;
+                        } else {
+                            width = inner_width;
+                        }
+                        if (pos_y + inner_height > bottom_right.y) {
+                            height = bottom_right.y - pos_y;
+                        } else {
+                            height = inner_height;
+                        }
+
+                        align = LABEL_ALIGN_CENTER_MIDDLE;
+                        padding_x = 0;
+                        padding_y = 0;
+                    }
+
+                    sclchar strStyle[256];
+                    snprintf(strStyle, 256,
+                        "DEFAULT='font=%s font_size=%d align=%s color=#%02X%02X%02X%02X wrap=word left_margin=%d right_margin=%d'",
+                            font_info.font_name, font_info.font_size,
+                            (((int)align % 3) == 1) ? "center" : ((((int)align % 3) == 2) ? "right" : "left"),
+                            color.r, color.g, color.b, color.a, padding_x, padding_x);
+
+                    Evas_Textblock_Style *st;
+                    st = evas_textblock_style_new();
+                    evas_textblock_style_set(st, strStyle);
+                    evas_object_textblock_style_set(text_object, st);
+                    //evas_textblock_style_free(st);
+
+                    //evas_object_textblock_clear(text_object);
+                    char *markup = evas_textblock_text_utf8_to_markup(text_object, str);
+                    if (markup) {
+                        evas_object_textblock_text_markup_set(text_object, markup);
+                        free(markup);
+                    }
+                    evas_object_resize(text_object, width, height);
+
+                    object->extracted = FALSE;
+                    object->type = EFLOBJECT_TEXTBLOCK;
+                    object->object = text_object;
+                    object->position.x = pos_x;
+                    object->position.y = pos_y;
+                    object->position.width = width;
+                    object->position.height = height;
+                    object->etc_info = str;
+                    object->data = st;
+
+                    sclint calwidth, calheight;
+                    if (cachedinfo) {
+                        calwidth = cachedinfo->actual_size.width;
+                        calheight = cachedinfo->actual_size.height;
+                    } else {
+                        evas_object_textblock_size_native_get(text_object, &calwidth, &calheight);
+                    }
+                    // FIXME: float to int may loose precision
+                    if (calwidth > 0) {
+                        static float _SPACE_RATE = 0.1;
+                        calwidth  *= 1 + _SPACE_RATE;
+                    }
+                    if (calheight > 0) {
+                        static float _SPACE_RATE = 0.1;
+                        calheight  *= 1 + _SPACE_RATE;
+                    }
+
+                    if (calwidth > width || calheight > height) {
+                        sclfloat width_rate = (sclfloat)width / (sclfloat)calwidth;
+                        sclfloat height_rate = (sclfloat)height / (sclfloat)calheight;
+                        sclfloat resize_rate = height_rate;
+                        if (width_rate < height_rate) {
+                            resize_rate = width_rate;
+                        }
+
+                        snprintf(strStyle, 128,
+                            "DEFAULT='font=%s font_size=%d align=%s color=#%02X%02X%02X%02X wrap=word left_margin=%d right_margin=%d'",
+                            font_info.font_name,
+                            (int)(SCL_LABEL_OVERLENGTH_TEXT_RESIZE_RATE * font_info.font_size * resize_rate),
+                            (((int)align % 3) == 1) ? "center" : ((((int)align % 3) == 2) ? "right" : "left"),
+                            color.r, color.g, color.b, color.a, padding_x, padding_x);
+                        evas_textblock_style_set(st, strStyle);
+                        evas_object_textblock_style_set(text_object, st);
+                        markup = evas_textblock_text_utf8_to_markup(text_object, str);
+                        if (markup) {
+                            evas_object_textblock_text_markup_set(text_object, markup);
+                            free(markup);
+                        }
+                        evas_object_resize(text_object, width, height);
+                        LOGI("[1] text object w: %d, h : %d", width, height);
+                        evas_object_textblock_size_native_get(text_object, &calwidth, &calheight);
+                    }
+
+                    /*if (align == LABEL_ALIGN_CENTER_TOP || align == LABEL_ALIGN_CENTER_MIDDLE || align == LABEL_ALIGN_CENTER_BOTTOM) {
+                        pos_x = pos_x + ((width - calwidth) / 2) + padding_x;
+                    } else if (align == LABEL_ALIGN_RIGHT_TOP || align == LABEL_ALIGN_RIGHT_MIDDLE || align == LABEL_ALIGN_RIGHT_BOTTOM) {
+                        pos_x = pos_x + (width - calwidth) - padding_x;
+                    } else {
+                        pos_x += padding_x;
+                    }*/
+                    if (align == LABEL_ALIGN_LEFT_MIDDLE ||
+                        align == LABEL_ALIGN_CENTER_MIDDLE ||
+                        align == LABEL_ALIGN_RIGHT_MIDDLE) {
+                            pos_y = pos_y + ((height - calheight) / 2) + padding_y;
+                    } else if (align == LABEL_ALIGN_LEFT_BOTTOM ||
+                        align == LABEL_ALIGN_CENTER_BOTTOM ||
+                        align == LABEL_ALIGN_RIGHT_BOTTOM) {
+                            pos_y = pos_y + (height - calheight) - padding_y;
+                    } else {
+                        pos_y += padding_y;
+                    }
+
+                    LOGI("[2] text object x: %d, y: %d, w: %d, h: %d", pos_x, pos_y, width, height);
+
+                    evas_object_move(text_object, pos_x, pos_y);
+                    evas_object_raise(text_object);
+                    evas_object_show(text_object);
+
+                    //evas_object_event_callback_add((Evas_Object*)text_object, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, window);
+                    /*evas_object_event_callback_add((Evas_Object*)text_object, EVAS_CALLBACK_MOUSE_UP, mouse_release, window);
+                    evas_object_event_callback_add((Evas_Object*)text_object, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, window);*/
+
+                    target_window_context->etc_info =
+                        eina_list_append((Eina_List*)(target_window_context->etc_info), object);
+
+                    sclint window_layer = 29000;
+                    if (!windows->is_base_window(reinterpret_cast<sclwindow>(draw_ctx))) {
+                        window_layer = 29010;
+                    }
+                    evas_object_layer_set(text_object, window_layer + 1);
+                    return text_object;
+                } else {
+                    delete object;
+                    object = NULL;
+                }
+            }
+#ifdef TEST_NEWBACKEND
+                TextCache cache;
+                cache.used = true;
+                cache.window = window;
+                cache.font_info = font_info;
+                cache.color = color;
+                strncpy(cache.font_info.font_name, font_info.font_name, MAX_FONT_NAME_LEN);
+                cache.font_info.font_size = font_info.font_size;
+                cache.font_info.is_bold = font_info.is_bold;
+                cache.font_info.is_italic = font_info.is_italic;
+                memcpy(&(cache.color), &(color), sizeof(SclColor));
+                strncpy(cache.str, str, sizeof(cache.str));
+                cache.strHash = hashval;
+                cache.pos_x = org_posx;
+                cache.pos_y = org_posy;
+                cache.width = width;
+                cache.height = height;
+                cache.align = align;
+                cache.padding_x = padding_x;
+                cache.padding_y = padding_y;
+                cache.inner_width = inner_width;
+                cache.inner_height = inner_height;
+
+                cache.text = object->object;
+
+                //g_TextCache.insert(g_TextCache.end(), cache);
+                sclboolean bInserted = FALSE;
+                for (sclint loop = 0;loop < (sclint)g_TextCache.size() && !bInserted;loop++) {
+                    if (!g_TextCache[loop].used) {
+                        g_TextCache[loop] = cache;
+                    }
+                }
+                if (!bInserted) {
+                    g_TextCache.push_back(cache);
+                }
+            }
+#endif /* TEST_NEWBACKEND */
+        }
+    }
+#endif /* 0 */
+
+    return NULL;
+}
+
+/**
+ * Draws a rectangle on cairo-surface
+ */
+scldrawing
+CSCLGraphicsImplNui::draw_rectangle(sclwindow window, const scldrawctx draw_ctx, scldouble pos_x, scldouble pos_y,
+                                    scldouble width, scldouble height, const scldouble line_width, const SclColor& line_color, sclboolean fill, const SclColor& fill_color, scldouble radius, sclfloat alpha)
+{
+    SCL_DEBUG();
+
+    LOGI("x(%f), y(%f), w(%f), h(%f)", pos_x, pos_y, width, height);
+    LOGI("fill(%d), r(%d), g(%d), b(%d), a(%d)", fill, fill_color.r, fill_color.g, fill_color.b, fill_color.a);
+
+    if (m_backend_callback) {
+        LOGI("call draw rectangle callback");
+        SCL_DEBUG_ELAPSED_TIME_START();
+        m_backend_callback->on_draw_rectangle(pos_x, pos_y, width, height, fill, fill_color.r, fill_color.g, fill_color.b, fill_color.a, m_backend_callback_data);
+        SCL_DEBUG_ELAPSED_TIME_END();
+    }
+    else {
+        LOGW("### No draw text callback ###");
+    }
+
+    return NULL;
+
+#if 0
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    SclWindowContext *window_context = NULL;
+    SclWindowContext *target_window_context = NULL;
+
+    if (windows && window) {
+        //window_context = windows->get_window_context(window, FALSE);
+        window_context = windows->get_window_context(window);
+        //target_window_context = windows->get_window_context(draw_ctx, FALSE);
+        target_window_context = windows->get_window_context(draw_ctx);
+    }
+
+    if (window_context && utils && cache && windows && target_window_context) {
+        EFLObject *object = new EFLObject;
+        if (object) {
+            Evas_Object *window_object = (Evas_Object*)window;
+            if (window_context->is_virtual) {
+                window_object = static_cast<Evas_Object*>(windows->get_base_window());
+            }
+
+            Evas *evas = evas_object_evas_get(window_object);
+            Evas_Object *rectobj = evas_object_rectangle_add(evas);
+
+            evas_object_color_set(rectobj, fill_color.r, fill_color.g, fill_color.b, fill_color.a);
+
+            evas_object_move(rectobj, pos_x, pos_y);
+            evas_object_resize(rectobj, width, height);
+            evas_object_show(rectobj);
+
+            object->extracted = FALSE;
+            object->object = rectobj;
+            object->type = EFLOBJECT_RECTANGLE;
+            object->position.x = pos_x;
+            object->position.y = pos_y;
+            object->position.width = width;
+            object->position.height = height;
+            object->etc_info = NULL;
+            object->data = NULL;
+
+            target_window_context->etc_info =
+                eina_list_append((Eina_List*)(target_window_context->etc_info), object);
+
+            /* FIXME : this is for placing the background image at the lowest depth */
+            sclint window_layer = 29000;
+            if (!windows->is_base_window(reinterpret_cast<sclwindow>(draw_ctx))) {
+                window_layer = 29010;
+            }
+            if (window_context->geometry.width == width &&
+                window_context->geometry.height == height) {
+                evas_object_layer_set(rectobj, window_layer + 0);
+            } else {
+                evas_object_layer_set(rectobj, window_layer + 1);
+            }
+            return rectobj;
+        }
+    }
+    return NULL;
+#endif
+}
+
+SclSize
+CSCLGraphicsImplNui::get_image_size(sclchar* image_path)
+{
+    SCL_DEBUG();
+    SclSize ret = { 0, 0 };
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    if (!windows) return ret;
+
+    Evas_Object *window_object = (Evas_Object*)(windows->get_base_window());
+    Evas_Object *image_object = NULL;
+
+    if (window_object) {
+        Evas *evas = evas_object_evas_get(window_object);
+        image_object = evas_object_image_add(evas);
+    }
+
+    if (image_object) {
+        int w, h;
+        evas_object_image_file_set(image_object, image_path, NULL);
+        evas_object_image_size_get(image_object, &w, &h);
+        evas_object_del(image_object);
+        ret.width = w;
+        ret.height = h;
+    }
+
+    return ret;
+}
+
+SclSize
+CSCLGraphicsImplNui::get_text_size(const SclFontInfo &fontinfo, const sclchar *str)
+{
+    SCL_DEBUG();
+    SclSize ret = { 0, 0 };
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    Evas_Object *winobj = NULL;
+    Evas *evas = NULL;
+
+    if (windows) {
+        winobj = (Evas_Object*)(windows->get_base_window());
+    }
+    if (winobj) {
+        evas = evas_object_evas_get(winobj);
+    }
+
+    int w, h;
+
+    Evas_Textblock_Style *st;
+    st = evas_textblock_style_new();
+
+    Evas_Object *text_object = evas_object_textblock_add(evas);
+
+    if (text_object && st) {
+        const sclint STYLE_STR_LEN = 256;
+        sclchar strStyle[STYLE_STR_LEN] = {0};
+        snprintf(strStyle, STYLE_STR_LEN - 1, "DEFAULT='font=%s font_size=%d'",
+            fontinfo.font_name, fontinfo.font_size);
+
+        evas_textblock_style_set(st, strStyle);
+        evas_object_textblock_style_set(text_object, st);
+
+        evas_object_textblock_clear(text_object);
+        char *markup = evas_textblock_text_utf8_to_markup(text_object, str);
+        if (markup) {
+            evas_object_textblock_text_markup_set(text_object, markup);
+            free(markup);
+        }
+
+        evas_object_textblock_size_native_get(text_object, &w, &h);
+
+        ret.width = w;
+        ret.height = h;
+    }
+    if (text_object) {
+        evas_object_del(text_object);
+    }
+    if (st) {
+        evas_textblock_style_free(st);
+    }
+
+    return ret;
+}
+
+void CSCLGraphicsImplNui::set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data)
+{
+    m_backend_callback = callback;
+    m_backend_callback_data = data;
+}
diff --git a/scl/sclgraphics-nui.h b/scl/sclgraphics-nui.h
new file mode 100644 (file)
index 0000000..faabf40
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2012 - 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 "sclgraphics.h"
+
+#ifndef __SCL_GRAPHICS_NUI_H__
+#define __SCL_GRAPHICS_NUI_H__
+
+//#define DO_NOT_MOVE_MAGNIFIER_WINDOW
+//#define FULL_SCREEN_TEST
+
+#include <Evas.h>
+
+/* Still an experimental feature.. Will be refined after being stabilized */
+//#define TEST_NEWBACKEND
+#ifdef TEST_NEWBACKEND
+using namespace scl;
+
+#include <Ecore_Evas.h>
+#include <Ecore.h>
+
+typedef struct {
+    sclboolean used;
+
+    Evas_Object *image;
+    Evas_Object *clipper;
+
+    sclwindow window;
+    sclchar image_path[_POSIX_PATH_MAX];
+    sclint imgPathHash;
+    sclint dest_x;
+    sclint dest_y;
+    sclint dest_width;
+    sclint dest_height;
+    sclint src_x;
+    sclint src_y;
+    sclint src_width;
+    sclint src_height;
+    sclboolean extrace_image;
+} ImageCache;
+
+typedef struct {
+    sclboolean used;
+
+    Evas_Object *text;
+
+    sclwindow window;
+    scl::SclFontInfo font_info;
+    SclColor color;
+    sclchar str[_POSIX_PATH_MAX];;
+    sclint strHash;
+    sclint pos_x;
+    sclint pos_y;
+    sclint width;
+    sclint height;
+    SCLLabelAlignment align;
+    sclint padding_x;
+    sclint padding_y;
+    sclint inner_width;
+    sclint inner_height;
+} TextCache;
+#else
+#endif
+
+namespace scl
+{
+class CSCLGraphicsImplNui : public CSCLGraphicsImpl
+{
+public :
+    CSCLGraphicsImplNui();
+    ~CSCLGraphicsImplNui();
+
+    void init();
+    void fini();
+
+    scldrawing draw_image(sclwindow window, const scldrawctx draw_ctx, sclchar* image_path, SclImageCachedInfo *cachedinfo,
+                    sclint dest_x, sclint dest_y, sclint dest_width, sclint dest_height,
+                    sclint src_x, sclint src_y, sclint src_width, sclint src_height, sclboolean extrace_image);
+    sclimage load_image(const sclchar* image_path);
+    void unload_image(sclimage image_data);
+
+    sclfont create_font(const SclFontInfo& info);
+    void destroy_font(sclfont font);
+    scldrawing draw_text(sclwindow window, const scldrawctx draw_ctx, const SclFontInfo& font_info, const SclColor& color,
+                   const sclchar *str, SclTextCachedInfo *cachedinfo, sclint pos_x, sclint pos_y, sclint width, sclint height,
+                   SCLLabelAlignment align, sclint padding_x, sclint padding_y, sclint inner_width, sclint inner_height);
+
+    scldrawing draw_rectangle(sclwindow window, const scldrawctx draw_ctx, scldouble pos_x, scldouble pos_y,
+                        scldouble width, scldouble height, const scldouble line_width, const SclColor& line_color,
+                        sclboolean fill, const SclColor& fill_color, scldouble radius, sclfloat alpha);
+    scldrawctx begin_paint(const sclwindow window, const sclboolean force_draw = FALSE);
+    void end_paint(const sclwindow window, scldrawctx draw_ctx);
+    SclSize get_image_size(sclchar* image_path);
+    SclSize get_text_size(const SclFontInfo &fontinfo, const sclchar *str);
+
+    void register_atspi_object(sclwindow window, scldrawing drawing, const sclchar* name);
+    //void set_draw_text_cb(scl_ui_draw_text_cb callback, void *data);
+    void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data);
+
+private:
+    Evas_Object *m_highlight_ui_object;
+    ISCLUIGraphicsBackendCallback* m_backend_callback;
+    void* m_backend_callback_data;
+};
+} /* End of scl namespace */
+#endif
diff --git a/scl/sclgraphics.cpp b/scl/sclgraphics.cpp
new file mode 100644 (file)
index 0000000..deb25d5
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012 - 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.
+ *
+ */
+
+#define __GTK__ 1
+
+#include "sclgraphics.h"
+#ifdef  __WIN32__
+#include "sclgraphics-win32.h"
+#elif defined(__EFL__)
+#include "sclgraphics-efl.h"
+#elif defined(__NUI__)
+#include "sclgraphics-nui.h"
+#elif __GTK__
+#include "sclgraphics-gtk.h"
+#else
+#include "sclgraphics-cairo.h"
+#endif
+#include "scldebug.h"
+
+using namespace scl;
+
+CSCLGraphics::CSCLGraphics()
+{
+    SCL_DEBUG();
+    m_impl = NULL;
+}
+
+CSCLGraphics::~CSCLGraphics()
+{
+    SCL_DEBUG();
+
+    if (m_impl) {
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+
+void CSCLGraphics::init()
+{
+    CSCLGraphicsImpl *impl = get_scl_graphics_impl();
+    if (impl) {
+        impl->init();
+    }
+}
+
+void CSCLGraphics::fini()
+{
+    CSCLGraphicsImpl *impl = get_scl_graphics_impl();
+    if (impl) {
+        impl->fini();
+    }
+}
+
+CSCLGraphicsImpl* CSCLGraphics::get_scl_graphics_impl()
+{
+    SCL_DEBUG();
+    if (m_impl == 0) {
+#ifdef  __WIN32__
+        m_impl = new CSCLGraphicsImplWin32;
+#elif defined(__EFL__)
+        m_impl = new CSCLGraphicsImplEfl;
+#elif defined(__NUI__)
+        m_impl = new CSCLGraphicsImplNui;
+#elif __GTK__
+        m_impl = new CSCLGraphicsImplGtk;
+#else
+        m_impl = new CSCLGraphicsImplCairo;
+#endif
+    }
+    return m_impl;
+}
+
+CSCLGraphics* CSCLGraphics::get_instance()
+{
+    static CSCLGraphics instance;
+    return &instance;
+}
+
diff --git a/scl/sclgraphics.h b/scl/sclgraphics.h
new file mode 100644 (file)
index 0000000..105dbe2
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "scltypes.h"
+#include "sclconfig.h"
+#include "sclstructs.h"
+#include "sclgraphicsbackendcallback.h"
+#include "sclgraphicsinfo.h"
+
+#ifndef __SCL_GRAPHICS_H__
+#define __SCL_GRAPHICS_H__
+
+#ifdef __cplusplus
+//SCL_BEGIN_DECLS
+#endif
+
+namespace scl
+{
+typedef struct _SclImageCachedInfo {
+    sclint nine_patch_left;
+    sclint nine_patch_right;
+    sclint nine_patch_top;
+    sclint nine_patch_bottom;
+}SclImageCachedInfo;
+
+typedef struct _SclTextCachedInfo {
+    SclSize actual_size;
+}SclTextCachedInfo;
+
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLGraphicsImpl
+{
+public:
+    CSCLGraphicsImpl() {}
+    virtual ~CSCLGraphicsImpl() {}
+
+    virtual void init() = 0;
+    virtual void fini() = 0;
+
+    friend class CSCLGraphics;
+private:
+    virtual scldrawing draw_image(sclwindow window, const scldrawctx draw_ctx, sclchar* image_path,
+                            SclImageCachedInfo *cachedinfo,
+                            sclint dest_x, sclint dest_y, sclint dest_width, sclint dest_height,
+                            sclint src_x, sclint src_y, sclint src_width, sclint src_height,
+                            sclboolean extrace_image) = 0;
+    virtual scldrawing draw_text(sclwindow window, const scldrawctx draw_ctx, const SclFontInfo& font_info, const SclColor& color,
+                           const sclchar *str, SclTextCachedInfo *cachedinfo, sclint pos_x, sclint pos_y,
+                           sclint width, sclint height, SCLLabelAlignment align,
+                           sclint padding_x, sclint padding_y, sclint inner_width, sclint inner_height) = 0;
+    virtual scldrawctx begin_paint(const sclwindow window, const sclboolean force_draw = FALSE) = 0;
+    virtual void end_paint(const sclwindow window, scldrawctx draw_ctx) = 0;
+    virtual sclimage load_image(const sclchar *image_path) = 0;
+    virtual void unload_image(sclimage image_data) = 0;
+    virtual sclfont create_font(const SclFontInfo& info) = 0;
+    virtual void destroy_font(sclfont font) = 0;
+    virtual scldrawing draw_rectangle(sclwindow window, const scldrawctx draw_ctx, scldouble pos_x, scldouble pos_y,
+                                scldouble width, scldouble height, const scldouble line_width, const SclColor& line_color,
+                                sclboolean fill, const SclColor& fill_color, scldouble radius, sclfloat alpha) = 0;
+    virtual SclSize get_image_size(sclchar* image_path) = 0;
+    virtual SclSize get_text_size(const SclFontInfo &fontinfo, const sclchar *str) = 0;
+    virtual void register_atspi_object(sclwindow window, scldrawing drawing, const sclchar* name) = 0;
+    virtual void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data) = 0;
+};
+
+class CSCLGraphics
+{
+    friend class CSCLImageProxy;
+    friend class CSCLFontProxy;
+
+private:
+    CSCLGraphics();
+public :
+    virtual ~CSCLGraphics();
+
+    static CSCLGraphics* get_instance();
+
+    void init();
+    void fini();
+
+    scldrawing draw_image(sclwindow window, const scldrawctx draw_ctx, sclchar* image_path, SclImageCachedInfo *cachedinfo, sclint dest_x, sclint dest_y,
+                    sclint dest_width = -1, sclint dest_height = -1, sclint src_x = 0, sclint src_y = 0, sclint src_width = -1, sclint src_height = -1, sclboolean extrace_image = FALSE) {
+        return get_scl_graphics_impl()->draw_image(window, draw_ctx, image_path, cachedinfo, dest_x, dest_y, dest_width, dest_height, src_x, src_y, src_width, src_height, extrace_image);
+    }
+
+    scldrawing draw_text(sclwindow window, const scldrawctx draw_ctx, const SclFontInfo& font_info, const SclColor& color,
+                   const sclchar *str, SclTextCachedInfo *cachedinfo, sclint pos_x, sclint pos_y, sclint width = 0, sclint height = 0,
+                   SCLLabelAlignment align = LABEL_ALIGN_LEFT_TOP,
+                   sclint padding_x = 0, sclint padding_y = 0, sclint inner_width = 0, sclint inner_height = 0) {
+        return get_scl_graphics_impl()->draw_text(window, draw_ctx, font_info, color, str, cachedinfo,
+            pos_x, pos_y, width, height, align, padding_x, padding_y, inner_width, inner_height);
+    }
+
+    scldrawctx begin_paint(const sclwindow window, const sclboolean force_draw = FALSE) {
+        return get_scl_graphics_impl()->begin_paint(window, force_draw);
+    }
+
+    void end_paint(const sclwindow window, scldrawctx draw_ctx) {
+        return get_scl_graphics_impl()->end_paint(window, draw_ctx);
+    }
+
+    scldrawing draw_rectangle(sclwindow window, const scldrawctx draw_ctx, scldouble pos_x, scldouble pos_y,
+                        scldouble width, scldouble height, const scldouble line_width, const SclColor& line_color,
+                        sclboolean fill, const SclColor& fill_color, scldouble radius = 0, sclfloat alpha = 1.0) {
+        return get_scl_graphics_impl()->draw_rectangle(window, draw_ctx, pos_x, pos_y, width, height, line_width, line_color, fill, fill_color, radius, alpha);
+    }
+
+    SclSize get_image_size(sclchar* image_path) {
+        return get_scl_graphics_impl()->get_image_size(image_path);
+    }
+
+    SclSize get_text_size(const SclFontInfo & fontinfo, const sclchar *str) {
+        return get_scl_graphics_impl()->get_text_size(fontinfo, str);
+    }
+
+    void register_atspi_object(sclwindow window, scldrawing drawing, const sclchar* name) {
+        return get_scl_graphics_impl()->register_atspi_object(window, drawing, name);
+    }
+
+    void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data) {
+        return get_scl_graphics_impl()->set_graphics_backend_callback(callback, data);
+    }
+
+private:
+    sclimage load_image(const sclchar *image_path) {
+        return get_scl_graphics_impl()->load_image(image_path);
+    }
+
+    void unload_image(sclimage image_data) {
+        return get_scl_graphics_impl()->unload_image(image_data);
+    }
+
+    sclfont create_font(const SclFontInfo& info) {
+        return get_scl_graphics_impl()->create_font(info);
+    }
+    void destroy_font(sclfont font) {
+        get_scl_graphics_impl()->destroy_font(font);
+    }
+
+protected :
+    CSCLGraphicsImpl* get_scl_graphics_impl();
+
+private :
+    CSCLGraphicsImpl* m_impl;
+};
+
+
+} /* End of scl namespace */
+
+#ifdef __cplusplus
+//SCL_END_DECLS
+#endif
+
+#endif //__SCL_GRAPHICS_H__
diff --git a/scl/sclgraphicsbackendcallback.h b/scl/sclgraphicsbackendcallback.h
new file mode 100644 (file)
index 0000000..93a68f2
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_GRAPHICS_BACKENDCALLBACK_H__
+#define __SCL_GRAPHICS_BACKENDCALLBACK_H__
+
+#include "sclgraphicsinfo.h"
+
+using namespace scl;
+
+//SCL_BEGIN_DECLS
+/* FIXME : Need to check the dependency cause by the next include statement */
+
+//typedef void (*scl_ui_draw_text_cb)(const char *str, int x, int y, int w, int h, int fontsize, void* user_data);
+
+struct ISCLUIGraphicsBackendCallback {
+    //virtual void on_draw_text(const char *str, int x, int y, int w, int h, int fontsize, void* user_data) { }
+    virtual void on_draw_text(const SclFontInfo& font_info, const SclColor& color, const char *str, int pos_x, int pos_y, int w, int h,
+                              SCLLabelAlignment align, int padding_x, int padding_y, int inner_width, int inner_height, void* user_data) { }
+
+    /*
+    const SclFontInfo& font_info, const SclColor& color,
+                               const sclchar *str, SclTextCachedInfo *cachedinfo, sclint pos_x, sclint pos_y, sclint width, sclint height,
+                               SCLLabelAlignment align, sclint padding_x, sclint padding_y,
+                               sclint inner_width, sclint inner_height)
+    */
+
+    virtual void on_draw_image(const char *image_path, int dest_x, int dest_y, int dest_weight, int dest_height, int src_x, int src_y, int src_width, int src_height, void* user_data) { }
+
+    virtual void on_draw_rectangle(int pos_x, int pos_y, int width, int height, bool fill, int fill_color_r, int fill_color_g, int fill_color_b, int fill_color_a, void* user_data) { }
+
+    //virtual void update_window(int x, int w, int width, int height, void* user_data) { }
+
+    //virtual void on_draw_image(const char *str, int x, int y, int w, int h, int fontsize, void* user_data) { }
+};
+
+#endif //__SCL_GRAPHICS_BACKENDCALLBACK_H__
diff --git a/scl/sclgraphicsinfo.h b/scl/sclgraphicsinfo.h
new file mode 100644 (file)
index 0000000..754d32f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "scltypes.h"
+#include "sclconfig.h"
+#include "sclstructs.h"
+
+#ifndef __SCL_GRAPHICS_INFO_H__
+#define __SCL_GRAPHICS_INFO_H__
+
+#ifdef __cplusplus
+//SCL_BEGIN_DECLS
+#endif
+
+namespace scl
+{
+#define MAX_FONT_NAME_LEN 32
+/**@brief  font information structure */
+typedef struct _SclFontInfo {
+    sclchar font_name[MAX_FONT_NAME_LEN];
+    sclshort font_size;
+    sclboolean is_italic;
+    sclboolean is_bold;
+} SclFontInfo;
+    
+typedef void * scldrawing;
+const SclColor SCLCOLOR_WHITE = {255, 255, 255, 255};
+const SclColor SCLCOLOR_GREY = {128, 128, 128, 255};
+const SclColor SCLCOLOR_BLACK = {0, 0, 0, 255};
+const SclColor SCLCOLOR_RED = {255, 0, 0, 255};
+const SclColor SCLCOLOR_BLUE = {0, 0, 255, 255};
+
+} /* End of scl namespace */
+
+#ifdef __cplusplus
+//SCL_END_DECLS
+#endif
+
+#endif //__SCL_GRAPHICS_INFO_H__
diff --git a/scl/sclgwes.cpp b/scl/sclgwes.cpp
new file mode 100644 (file)
index 0000000..00b352c
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012 - 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 "sclgwes.h"
+#include "scldebug.h"
+
+using namespace scl;
+
+CSCLGwes::CSCLGwes()
+{
+    SCL_DEBUG();
+
+    m_windows = NULL;
+    m_graphics = NULL;
+    m_events = NULL;
+}
+
+CSCLGwes::~CSCLGwes()
+{
+    SCL_DEBUG();
+}
+
+void CSCLGwes::init(sclwindow parent, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    if (m_windows == NULL) m_windows = CSCLWindows::get_instance();
+    if (m_graphics == NULL) m_graphics = CSCLGraphics::get_instance();
+    if (m_events == NULL) m_events = CSCLEvents::get_instance();
+
+    if (m_windows) {
+        m_windows->init();
+    }
+
+    if (m_graphics) {
+        m_graphics->init();
+    }
+
+    if (m_events) {
+        m_events->init();
+    }
+
+    if (m_windows) {
+        sclwindow wnd = m_windows->create_base_window(parent, width, height);
+        if (m_events) {
+            m_events->connect_window_events(wnd, SCL_EVENT_MOUSE | SCL_EVENT_EXPOSE);
+        }
+    }
+}
+
+void CSCLGwes::fini()
+{
+    SCL_DEBUG();
+
+    if (m_windows) {
+        m_windows->fini();
+        m_windows = NULL;
+    }
+    if (m_graphics) {
+        m_graphics->fini();
+        m_graphics = NULL;
+    }
+    if (m_events) {
+        m_events->fini();
+        m_events = NULL;
+    }
+}
+
+CSCLGwes* CSCLGwes::get_instance()
+{
+    static CSCLGwes instance;
+    return &instance;
+}
+
diff --git a/scl/sclgwes.h b/scl/sclgwes.h
new file mode 100644 (file)
index 0000000..6df9ceb
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "scltypes.h"
+#include "sclconfig.h"
+#include "sclwindows.h"
+#include "sclgraphics.h"
+#include "sclevents.h"
+
+#ifndef __SCL_GWES_H__
+#define __SCL_GWES_H__
+
+#ifdef __cplusplus
+//SCL_BEGIN_DECLS
+#endif
+
+namespace scl
+{
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLGwes
+{
+private:
+    CSCLGwes();
+public :
+    virtual ~CSCLGwes();
+
+    static CSCLGwes* get_instance();
+
+private:
+public:
+    void init(sclwindow parent, scl16 width, scl16 height);
+    void fini();
+
+    CSCLGraphics *m_graphics;
+    CSCLWindows *m_windows;
+    CSCLEvents *m_events;
+};
+
+} /* End of scl namespace */
+
+#ifdef __cplusplus
+//SCL_END_DECLS
+#endif
+
+#endif //__SCL_GWES_H__
diff --git a/scl/sclheaders.h b/scl/sclheaders.h
new file mode 100644 (file)
index 0000000..e9fcbcc
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 - 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 __SCLHEADERS_H__
+#define __SCLHEADERS_H__
+
+#include "sclversion.h"
+#include "scltypes.h"
+#include "sclkeydefines.h"
+#include "sclconfig.h"
+#include "sclstructs.h"
+#include "scldebug.h"
+#include "scleffect.h"
+#include "sclerroradjustment.h"
+#include "sclfeedback.h"
+#include "sclgraphics.h"
+#include "sclutils.h"
+#include "sclcontext.h"
+#include "sclactionstate.h"
+#include "sclcore.h"
+#include "sclresource.h"
+#include "sclresourcecache.h"
+#include "scleventcallback.h"
+
+#endif
diff --git a/scl/sclimageproxy.cpp b/scl/sclimageproxy.cpp
new file mode 100644 (file)
index 0000000..a2ec3e5
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012 - 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 "sclgraphics.h"
+#include "sclimageproxy.h"
+#include "scldebug.h"
+
+using namespace scl;
+
+/**
+* Constructor
+*/
+CSCLImageProxy::CSCLImageProxy()
+{
+    SCL_DEBUG();
+
+    for (int loop = 0;loop < IMAGE_PROXY_SIZE;loop++) {
+        m_image_cache_items[loop].image_data = NULL;
+        memset(m_image_cache_items[loop].image_path, 0x00, sizeof(m_image_cache_items[loop].image_path));
+    }
+}
+
+/**
+* De-constructor
+*/
+CSCLImageProxy::~CSCLImageProxy()
+{
+    SCL_DEBUG();
+    free_images();
+}
+
+CSCLImageProxy* CSCLImageProxy::get_instance()
+{
+    static CSCLImageProxy instance;
+    return &instance;
+}
+
+sclimage
+CSCLImageProxy::get_image(const sclchar* image_path)
+{
+    SCL_DEBUG();
+
+    sclimage ret = NULL;
+
+    /* FIXME : Better to use std::map for searching image cache item */
+    for (int loop = 0;loop < IMAGE_PROXY_SIZE && ret == NULL;loop++) {
+        if (strcmp(image_path, m_image_cache_items[loop].image_path) == 0) {
+            ret = m_image_cache_items[loop].image_data;
+            break;
+        }
+    }
+
+    if (ret == NULL) {
+        sclboolean isEmpty = FALSE;
+        CSCLGraphics *graphics = CSCLGraphics::get_instance();
+        ret = graphics->load_image(image_path);
+
+        if (ret) {
+            for (int loop = 0;loop < IMAGE_PROXY_SIZE && !isEmpty;loop++) {
+                if (m_image_cache_items[loop].image_data == NULL) {
+                    isEmpty = TRUE;
+                    strncpy(m_image_cache_items[loop].image_path, image_path, MAX_IMAGE_PATH_LEN);
+                    m_image_cache_items[loop].image_path[MAX_IMAGE_PATH_LEN] = '\0';
+                    m_image_cache_items[loop].image_data = ret;
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+void
+CSCLImageProxy::free_images()
+{
+    SCL_DEBUG();
+
+    for (int loop = 0;loop < IMAGE_PROXY_SIZE;loop++) {
+        if (m_image_cache_items[loop].image_data) {
+            CSCLGraphics *graphics = CSCLGraphics::get_instance();
+            graphics->unload_image(m_image_cache_items[loop].image_data);
+            m_image_cache_items[loop].image_data = NULL;
+        }
+    }
+}
diff --git a/scl/sclimageproxy.h b/scl/sclimageproxy.h
new file mode 100644 (file)
index 0000000..3050b4d
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_IMAGE_PROXY_H__
+#define __SCL_IMAGE_PROXY_H__
+
+namespace scl
+{
+class CSCLImageProxy
+{
+private:
+       CSCLImageProxy();
+public :
+    virtual ~CSCLImageProxy();
+    static CSCLImageProxy* get_instance();
+
+    sclimage get_image(const sclchar* image_path);
+    void free_images();
+
+private:
+    static const sclint MAX_IMAGE_PATH_LEN = 255;
+    typedef struct _SclImageCacheItem {
+        sclchar image_path[MAX_IMAGE_PATH_LEN + 1];
+        sclimage image_data;
+    } SclImageCacheItem;
+
+    static const sclint IMAGE_PROXY_SIZE = 1;
+    SclImageCacheItem m_image_cache_items[IMAGE_PROXY_SIZE];
+};
+} /* End of scl namespace */
+#endif
diff --git a/scl/sclintl.h b/scl/sclintl.h
new file mode 100644 (file)
index 0000000..f5202af
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2012 - 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.
+ *
+ */
+
diff --git a/scl/sclkeydefines.h b/scl/sclkeydefines.h
new file mode 100644 (file)
index 0000000..ec7a182
--- /dev/null
@@ -0,0 +1,2090 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_KEY_DEFINES_H__
+#define __SCL_KEY_DEFINES_H__
+
+/* Virtual key definitions to use in SCL */
+
+#define MVK_VoidSymbol 0xffffff
+#define MVK_BackSpace 0xff08
+#define MVK_Tab 0xff09
+#define MVK_Linefeed 0xff0a
+#define MVK_Clear 0xff0b
+#define MVK_Return 0xff0d
+#define MVK_Pause 0xff13
+#define MVK_Scroll_Lock 0xff14
+#define MVK_Sys_Req 0xff15
+#define MVK_Escape 0xff1b
+#define MVK_Delete 0xffff
+#define MVK_Multi_key 0xff20
+#define MVK_Codeinput 0xff37
+#define MVK_SingleCandidate 0xff3c
+#define MVK_MultipleCandidate 0xff3d
+#define MVK_PreviousCandidate 0xff3e
+#define MVK_Kanji 0xff21
+#define MVK_Muhenkan 0xff22
+#define MVK_Henkan_Mode 0xff23
+#define MVK_Henkan 0xff23
+#define MVK_Romaji 0xff24
+#define MVK_Hiragana 0xff25
+#define MVK_Katakana 0xff26
+#define MVK_Hiragana_Katakana 0xff27
+#define MVK_Zenkaku 0xff28
+#define MVK_Hankaku 0xff29
+#define MVK_Zenkaku_Hankaku 0xff2a
+#define MVK_Touroku 0xff2b
+#define MVK_Massyo 0xff2c
+#define MVK_Kana_Lock 0xff2d
+#define MVK_Kana_Shift 0xff2e
+#define MVK_Eisu_Shift 0xff2f
+#define MVK_Eisu_toggle 0xff30
+#define MVK_Kanji_Bangou 0xff37
+#define MVK_Zen_Koho 0xff3d
+#define MVK_Mae_Koho 0xff3e
+#define MVK_Home 0xff50
+#define MVK_Left 0xff51
+#define MVK_Up 0xff52
+#define MVK_Right 0xff53
+#define MVK_Down 0xff54
+#define MVK_Prior 0xff55
+#define MVK_Page_Up 0xff55
+#define MVK_Next 0xff56
+#define MVK_Page_Down 0xff56
+#define MVK_End 0xff57
+#define MVK_Begin 0xff58
+#define MVK_Select 0xff60
+#define MVK_Print 0xff61
+#define MVK_Execute 0xff62
+#define MVK_Insert 0xff63
+#define MVK_Undo 0xff65
+#define MVK_Redo 0xff66
+#define MVK_Menu 0xff67
+#define MVK_Find 0xff68
+#define MVK_Cancel 0xff69
+#define MVK_Help 0xff6a
+#define MVK_Break 0xff6b
+#define MVK_Mode_switch 0xff7e
+#define MVK_script_switch 0xff7e
+#define MVK_Num_Lock 0xff7f
+#define MVK_KP_Space 0xff80
+#define MVK_KP_Tab 0xff89
+#define MVK_KP_Enter 0xff8d
+#define MVK_KP_F1 0xff91
+#define MVK_KP_F2 0xff92
+#define MVK_KP_F3 0xff93
+#define MVK_KP_F4 0xff94
+#define MVK_KP_Home 0xff95
+#define MVK_KP_Left 0xff96
+#define MVK_KP_Up 0xff97
+#define MVK_KP_Right 0xff98
+#define MVK_KP_Down 0xff99
+#define MVK_KP_Prior 0xff9a
+#define MVK_KP_Page_Up 0xff9a
+#define MVK_KP_Next 0xff9b
+#define MVK_KP_Page_Down 0xff9b
+#define MVK_KP_End 0xff9c
+#define MVK_KP_Begin 0xff9d
+#define MVK_KP_Insert 0xff9e
+#define MVK_KP_Delete 0xff9f
+#define MVK_KP_Equal 0xffbd
+#define MVK_KP_Multiply 0xffaa
+#define MVK_KP_Add 0xffab
+#define MVK_KP_Separator 0xffac
+#define MVK_KP_Subtract 0xffad
+#define MVK_KP_Decimal 0xffae
+#define MVK_KP_Divide 0xffaf
+#define MVK_KP_0 0xffb0
+#define MVK_KP_1 0xffb1
+#define MVK_KP_2 0xffb2
+#define MVK_KP_3 0xffb3
+#define MVK_KP_4 0xffb4
+#define MVK_KP_5 0xffb5
+#define MVK_KP_6 0xffb6
+#define MVK_KP_7 0xffb7
+#define MVK_KP_8 0xffb8
+#define MVK_KP_9 0xffb9
+#define MVK_F1 0xffbe
+#define MVK_F2 0xffbf
+#define MVK_F3 0xffc0
+#define MVK_F4 0xffc1
+#define MVK_F5 0xffc2
+#define MVK_F6 0xffc3
+#define MVK_F7 0xffc4
+#define MVK_F8 0xffc5
+#define MVK_F9 0xffc6
+#define MVK_F10 0xffc7
+#define MVK_F11 0xffc8
+#define MVK_L1 0xffc8
+#define MVK_F12 0xffc9
+#define MVK_L2 0xffc9
+#define MVK_F13 0xffca
+#define MVK_L3 0xffca
+#define MVK_F14 0xffcb
+#define MVK_L4 0xffcb
+#define MVK_F15 0xffcc
+#define MVK_L5 0xffcc
+#define MVK_F16 0xffcd
+#define MVK_L6 0xffcd
+#define MVK_F17 0xffce
+#define MVK_L7 0xffce
+#define MVK_F18 0xffcf
+#define MVK_L8 0xffcf
+#define MVK_F19 0xffd0
+#define MVK_L9 0xffd0
+#define MVK_F20 0xffd1
+#define MVK_L10 0xffd1
+#define MVK_F21 0xffd2
+#define MVK_R1 0xffd2
+#define MVK_F22 0xffd3
+#define MVK_R2 0xffd3
+#define MVK_F23 0xffd4
+#define MVK_R3 0xffd4
+#define MVK_F24 0xffd5
+#define MVK_R4 0xffd5
+#define MVK_F25 0xffd6
+#define MVK_R5 0xffd6
+#define MVK_F26 0xffd7
+#define MVK_R6 0xffd7
+#define MVK_F27 0xffd8
+#define MVK_R7 0xffd8
+#define MVK_F28 0xffd9
+#define MVK_R8 0xffd9
+#define MVK_F29 0xffda
+#define MVK_R9 0xffda
+#define MVK_F30 0xffdb
+#define MVK_R10 0xffdb
+#define MVK_F31 0xffdc
+#define MVK_R11 0xffdc
+#define MVK_F32 0xffdd
+#define MVK_R12 0xffdd
+#define MVK_F33 0xffde
+#define MVK_R13 0xffde
+#define MVK_F34 0xffdf
+#define MVK_R14 0xffdf
+#define MVK_F35 0xffe0
+#define MVK_R15 0xffe0
+#define MVK_Shift_L 0xffe1
+#define MVK_Shift_R 0xffe2
+#define MVK_Control_L 0xffe3
+#define MVK_Control_R 0xffe4
+#define MVK_Caps_Lock 0xffe5
+#define MVK_Shift_Lock 0xffe6
+#define MVK_Meta_L 0xffe7
+#define MVK_Meta_R 0xffe8
+#define MVK_Alt_L 0xffe9
+#define MVK_Alt_R 0xffea
+#define MVK_Super_L 0xffeb
+#define MVK_Super_R 0xffec
+#define MVK_Hyper_L 0xffed
+#define MVK_Hyper_R 0xffee
+#define MVK_ISO_Lock 0xfe01
+#define MVK_ISO_Level2_Latch 0xfe02
+#define MVK_ISO_Level3_Shift 0xfe03
+#define MVK_ISO_Level3_Latch 0xfe04
+#define MVK_ISO_Level3_Lock 0xfe05
+#define MVK_ISO_Level5_Shift 0xfe11
+#define MVK_ISO_Level5_Latch 0xfe12
+#define MVK_ISO_Level5_Lock 0xfe13
+#define MVK_ISO_Group_Shift 0xff7e
+#define MVK_ISO_Group_Latch 0xfe06
+#define MVK_ISO_Group_Lock 0xfe07
+#define MVK_ISO_Next_Group 0xfe08
+#define MVK_ISO_Next_Group_Lock 0xfe09
+#define MVK_ISO_Prev_Group 0xfe0a
+#define MVK_ISO_Prev_Group_Lock 0xfe0b
+#define MVK_ISO_First_Group 0xfe0c
+#define MVK_ISO_First_Group_Lock 0xfe0d
+#define MVK_ISO_Last_Group 0xfe0e
+#define MVK_ISO_Last_Group_Lock 0xfe0f
+#define MVK_ISO_Left_Tab 0xfe20
+#define MVK_ISO_Move_Line_Up 0xfe21
+#define MVK_ISO_Move_Line_Down 0xfe22
+#define MVK_ISO_Partial_Line_Up 0xfe23
+#define MVK_ISO_Partial_Line_Down 0xfe24
+#define MVK_ISO_Partial_Space_Left 0xfe25
+#define MVK_ISO_Partial_Space_Right 0xfe26
+#define MVK_ISO_Set_Margin_Left 0xfe27
+#define MVK_ISO_Set_Margin_Right 0xfe28
+#define MVK_ISO_Release_Margin_Left 0xfe29
+#define MVK_ISO_Release_Margin_Right 0xfe2a
+#define MVK_ISO_Release_Both_Margins 0xfe2b
+#define MVK_ISO_Fast_Cursor_Left 0xfe2c
+#define MVK_ISO_Fast_Cursor_Right 0xfe2d
+#define MVK_ISO_Fast_Cursor_Up 0xfe2e
+#define MVK_ISO_Fast_Cursor_Down 0xfe2f
+#define MVK_ISO_Continuous_Underline 0xfe30
+#define MVK_ISO_Discontinuous_Underline 0xfe31
+#define MVK_ISO_Emphasize 0xfe32
+#define MVK_ISO_Center_Object 0xfe33
+#define MVK_ISO_Enter 0xfe34
+#define MVK_dead_grave 0xfe50
+#define MVK_dead_acute 0xfe51
+#define MVK_dead_circumflex 0xfe52
+#define MVK_dead_tilde 0xfe53
+#define MVK_dead_perispomeni 0xfe53
+#define MVK_dead_macron 0xfe54
+#define MVK_dead_breve 0xfe55
+#define MVK_dead_abovedot 0xfe56
+#define MVK_dead_diaeresis 0xfe57
+#define MVK_dead_abovering 0xfe58
+#define MVK_dead_doubleacute 0xfe59
+#define MVK_dead_caron 0xfe5a
+#define MVK_dead_cedilla 0xfe5b
+#define MVK_dead_ogonek 0xfe5c
+#define MVK_dead_iota 0xfe5d
+#define MVK_dead_voiced_sound 0xfe5e
+#define MVK_dead_semivoiced_sound 0xfe5f
+#define MVK_dead_belowdot 0xfe60
+#define MVK_dead_hook 0xfe61
+#define MVK_dead_horn 0xfe62
+#define MVK_dead_stroke 0xfe63
+#define MVK_dead_abovecomma 0xfe64
+#define MVK_dead_psili 0xfe64
+#define MVK_dead_abovereversedcomma 0xfe65
+#define MVK_dead_dasia 0xfe65
+#define MVK_First_Virtual_Screen 0xfed0
+#define MVK_Prev_Virtual_Screen 0xfed1
+#define MVK_Next_Virtual_Screen 0xfed2
+#define MVK_Last_Virtual_Screen 0xfed4
+#define MVK_Terminate_Server 0xfed5
+#define MVK_AccessX_Enable 0xfe70
+#define MVK_AccessX_Feedback_Enable 0xfe71
+#define MVK_RepeatKeys_Enable 0xfe72
+#define MVK_SlowKeys_Enable 0xfe73
+#define MVK_BounceKeys_Enable 0xfe74
+#define MVK_StickyKeys_Enable 0xfe75
+#define MVK_MouseKeys_Enable 0xfe76
+#define MVK_MouseKeys_Accel_Enable 0xfe77
+#define MVK_Overlay1_Enable 0xfe78
+#define MVK_Overlay2_Enable 0xfe79
+#define MVK_AudibleBell_Enable 0xfe7a
+#define MVK_Pointer_Left 0xfee0
+#define MVK_Pointer_Right 0xfee1
+#define MVK_Pointer_Up 0xfee2
+#define MVK_Pointer_Down 0xfee3
+#define MVK_Pointer_UpLeft 0xfee4
+#define MVK_Pointer_UpRight 0xfee5
+#define MVK_Pointer_DownLeft 0xfee6
+#define MVK_Pointer_DownRight 0xfee7
+#define MVK_Pointer_Button_Dflt 0xfee8
+#define MVK_Pointer_Button1 0xfee9
+#define MVK_Pointer_Button2 0xfeea
+#define MVK_Pointer_Button3 0xfeeb
+#define MVK_Pointer_Button4 0xfeec
+#define MVK_Pointer_Button5 0xfeed
+#define MVK_Pointer_DblClick_Dflt 0xfeee
+#define MVK_Pointer_DblClick1 0xfeef
+#define MVK_Pointer_DblClick2 0xfef0
+#define MVK_Pointer_DblClick3 0xfef1
+#define MVK_Pointer_DblClick4 0xfef2
+#define MVK_Pointer_DblClick5 0xfef3
+#define MVK_Pointer_Drag_Dflt 0xfef4
+#define MVK_Pointer_Drag1 0xfef5
+#define MVK_Pointer_Drag2 0xfef6
+#define MVK_Pointer_Drag3 0xfef7
+#define MVK_Pointer_Drag4 0xfef8
+#define MVK_Pointer_Drag5 0xfefd
+#define MVK_Pointer_EnableKeys 0xfef9
+#define MVK_Pointer_Accelerate 0xfefa
+#define MVK_Pointer_DfltBtnNext 0xfefb
+#define MVK_Pointer_DfltBtnPrev 0xfefc
+#define MVK_3270_Duplicate 0xfd01
+#define MVK_3270_FieldMark 0xfd02
+#define MVK_3270_Right2 0xfd03
+#define MVK_3270_Left2 0xfd04
+#define MVK_3270_BackTab 0xfd05
+#define MVK_3270_EraseEOF 0xfd06
+#define MVK_3270_EraseInput 0xfd07
+#define MVK_3270_Reset 0xfd08
+#define MVK_3270_Quit 0xfd09
+#define MVK_3270_PA1 0xfd0a
+#define MVK_3270_PA2 0xfd0b
+#define MVK_3270_PA3 0xfd0c
+#define MVK_3270_Test 0xfd0d
+#define MVK_3270_Attn 0xfd0e
+#define MVK_3270_CursorBlink 0xfd0f
+#define MVK_3270_AltCursor 0xfd10
+#define MVK_3270_KeyClick 0xfd11
+#define MVK_3270_Jump 0xfd12
+#define MVK_3270_Ident 0xfd13
+#define MVK_3270_Rule 0xfd14
+#define MVK_3270_Copy 0xfd15
+#define MVK_3270_Play 0xfd16
+#define MVK_3270_Setup 0xfd17
+#define MVK_3270_Record 0xfd18
+#define MVK_3270_ChangeScreen 0xfd19
+#define MVK_3270_DeleteWord 0xfd1a
+#define MVK_3270_ExSelect 0xfd1b
+#define MVK_3270_CursorSelect 0xfd1c
+#define MVK_3270_PrintScreen 0xfd1d
+#define MVK_3270_Enter 0xfd1e
+#define MVK_space 0x020
+#define MVK_exclam 0x021
+#define MVK_quotedbl 0x022
+#define MVK_numbersign 0x023
+#define MVK_dollar 0x024
+#define MVK_percent 0x025
+#define MVK_ampersand 0x026
+#define MVK_apostrophe 0x027
+#define MVK_quoteright 0x027
+#define MVK_parenleft 0x028
+#define MVK_parenright 0x029
+#define MVK_asterisk 0x02a
+#define MVK_plus 0x02b
+#define MVK_comma 0x02c
+#define MVK_minus 0x02d
+#define MVK_period 0x02e
+#define MVK_slash 0x02f
+#define MVK_0 0x030
+#define MVK_1 0x031
+#define MVK_2 0x032
+#define MVK_3 0x033
+#define MVK_4 0x034
+#define MVK_5 0x035
+#define MVK_6 0x036
+#define MVK_7 0x037
+#define MVK_8 0x038
+#define MVK_9 0x039
+#define MVK_colon 0x03a
+#define MVK_semicolon 0x03b
+#define MVK_less 0x03c
+#define MVK_equal 0x03d
+#define MVK_greater 0x03e
+#define MVK_question 0x03f
+#define MVK_at 0x040
+#define MVK_A 0x041
+#define MVK_B 0x042
+#define MVK_C 0x043
+#define MVK_D 0x044
+#define MVK_E 0x045
+#define MVK_F 0x046
+#define MVK_G 0x047
+#define MVK_H 0x048
+#define MVK_I 0x049
+#define MVK_J 0x04a
+#define MVK_K 0x04b
+#define MVK_L 0x04c
+#define MVK_M 0x04d
+#define MVK_N 0x04e
+#define MVK_O 0x04f
+#define MVK_P 0x050
+#define MVK_Q 0x051
+#define MVK_R 0x052
+#define MVK_S 0x053
+#define MVK_T 0x054
+#define MVK_U 0x055
+#define MVK_V 0x056
+#define MVK_W 0x057
+#define MVK_X 0x058
+#define MVK_Y 0x059
+#define MVK_Z 0x05a
+#define MVK_bracketleft 0x05b
+#define MVK_backslash 0x05c
+#define MVK_bracketright 0x05d
+#define MVK_asciicircum 0x05e
+#define MVK_underscore 0x05f
+#define MVK_grave 0x060
+#define MVK_quoteleft 0x060
+#define MVK_a 0x061
+#define MVK_b 0x062
+#define MVK_c 0x063
+#define MVK_d 0x064
+#define MVK_e 0x065
+#define MVK_f 0x066
+#define MVK_g 0x067
+#define MVK_h 0x068
+#define MVK_i 0x069
+#define MVK_j 0x06a
+#define MVK_k 0x06b
+#define MVK_l 0x06c
+#define MVK_m 0x06d
+#define MVK_n 0x06e
+#define MVK_o 0x06f
+#define MVK_p 0x070
+#define MVK_q 0x071
+#define MVK_r 0x072
+#define MVK_s 0x073
+#define MVK_t 0x074
+#define MVK_u 0x075
+#define MVK_v 0x076
+#define MVK_w 0x077
+#define MVK_x 0x078
+#define MVK_y 0x079
+#define MVK_z 0x07a
+#define MVK_braceleft 0x07b
+#define MVK_bar 0x07c
+#define MVK_braceright 0x07d
+#define MVK_asciitilde 0x07e
+#define MVK_nobreakspace 0x0a0
+#define MVK_exclamdown 0x0a1
+#define MVK_cent 0x0a2
+#define MVK_sterling 0x0a3
+#define MVK_currency 0x0a4
+#define MVK_yen 0x0a5
+#define MVK_brokenbar 0x0a6
+#define MVK_section 0x0a7
+#define MVK_diaeresis 0x0a8
+#define MVK_copyright 0x0a9
+#define MVK_ordfeminine 0x0aa
+#define MVK_guillemotleft 0x0ab
+#define MVK_notsign 0x0ac
+#define MVK_hyphen 0x0ad
+#define MVK_registered 0x0ae
+#define MVK_macron 0x0af
+#define MVK_degree 0x0b0
+#define MVK_plusminus 0x0b1
+#define MVK_twosuperior 0x0b2
+#define MVK_threesuperior 0x0b3
+#define MVK_acute 0x0b4
+#define MVK_mu 0x0b5
+#define MVK_paragraph 0x0b6
+#define MVK_periodcentered 0x0b7
+#define MVK_cedilla 0x0b8
+#define MVK_onesuperior 0x0b9
+#define MVK_masculine 0x0ba
+#define MVK_guillemotright 0x0bb
+#define MVK_onequarter 0x0bc
+#define MVK_onehalf 0x0bd
+#define MVK_threequarters 0x0be
+#define MVK_questiondown 0x0bf
+#define MVK_Agrave 0x0c0
+#define MVK_Aacute 0x0c1
+#define MVK_Acircumflex 0x0c2
+#define MVK_Atilde 0x0c3
+#define MVK_Adiaeresis 0x0c4
+#define MVK_Aring 0x0c5
+#define MVK_AE 0x0c6
+#define MVK_Ccedilla 0x0c7
+#define MVK_Egrave 0x0c8
+#define MVK_Eacute 0x0c9
+#define MVK_Ecircumflex 0x0ca
+#define MVK_Ediaeresis 0x0cb
+#define MVK_Igrave 0x0cc
+#define MVK_Iacute 0x0cd
+#define MVK_Icircumflex 0x0ce
+#define MVK_Idiaeresis 0x0cf
+#define MVK_ETH 0x0d0
+#define MVK_Eth 0x0d0
+#define MVK_Ntilde 0x0d1
+#define MVK_Ograve 0x0d2
+#define MVK_Oacute 0x0d3
+#define MVK_Ocircumflex 0x0d4
+#define MVK_Otilde 0x0d5
+#define MVK_Odiaeresis 0x0d6
+#define MVK_multiply 0x0d7
+#define MVK_Oslash 0x0d8
+#define MVK_Ooblique 0x0d8
+#define MVK_Ugrave 0x0d9
+#define MVK_Uacute 0x0da
+#define MVK_Ucircumflex 0x0db
+#define MVK_Udiaeresis 0x0dc
+#define MVK_Yacute 0x0dd
+#define MVK_THORN 0x0de
+#define MVK_Thorn 0x0de
+#define MVK_ssharp 0x0df
+#define MVK_agrave 0x0e0
+#define MVK_aacute 0x0e1
+#define MVK_acircumflex 0x0e2
+#define MVK_atilde 0x0e3
+#define MVK_adiaeresis 0x0e4
+#define MVK_aring 0x0e5
+#define MVK_ae 0x0e6
+#define MVK_ccedilla 0x0e7
+#define MVK_egrave 0x0e8
+#define MVK_eacute 0x0e9
+#define MVK_ecircumflex 0x0ea
+#define MVK_ediaeresis 0x0eb
+#define MVK_igrave 0x0ec
+#define MVK_iacute 0x0ed
+#define MVK_icircumflex 0x0ee
+#define MVK_idiaeresis 0x0ef
+#define MVK_eth 0x0f0
+#define MVK_ntilde 0x0f1
+#define MVK_ograve 0x0f2
+#define MVK_oacute 0x0f3
+#define MVK_ocircumflex 0x0f4
+#define MVK_otilde 0x0f5
+#define MVK_odiaeresis 0x0f6
+#define MVK_division 0x0f7
+#define MVK_oslash 0x0f8
+#define MVK_ooblique 0x0f8
+#define MVK_ugrave 0x0f9
+#define MVK_uacute 0x0fa
+#define MVK_ucircumflex 0x0fb
+#define MVK_udiaeresis 0x0fc
+#define MVK_yacute 0x0fd
+#define MVK_thorn 0x0fe
+#define MVK_ydiaeresis 0x0ff
+#define MVK_Aogonek 0x1a1
+#define MVK_breve 0x1a2
+#define MVK_Lstroke 0x1a3
+#define MVK_Lcaron 0x1a5
+#define MVK_Sacute 0x1a6
+#define MVK_Scaron 0x1a9
+#define MVK_Scedilla 0x1aa
+#define MVK_Tcaron 0x1ab
+#define MVK_Zacute 0x1ac
+#define MVK_Zcaron 0x1ae
+#define MVK_Zabovedot 0x1af
+#define MVK_aogonek 0x1b1
+#define MVK_ogonek 0x1b2
+#define MVK_lstroke 0x1b3
+#define MVK_lcaron 0x1b5
+#define MVK_sacute 0x1b6
+#define MVK_caron 0x1b7
+#define MVK_scaron 0x1b9
+#define MVK_scedilla 0x1ba
+#define MVK_tcaron 0x1bb
+#define MVK_zacute 0x1bc
+#define MVK_doubleacute 0x1bd
+#define MVK_zcaron 0x1be
+#define MVK_zabovedot 0x1bf
+#define MVK_Racute 0x1c0
+#define MVK_Abreve 0x1c3
+#define MVK_Lacute 0x1c5
+#define MVK_Cacute 0x1c6
+#define MVK_Ccaron 0x1c8
+#define MVK_Eogonek 0x1ca
+#define MVK_Ecaron 0x1cc
+#define MVK_Dcaron 0x1cf
+#define MVK_Dstroke 0x1d0
+#define MVK_Nacute 0x1d1
+#define MVK_Ncaron 0x1d2
+#define MVK_Odoubleacute 0x1d5
+#define MVK_Rcaron 0x1d8
+#define MVK_Uring 0x1d9
+#define MVK_Udoubleacute 0x1db
+#define MVK_Tcedilla 0x1de
+#define MVK_racute 0x1e0
+#define MVK_abreve 0x1e3
+#define MVK_lacute 0x1e5
+#define MVK_cacute 0x1e6
+#define MVK_ccaron 0x1e8
+#define MVK_eogonek 0x1ea
+#define MVK_ecaron 0x1ec
+#define MVK_dcaron 0x1ef
+#define MVK_dstroke 0x1f0
+#define MVK_nacute 0x1f1
+#define MVK_ncaron 0x1f2
+#define MVK_odoubleacute 0x1f5
+#define MVK_udoubleacute 0x1fb
+#define MVK_rcaron 0x1f8
+#define MVK_uring 0x1f9
+#define MVK_tcedilla 0x1fe
+#define MVK_abovedot 0x1ff
+#define MVK_Hstroke 0x2a1
+#define MVK_Hcircumflex 0x2a6
+#define MVK_Iabovedot 0x2a9
+#define MVK_Gbreve 0x2ab
+#define MVK_Jcircumflex 0x2ac
+#define MVK_hstroke 0x2b1
+#define MVK_hcircumflex 0x2b6
+#define MVK_idotless 0x2b9
+#define MVK_gbreve 0x2bb
+#define MVK_jcircumflex 0x2bc
+#define MVK_Cabovedot 0x2c5
+#define MVK_Ccircumflex 0x2c6
+#define MVK_Gabovedot 0x2d5
+#define MVK_Gcircumflex 0x2d8
+#define MVK_Ubreve 0x2dd
+#define MVK_Scircumflex 0x2de
+#define MVK_cabovedot 0x2e5
+#define MVK_ccircumflex 0x2e6
+#define MVK_gabovedot 0x2f5
+#define MVK_gcircumflex 0x2f8
+#define MVK_ubreve 0x2fd
+#define MVK_scircumflex 0x2fe
+#define MVK_kra 0x3a2
+#define MVK_kappa 0x3a2
+#define MVK_Rcedilla 0x3a3
+#define MVK_Itilde 0x3a5
+#define MVK_Lcedilla 0x3a6
+#define MVK_Emacron 0x3aa
+#define MVK_Gcedilla 0x3ab
+#define MVK_Tslash 0x3ac
+#define MVK_rcedilla 0x3b3
+#define MVK_itilde 0x3b5
+#define MVK_lcedilla 0x3b6
+#define MVK_emacron 0x3ba
+#define MVK_gcedilla 0x3bb
+#define MVK_tslash 0x3bc
+#define MVK_ENG 0x3bd
+#define MVK_eng 0x3bf
+#define MVK_Amacron 0x3c0
+#define MVK_Iogonek 0x3c7
+#define MVK_Eabovedot 0x3cc
+#define MVK_Imacron 0x3cf
+#define MVK_Ncedilla 0x3d1
+#define MVK_Omacron 0x3d2
+#define MVK_Kcedilla 0x3d3
+#define MVK_Uogonek 0x3d9
+#define MVK_Utilde 0x3dd
+#define MVK_Umacron 0x3de
+#define MVK_amacron 0x3e0
+#define MVK_iogonek 0x3e7
+#define MVK_eabovedot 0x3ec
+#define MVK_imacron 0x3ef
+#define MVK_ncedilla 0x3f1
+#define MVK_omacron 0x3f2
+#define MVK_kcedilla 0x3f3
+#define MVK_uogonek 0x3f9
+#define MVK_utilde 0x3fd
+#define MVK_umacron 0x3fe
+#define MVK_Babovedot 0x1e02
+#define MVK_babovedot 0x1e03
+#define MVK_Dabovedot 0x1e0a
+#define MVK_Wgrave 0x1e80
+#define MVK_Wacute 0x1e82
+#define MVK_dabovedot 0x1e0b
+#define MVK_Ygrave 0x1ef2
+#define MVK_Fabovedot 0x1e1e
+#define MVK_fabovedot 0x1e1f
+#define MVK_Mabovedot 0x1e40
+#define MVK_mabovedot 0x1e41
+#define MVK_Pabovedot 0x1e56
+#define MVK_wgrave 0x1e81
+#define MVK_pabovedot 0x1e57
+#define MVK_wacute 0x1e83
+#define MVK_Sabovedot 0x1e60
+#define MVK_ygrave 0x1ef3
+#define MVK_Wdiaeresis 0x1e84
+#define MVK_wdiaeresis 0x1e85
+#define MVK_sabovedot 0x1e61
+#define MVK_Wcircumflex 0x174
+#define MVK_Tabovedot 0x1e6a
+#define MVK_Ycircumflex 0x176
+#define MVK_wcircumflex 0x175
+#define MVK_tabovedot 0x1e6b
+#define MVK_ycircumflex 0x177
+#define MVK_OE 0x13bc
+#define MVK_oe 0x13bd
+#define MVK_Ydiaeresis 0x13be
+#define MVK_overline 0x47e
+#define MVK_kana_fullstop 0x4a1
+#define MVK_kana_openingbracket 0x4a2
+#define MVK_kana_closingbracket 0x4a3
+#define MVK_kana_comma 0x4a4
+#define MVK_kana_conjunctive 0x4a5
+#define MVK_kana_middledot 0x4a5
+#define MVK_kana_WO 0x4a6
+#define MVK_kana_a 0x4a7
+#define MVK_kana_i 0x4a8
+#define MVK_kana_u 0x4a9
+#define MVK_kana_e 0x4aa
+#define MVK_kana_o 0x4ab
+#define MVK_kana_ya 0x4ac
+#define MVK_kana_yu 0x4ad
+#define MVK_kana_yo 0x4ae
+#define MVK_kana_tsu 0x4af
+#define MVK_kana_tu 0x4af
+#define MVK_prolongedsound 0x4b0
+#define MVK_kana_A 0x4b1
+#define MVK_kana_I 0x4b2
+#define MVK_kana_U 0x4b3
+#define MVK_kana_E 0x4b4
+#define MVK_kana_O 0x4b5
+#define MVK_kana_KA 0x4b6
+#define MVK_kana_KI 0x4b7
+#define MVK_kana_KU 0x4b8
+#define MVK_kana_KE 0x4b9
+#define MVK_kana_KO 0x4ba
+#define MVK_kana_SA 0x4bb
+#define MVK_kana_SHI 0x4bc
+#define MVK_kana_SU 0x4bd
+#define MVK_kana_SE 0x4be
+#define MVK_kana_SO 0x4bf
+#define MVK_kana_TA 0x4c0
+#define MVK_kana_CHI 0x4c1
+#define MVK_kana_TI 0x4c1
+#define MVK_kana_TSU 0x4c2
+#define MVK_kana_TU 0x4c2
+#define MVK_kana_TE 0x4c3
+#define MVK_kana_TO 0x4c4
+#define MVK_kana_NA 0x4c5
+#define MVK_kana_NI 0x4c6
+#define MVK_kana_NU 0x4c7
+#define MVK_kana_NE 0x4c8
+#define MVK_kana_NO 0x4c9
+#define MVK_kana_HA 0x4ca
+#define MVK_kana_HI 0x4cb
+#define MVK_kana_FU 0x4cc
+#define MVK_kana_HU 0x4cc
+#define MVK_kana_HE 0x4cd
+#define MVK_kana_HO 0x4ce
+#define MVK_kana_MA 0x4cf
+#define MVK_kana_MI 0x4d0
+#define MVK_kana_MU 0x4d1
+#define MVK_kana_ME 0x4d2
+#define MVK_kana_MO 0x4d3
+#define MVK_kana_YA 0x4d4
+#define MVK_kana_YU 0x4d5
+#define MVK_kana_YO 0x4d6
+#define MVK_kana_RA 0x4d7
+#define MVK_kana_RI 0x4d8
+#define MVK_kana_RU 0x4d9
+#define MVK_kana_RE 0x4da
+#define MVK_kana_RO 0x4db
+#define MVK_kana_WA 0x4dc
+#define MVK_kana_N 0x4dd
+#define MVK_voicedsound 0x4de
+#define MVK_semivoicedsound 0x4df
+#define MVK_kana_switch 0xff7e
+#define MVK_Farsi_0 0x6f0
+#define MVK_Farsi_1 0x6f1
+#define MVK_Farsi_2 0x6f2
+#define MVK_Farsi_3 0x6f3
+#define MVK_Farsi_4 0x6f4
+#define MVK_Farsi_5 0x6f5
+#define MVK_Farsi_6 0x6f6
+#define MVK_Farsi_7 0x6f7
+#define MVK_Farsi_8 0x6f8
+#define MVK_Farsi_9 0x6f9
+#define MVK_Arabic_percent 0x66a
+#define MVK_Arabic_superscript_alef 0x670
+#define MVK_Arabic_tteh 0x679
+#define MVK_Arabic_peh 0x67e
+#define MVK_Arabic_tcheh 0x686
+#define MVK_Arabic_ddal 0x688
+#define MVK_Arabic_rreh 0x691
+#define MVK_Arabic_comma 0x60C
+#define MVK_Arabic_fullstop 0x6d4
+#define MVK_Arabic_0 0x660
+#define MVK_Arabic_1 0x661
+#define MVK_Arabic_2 0x662
+#define MVK_Arabic_3 0x663
+#define MVK_Arabic_4 0x664
+#define MVK_Arabic_5 0x665
+#define MVK_Arabic_6 0x666
+#define MVK_Arabic_7 0x667
+#define MVK_Arabic_8 0x668
+#define MVK_Arabic_9 0x669
+#define MVK_Arabic_semicolon 0x61B
+#define MVK_Arabic_question_mark 0x61F
+#define MVK_Arabic_hamza 0x621
+#define MVK_Arabic_maddaonalef 0x622
+#define MVK_Arabic_hamzaonalef 0x623
+#define MVK_Arabic_hamzaonwaw 0x624
+#define MVK_Arabic_hamzaunderalef 0x625
+#define MVK_Arabic_hamzaonyeh 0x626
+#define MVK_Arabic_alef 0x627
+#define MVK_Arabic_beh 0x628
+#define MVK_Arabic_tehmarbuta 0x629
+#define MVK_Arabic_teh 0x62A
+#define MVK_Arabic_theh 0x62B
+#define MVK_Arabic_jeem 0x62C
+#define MVK_Arabic_hah 0x62D
+#define MVK_Arabic_khah 0x62E
+#define MVK_Arabic_dal 0x62F
+#define MVK_Arabic_thal 0x630
+#define MVK_Arabic_reh 0x631
+#define MVK_Arabic_zain 0x632
+#define MVK_Arabic_seen 0x633
+#define MVK_Arabic_sheen 0x634
+#define MVK_Arabic_sad 0x635
+#define MVK_Arabic_dad 0x636
+#define MVK_Arabic_tah 0x637
+#define MVK_Arabic_zah 0x638
+#define MVK_Arabic_ain 0x639
+#define MVK_Arabic_ghain 0x63A
+#define MVK_Arabic_tatweel 0x640
+#define MVK_Arabic_feh 0x641
+#define MVK_Arabic_qaf 0x642
+#define MVK_Arabic_kaf 0x643
+#define MVK_Arabic_lam 0x644
+#define MVK_Arabic_meem 0x645
+#define MVK_Arabic_noon 0x646
+#define MVK_Arabic_ha 0x647
+#define MVK_Arabic_heh 0x647
+#define MVK_Arabic_waw 0x648
+#define MVK_Arabic_alefmaksura 0x649
+#define MVK_Arabic_yeh 0x64A
+#define MVK_Arabic_fathatan 0x64B
+#define MVK_Arabic_dammatan 0x64C
+#define MVK_Arabic_kasratan 0x64D
+#define MVK_Arabic_fatha 0x64E
+#define MVK_Arabic_damma 0x64F
+#define MVK_Arabic_kasra 0x650
+#define MVK_Arabic_shadda 0x651
+#define MVK_Arabic_sukun 0x652
+#define MVK_Arabic_madda_above 0x653
+#define MVK_Arabic_hamza_above 0x654
+#define MVK_Arabic_hamza_below 0x655
+#define MVK_Arabic_jeh 0x698
+#define MVK_Arabic_veh 0x6a4
+#define MVK_Arabic_keheh 0x6a9
+#define MVK_Arabic_gaf 0x6af
+#define MVK_Arabic_noon_ghunna 0x6ba
+#define MVK_Arabic_heh_doachashmee 0x6be
+#define MVK_Farsi_yeh 0x6cc
+#define MVK_Arabic_farsi_yeh 0x6cc
+#define MVK_Arabic_yeh_barree 0x6d2
+#define MVK_Arabic_ae 0x6d5
+#define MVK_Arabic_heh_goal 0x6c1
+#define MVK_Arabic_ligature_lam_with_alef_with_hamza_below_isolated_form 0Xfef9
+#define MVK_Arabic_ligature_lam_with_alef_with_hamza_above_isolated_form 0Xfef7
+#define MVK_Arabic_ligature_lam_with_alef_isolated_form 0Xfefb
+#define MVK_Arabic_ligature_lam_with_alef_with_madda_above_isolated_form 0Xfef5
+#define MVK_Arabic_switch 0xff7e
+#define MVK_Cyrillic_GHE_bar 0x492
+#define MVK_Cyrillic_ghe_bar 0x493
+#define MVK_Cyrillic_ZHE_descender 0x496
+#define MVK_Cyrillic_zhe_descender 0x497
+#define MVK_Cyrillic_KA_descender 0x49a
+#define MVK_Cyrillic_ka_descender 0x49b
+#define MVK_Cyrillic_KA_vertstroke 0x49c
+#define MVK_Cyrillic_ka_vertstroke 0x49d
+#define MVK_Cyrillic_EN_descender 0x4a2
+#define MVK_Cyrillic_en_descender 0x4a3
+#define MVK_Cyrillic_U_straight 0x4ae
+#define MVK_Cyrillic_u_straight 0x4af
+#define MVK_Cyrillic_U_straight_bar 0x4b0
+#define MVK_Cyrillic_u_straight_bar 0x4b1
+#define MVK_Cyrillic_HA_descender 0x4b2
+#define MVK_Cyrillic_ha_descender 0x4b3
+#define MVK_Cyrillic_CHE_descender 0x4b6
+#define MVK_Cyrillic_che_descender 0x4b7
+#define MVK_Cyrillic_CHE_vertstroke 0x4b8
+#define MVK_Cyrillic_che_vertstroke 0x4b9
+#define MVK_Cyrillic_SHHA 0x4ba
+#define MVK_Cyrillic_shha 0x4bb
+#define MVK_Cyrillic_SCHWA 0x4d8
+#define MVK_Cyrillic_schwa 0x4d9
+#define MVK_Cyrillic_I_macron 0x4e2
+#define MVK_Cyrillic_i_macron 0x4e3
+#define MVK_Cyrillic_O_bar 0x4e8
+#define MVK_Cyrillic_o_bar 0x4e9
+#define MVK_Cyrillic_U_macron 0x4ee
+#define MVK_Cyrillic_u_macron 0x4ef
+#define MVK_Serbian_dje 0x6a1
+#define MVK_Macedonia_gje 0x6a2
+#define MVK_Cyrillic_io 0x6a3
+#define MVK_Ukrainian_ie 0x6a4
+#define MVK_Ukranian_je 0x6a4
+#define MVK_Macedonia_dse 0x6a5
+#define MVK_Ukrainian_i 0x6a6
+#define MVK_Ukranian_i 0x6a6
+#define MVK_Ukrainian_yi 0x6a7
+#define MVK_Ukranian_yi 0x6a7
+#define MVK_Cyrillic_je 0x6a8
+#define MVK_Serbian_je 0x6a8
+#define MVK_Cyrillic_lje 0x6a9
+#define MVK_Serbian_lje 0x6a9
+#define MVK_Cyrillic_nje 0x6aa
+#define MVK_Serbian_nje 0x6aa
+#define MVK_Serbian_tshe 0x6ab
+#define MVK_Macedonia_kje 0x6ac
+#define MVK_Ukrainian_ghe_with_upturn 0x6ad
+#define MVK_Byelorussian_shortu 0x6ae
+#define MVK_Cyrillic_dzhe 0x6af
+#define MVK_Serbian_dze 0x6af
+#define MVK_numerosign 0x6b0
+#define MVK_Serbian_DJE 0x6b1
+#define MVK_Macedonia_GJE 0x6b2
+#define MVK_Cyrillic_IO 0x6b3
+#define MVK_Ukrainian_IE 0x6b4
+#define MVK_Ukranian_JE 0x6b4
+#define MVK_Macedonia_DSE 0x6b5
+#define MVK_Ukrainian_I 0x6b6
+#define MVK_Ukranian_I 0x6b6
+#define MVK_Ukrainian_YI 0x6b7
+#define MVK_Ukranian_YI 0x6b7
+#define MVK_Cyrillic_JE 0x6b8
+#define MVK_Serbian_JE 0x6b8
+#define MVK_Cyrillic_LJE 0x6b9
+#define MVK_Serbian_LJE 0x6b9
+#define MVK_Cyrillic_NJE 0x6ba
+#define MVK_Serbian_NJE 0x6ba
+#define MVK_Serbian_TSHE 0x6bb
+#define MVK_Macedonia_KJE 0x6bc
+#define MVK_Ukrainian_GHE_WITH_UPTURN 0x6bd
+#define MVK_Byelorussian_SHORTU 0x6be
+#define MVK_Cyrillic_DZHE 0x6bf
+#define MVK_Serbian_DZE 0x6bf
+#define MVK_Cyrillic_yu 0x6c0
+#define MVK_Cyrillic_a 0x6c1
+#define MVK_Cyrillic_be 0x6c2
+#define MVK_Cyrillic_tse 0x6c3
+#define MVK_Cyrillic_de 0x6c4
+#define MVK_Cyrillic_ie 0x6c5
+#define MVK_Cyrillic_ef 0x6c6
+#define MVK_Cyrillic_ghe 0x6c7
+#define MVK_Cyrillic_ha 0x6c8
+#define MVK_Cyrillic_i 0x6c9
+#define MVK_Cyrillic_shorti 0x6ca
+#define MVK_Cyrillic_ka 0x6cb
+#define MVK_Cyrillic_el 0x6cc
+#define MVK_Cyrillic_em 0x6cd
+#define MVK_Cyrillic_en 0x6ce
+#define MVK_Cyrillic_o 0x6cf
+#define MVK_Cyrillic_pe 0x6d0
+#define MVK_Cyrillic_ya 0x6d1
+#define MVK_Cyrillic_er 0x6d2
+#define MVK_Cyrillic_es 0x6d3
+#define MVK_Cyrillic_te 0x6d4
+#define MVK_Cyrillic_u 0x6d5
+#define MVK_Cyrillic_zhe 0x6d6
+#define MVK_Cyrillic_ve 0x6d7
+#define MVK_Cyrillic_softsign 0x6d8
+#define MVK_Cyrillic_yeru 0x6d9
+#define MVK_Cyrillic_ze 0x6da
+#define MVK_Cyrillic_sha 0x6db
+#define MVK_Cyrillic_e 0x6dc
+#define MVK_Cyrillic_shcha 0x6dd
+#define MVK_Cyrillic_che 0x6de
+#define MVK_Cyrillic_hardsign 0x6df
+#define MVK_Cyrillic_YU 0x6e0
+#define MVK_Cyrillic_A 0x6e1
+#define MVK_Cyrillic_BE 0x6e2
+#define MVK_Cyrillic_TSE 0x6e3
+#define MVK_Cyrillic_DE 0x6e4
+#define MVK_Cyrillic_IE 0x6e5
+#define MVK_Cyrillic_EF 0x6e6
+#define MVK_Cyrillic_GHE 0x6e7
+#define MVK_Cyrillic_HA 0x6e8
+#define MVK_Cyrillic_I 0x6e9
+#define MVK_Cyrillic_SHORTI 0x6ea
+#define MVK_Cyrillic_KA 0x6eb
+#define MVK_Cyrillic_EL 0x6ec
+#define MVK_Cyrillic_EM 0x6ed
+#define MVK_Cyrillic_EN 0x6ee
+#define MVK_Cyrillic_O 0x6ef
+#define MVK_Cyrillic_PE 0x6f0
+#define MVK_Cyrillic_YA 0x6f1
+#define MVK_Cyrillic_ER 0x6f2
+#define MVK_Cyrillic_ES 0x6f3
+#define MVK_Cyrillic_TE 0x6f4
+#define MVK_Cyrillic_U 0x6f5
+#define MVK_Cyrillic_ZHE 0x6f6
+#define MVK_Cyrillic_VE 0x6f7
+#define MVK_Cyrillic_SOFTSIGN 0x6f8
+#define MVK_Cyrillic_YERU 0x6f9
+#define MVK_Cyrillic_ZE 0x6fa
+#define MVK_Cyrillic_SHA 0x6fb
+#define MVK_Cyrillic_E 0x6fc
+#define MVK_Cyrillic_SHCHA 0x6fd
+#define MVK_Cyrillic_CHE 0x6fe
+#define MVK_Cyrillic_HARDSIGN 0x6ff
+#define MVK_Greek_ALPHAaccent 0x7a1
+#define MVK_Greek_EPSILONaccent 0x7a2
+#define MVK_Greek_ETAaccent 0x7a3
+#define MVK_Greek_IOTAaccent 0x7a4
+#define MVK_Greek_IOTAdieresis 0x7a5
+#define MVK_Greek_IOTAdiaeresis 0x7a5
+#define MVK_Greek_OMICRONaccent 0x7a7
+#define MVK_Greek_UPSILONaccent 0x7a8
+#define MVK_Greek_UPSILONdieresis 0x7a9
+#define MVK_Greek_OMEGAaccent 0x7ab
+#define MVK_Greek_accentdieresis 0x7ae
+#define MVK_Greek_horizbar 0x7af
+#define MVK_Greek_alphaaccent 0x7b1
+#define MVK_Greek_epsilonaccent 0x7b2
+#define MVK_Greek_etaaccent 0x7b3
+#define MVK_Greek_iotaaccent 0x7b4
+#define MVK_Greek_iotadieresis 0x7b5
+#define MVK_Greek_iotaaccentdieresis 0x7b6
+#define MVK_Greek_omicronaccent 0x7b7
+#define MVK_Greek_upsilonaccent 0x7b8
+#define MVK_Greek_upsilondieresis 0x7b9
+#define MVK_Greek_upsilonaccentdieresis 0x7ba
+#define MVK_Greek_omegaaccent 0x7bb
+#define MVK_Greek_ALPHA 0x7c1
+#define MVK_Greek_BETA 0x7c2
+#define MVK_Greek_GAMMA 0x7c3
+#define MVK_Greek_DELTA 0x7c4
+#define MVK_Greek_EPSILON 0x7c5
+#define MVK_Greek_ZETA 0x7c6
+#define MVK_Greek_ETA 0x7c7
+#define MVK_Greek_THETA 0x7c8
+#define MVK_Greek_IOTA 0x7c9
+#define MVK_Greek_KAPPA 0x7ca
+#define MVK_Greek_LAMDA 0x7cb
+#define MVK_Greek_LAMBDA 0x7cb
+#define MVK_Greek_MU 0x7cc
+#define MVK_Greek_NU 0x7cd
+#define MVK_Greek_XI 0x7ce
+#define MVK_Greek_OMICRON 0x7cf
+#define MVK_Greek_PI 0x7d0
+#define MVK_Greek_RHO 0x7d1
+#define MVK_Greek_SIGMA 0x7d2
+#define MVK_Greek_TAU 0x7d4
+#define MVK_Greek_UPSILON 0x7d5
+#define MVK_Greek_PHI 0x7d6
+#define MVK_Greek_CHI 0x7d7
+#define MVK_Greek_PSI 0x7d8
+#define MVK_Greek_OMEGA 0x7d9
+#define MVK_Greek_alpha 0x7e1
+#define MVK_Greek_beta 0x7e2
+#define MVK_Greek_gamma 0x7e3
+#define MVK_Greek_delta 0x7e4
+#define MVK_Greek_epsilon 0x7e5
+#define MVK_Greek_zeta 0x7e6
+#define MVK_Greek_eta 0x7e7
+#define MVK_Greek_theta 0x7e8
+#define MVK_Greek_iota 0x7e9
+#define MVK_Greek_kappa 0x7ea
+#define MVK_Greek_lamda 0x7eb
+#define MVK_Greek_lambda 0x7eb
+#define MVK_Greek_mu 0x7ec
+#define MVK_Greek_nu 0x7ed
+#define MVK_Greek_xi 0x7ee
+#define MVK_Greek_omicron 0x7ef
+#define MVK_Greek_pi 0x7f0
+#define MVK_Greek_rho 0x7f1
+#define MVK_Greek_sigma 0x7f2
+#define MVK_Greek_finalsmallsigma 0x7f3
+#define MVK_Greek_tau 0x7f4
+#define MVK_Greek_upsilon 0x7f5
+#define MVK_Greek_phi 0x7f6
+#define MVK_Greek_chi 0x7f7
+#define MVK_Greek_psi 0x7f8
+#define MVK_Greek_omega 0x7f9
+#define MVK_Greek_switch 0xff7e
+#define MVK_leftradical 0x8a1
+#define MVK_topleftradical 0x8a2
+#define MVK_horizconnector 0x8a3
+#define MVK_topintegral 0x8a4
+#define MVK_botintegral 0x8a5
+#define MVK_vertconnector 0x8a6
+#define MVK_topleftsqbracket 0x8a7
+#define MVK_botleftsqbracket 0x8a8
+#define MVK_toprightsqbracket 0x8a9
+#define MVK_botrightsqbracket 0x8aa
+#define MVK_topleftparens 0x8ab
+#define MVK_botleftparens 0x8ac
+#define MVK_toprightparens 0x8ad
+#define MVK_botrightparens 0x8ae
+#define MVK_leftmiddlecurlybrace 0x8af
+#define MVK_rightmiddlecurlybrace 0x8b0
+#define MVK_topleftsummation 0x8b1
+#define MVK_botleftsummation 0x8b2
+#define MVK_topvertsummationconnector 0x8b3
+#define MVK_botvertsummationconnector 0x8b4
+#define MVK_toprightsummation 0x8b5
+#define MVK_botrightsummation 0x8b6
+#define MVK_rightmiddlesummation 0x8b7
+#define MVK_lessthanequal 0x8bc
+#define MVK_notequal 0x8bd
+#define MVK_greaterthanequal 0x8be
+#define MVK_integral 0x8bf
+#define MVK_therefore 0x8c0
+#define MVK_variation 0x8c1
+#define MVK_infinity 0x8c2
+#define MVK_nabla 0x8c5
+#define MVK_approximate 0x8c8
+#define MVK_similarequal 0x8c9
+#define MVK_ifonlyif 0x8cd
+#define MVK_implies 0x8ce
+#define MVK_identical 0x8cf
+#define MVK_radical 0x8d6
+#define MVK_includedin 0x8da
+#define MVK_includes 0x8db
+#define MVK_intersection 0x8dc
+#define MVK_union 0x8dd
+#define MVK_logicaland 0x8de
+#define MVK_logicalor 0x8df
+#define MVK_partialderivative 0x8ef
+#define MVK_function 0x8f6
+#define MVK_leftarrow 0x8fb
+#define MVK_uparrow 0x8fc
+#define MVK_rightarrow 0x8fd
+#define MVK_downarrow 0x8fe
+#define MVK_blank 0x9df
+#define MVK_soliddiamond 0x9e0
+#define MVK_checkerboard 0x9e1
+#define MVK_ht 0x9e2
+#define MVK_ff 0x9e3
+#define MVK_cr 0x9e4
+#define MVK_lf 0x9e5
+#define MVK_nl 0x9e8
+#define MVK_vt 0x9e9
+#define MVK_lowrightcorner 0x9ea
+#define MVK_uprightcorner 0x9eb
+#define MVK_upleftcorner 0x9ec
+#define MVK_lowleftcorner 0x9ed
+#define MVK_crossinglines 0x9ee
+#define MVK_horizlinescan1 0x9ef
+#define MVK_horizlinescan3 0x9f0
+#define MVK_horizlinescan5 0x9f1
+#define MVK_horizlinescan7 0x9f2
+#define MVK_horizlinescan9 0x9f3
+#define MVK_leftt 0x9f4
+#define MVK_rightt 0x9f5
+#define MVK_bott 0x9f6
+#define MVK_topt 0x9f7
+#define MVK_vertbar 0x9f8
+#define MVK_emspace 0xaa1
+#define MVK_enspace 0xaa2
+#define MVK_em3space 0xaa3
+#define MVK_em4space 0xaa4
+#define MVK_digitspace 0xaa5
+#define MVK_punctspace 0xaa6
+#define MVK_thinspace 0xaa7
+#define MVK_hairspace 0xaa8
+#define MVK_emdash 0xaa9
+#define MVK_endash 0xaaa
+#define MVK_signifblank 0xaac
+#define MVK_ellipsis 0xaae
+#define MVK_doubbaselinedot 0xaaf
+#define MVK_onethird 0xab0
+#define MVK_twothirds 0xab1
+#define MVK_onefifth 0xab2
+#define MVK_twofifths 0xab3
+#define MVK_threefifths 0xab4
+#define MVK_fourfifths 0xab5
+#define MVK_onesixth 0xab6
+#define MVK_fivesixths 0xab7
+#define MVK_careof 0xab8
+#define MVK_figdash 0xabb
+#define MVK_leftanglebracket 0xabc
+#define MVK_decimalpoint 0xabd
+#define MVK_rightanglebracket 0xabe
+#define MVK_marker 0xabf
+#define MVK_oneeighth 0xac3
+#define MVK_threeeighths 0xac4
+#define MVK_fiveeighths 0xac5
+#define MVK_seveneighths 0xac6
+#define MVK_trademark 0xac9
+#define MVK_signaturemark 0xaca
+#define MVK_trademarkincircle 0xacb
+#define MVK_leftopentriangle 0xacc
+#define MVK_rightopentriangle 0xacd
+#define MVK_emopencircle 0xace
+#define MVK_emopenrectangle 0xacf
+#define MVK_leftsinglequotemark 0xad0
+#define MVK_rightsinglequotemark 0xad1
+#define MVK_leftdoublequotemark 0xad2
+#define MVK_rightdoublequotemark 0xad3
+#define MVK_prescription 0xad4
+#define MVK_minutes 0xad6
+#define MVK_seconds 0xad7
+#define MVK_latincross 0xad9
+#define MVK_hexagram 0xada
+#define MVK_filledrectbullet 0xadb
+#define MVK_filledlefttribullet 0xadc
+#define MVK_filledrighttribullet 0xadd
+#define MVK_emfilledcircle 0xade
+#define MVK_emfilledrect 0xadf
+#define MVK_enopencircbullet 0xae0
+#define MVK_enopensquarebullet 0xae1
+#define MVK_openrectbullet 0xae2
+#define MVK_opentribulletup 0xae3
+#define MVK_opentribulletdown 0xae4
+#define MVK_openstar 0xae5
+#define MVK_enfilledcircbullet 0xae6
+#define MVK_enfilledsqbullet 0xae7
+#define MVK_filledtribulletup 0xae8
+#define MVK_filledtribulletdown 0xae9
+#define MVK_leftpointer 0xaea
+#define MVK_rightpointer 0xaeb
+#define MVK_club 0xaec
+#define MVK_diamond 0xaed
+#define MVK_heart 0xaee
+#define MVK_maltesecross 0xaf0
+#define MVK_dagger 0xaf1
+#define MVK_doubledagger 0xaf2
+#define MVK_checkmark 0xaf3
+#define MVK_ballotcross 0xaf4
+#define MVK_musicalsharp 0xaf5
+#define MVK_musicalflat 0xaf6
+#define MVK_malesymbol 0xaf7
+#define MVK_femalesymbol 0xaf8
+#define MVK_telephone 0xaf9
+#define MVK_telephonerecorder 0xafa
+#define MVK_phonographcopyright 0xafb
+#define MVK_caret 0xafc
+#define MVK_singlelowquotemark 0xafd
+#define MVK_doublelowquotemark 0xafe
+#define MVK_cursor 0xaff
+#define MVK_leftcaret 0xba3
+#define MVK_rightcaret 0xba6
+#define MVK_downcaret 0xba8
+#define MVK_upcaret 0xba9
+#define MVK_overbar 0xbc0
+#define MVK_downtack 0xbc2
+#define MVK_upshoe 0xbc3
+#define MVK_downstile 0xbc4
+#define MVK_underbar 0xbc6
+#define MVK_jot 0xbca
+#define MVK_quad 0xbcc
+#define MVK_uptack 0xbce
+#define MVK_circle 0xbcf
+#define MVK_upstile 0xbd3
+#define MVK_downshoe 0xbd6
+#define MVK_rightshoe 0xbd8
+#define MVK_leftshoe 0xbda
+#define MVK_lefttack 0xbdc
+#define MVK_righttack 0xbfc
+#define MVK_hebrew_doublelowline 0xcdf
+#define MVK_hebrew_aleph 0x5D0
+#define MVK_hebrew_bet 0x5D1
+#define MVK_hebrew_beth 0x5D1
+#define MVK_hebrew_gimel 0x5D2
+#define MVK_hebrew_gimmel 0x5D2
+#define MVK_hebrew_dalet 0x5D3
+#define MVK_hebrew_daleth 0x5D3
+#define MVK_hebrew_he 0x5D4
+#define MVK_hebrew_waw 0x5D5
+#define MVK_hebrew_zain 0x5D6
+#define MVK_hebrew_zayin 0x5D6
+#define MVK_hebrew_chet 0x5D7
+#define MVK_hebrew_het 0x5D7
+#define MVK_hebrew_tet 0x5D8
+#define MVK_hebrew_teth 0x5D8
+#define MVK_hebrew_yod 0x5D9
+#define MVK_hebrew_finalkaph 0x5DA
+#define MVK_hebrew_kaph 0x5DB
+#define MVK_hebrew_lamed 0x5DC
+#define MVK_hebrew_finalmem 0x5DD
+#define MVK_hebrew_mem 0x5DE
+#define MVK_hebrew_finalnun 0x5DF
+#define MVK_hebrew_nun 0x5E0
+#define MVK_hebrew_samech 0x5E1
+#define MVK_hebrew_samekh 0x5E1
+#define MVK_hebrew_ayin 0x5E2
+#define MVK_hebrew_finalpe 0x5E3
+#define MVK_hebrew_pe 0x5E4
+#define MVK_hebrew_finalzade 0x5E5
+#define MVK_hebrew_finalzadi 0x5E5
+#define MVK_hebrew_zade 0x5E6
+#define MVK_hebrew_zadi 0x5E6
+#define MVK_hebrew_qoph 0x5E7
+#define MVK_hebrew_kuf 0x5E7
+#define MVK_hebrew_resh 0x5E8
+#define MVK_hebrew_shin 0x5E9
+#define MVK_hebrew_taw 0x5EA
+#define MVK_hebrew_taf 0x5EA
+#define MVK_Hebrew_switch 0xff7e
+#define MVK_Thai_kokai 0xda1
+#define MVK_Thai_khokhai 0xda2
+#define MVK_Thai_khokhuat 0xda3
+#define MVK_Thai_khokhwai 0xda4
+#define MVK_Thai_khokhon 0xda5
+#define MVK_Thai_khorakhang 0xda6
+#define MVK_Thai_ngongu 0xda7
+#define MVK_Thai_chochan 0xda8
+#define MVK_Thai_choching 0xda9
+#define MVK_Thai_chochang 0xdaa
+#define MVK_Thai_soso 0xdab
+#define MVK_Thai_chochoe 0xdac
+#define MVK_Thai_yoying 0xdad
+#define MVK_Thai_dochada 0xdae
+#define MVK_Thai_topatak 0xdaf
+#define MVK_Thai_thothan 0xdb0
+#define MVK_Thai_thonangmontho 0xdb1
+#define MVK_Thai_thophuthao 0xdb2
+#define MVK_Thai_nonen 0xdb3
+#define MVK_Thai_dodek 0xdb4
+#define MVK_Thai_totao 0xdb5
+#define MVK_Thai_thothung 0xdb6
+#define MVK_Thai_thothahan 0xdb7
+#define MVK_Thai_thothong 0xdb8
+#define MVK_Thai_nonu 0xdb9
+#define MVK_Thai_bobaimai 0xdba
+#define MVK_Thai_popla 0xdbb
+#define MVK_Thai_phophung 0xdbc
+#define MVK_Thai_fofa 0xdbd
+#define MVK_Thai_phophan 0xdbe
+#define MVK_Thai_fofan 0xdbf
+#define MVK_Thai_phosamphao 0xdc0
+#define MVK_Thai_moma 0xdc1
+#define MVK_Thai_yoyak 0xdc2
+#define MVK_Thai_rorua 0xdc3
+#define MVK_Thai_ru 0xdc4
+#define MVK_Thai_loling 0xdc5
+#define MVK_Thai_lu 0xdc6
+#define MVK_Thai_wowaen 0xdc7
+#define MVK_Thai_sosala 0xdc8
+#define MVK_Thai_sorusi 0xdc9
+#define MVK_Thai_sosua 0xdca
+#define MVK_Thai_hohip 0xdcb
+#define MVK_Thai_lochula 0xdcc
+#define MVK_Thai_oang 0xdcd
+#define MVK_Thai_honokhuk 0xdce
+#define MVK_Thai_paiyannoi 0xdcf
+#define MVK_Thai_saraa 0xdd0
+#define MVK_Thai_maihanakat 0xdd1
+#define MVK_Thai_saraaa 0xdd2
+#define MVK_Thai_saraam 0xdd3
+#define MVK_Thai_sarai 0xdd4
+#define MVK_Thai_saraii 0xdd5
+#define MVK_Thai_saraue 0xdd6
+#define MVK_Thai_sarauee 0xdd7
+#define MVK_Thai_sarau 0xdd8
+#define MVK_Thai_sarauu 0xdd9
+#define MVK_Thai_phinthu 0xdda
+#define MVK_Thai_maihanakat_maitho 0xdde
+#define MVK_Thai_baht 0xddf
+#define MVK_Thai_sarae 0xde0
+#define MVK_Thai_saraae 0xde1
+#define MVK_Thai_sarao 0xde2
+#define MVK_Thai_saraaimaimuan 0xde3
+#define MVK_Thai_saraaimaimalai 0xde4
+#define MVK_Thai_lakkhangyao 0xde5
+#define MVK_Thai_maiyamok 0xde6
+#define MVK_Thai_maitaikhu 0xde7
+#define MVK_Thai_maiek 0xde8
+#define MVK_Thai_maitho 0xde9
+#define MVK_Thai_maitri 0xdea
+#define MVK_Thai_maichattawa 0xdeb
+#define MVK_Thai_thanthakhat 0xdec
+#define MVK_Thai_nikhahit 0xded
+#define MVK_Thai_leksun 0xdf0
+#define MVK_Thai_leknung 0xdf1
+#define MVK_Thai_leksong 0xdf2
+#define MVK_Thai_leksam 0xdf3
+#define MVK_Thai_leksi 0xdf4
+#define MVK_Thai_lekha 0xdf5
+#define MVK_Thai_lekhok 0xdf6
+#define MVK_Thai_lekchet 0xdf7
+#define MVK_Thai_lekpaet 0xdf8
+#define MVK_Thai_lekkao 0xdf9
+#define MVK_Hangul 0xff31
+#define MVK_Hangul_Start 0xff32
+#define MVK_Hangul_End 0xff33
+#define MVK_Hangul_Hanja 0xff34
+#define MVK_Hangul_Jamo 0xff35
+#define MVK_Hangul_Romaja 0xff36
+#define MVK_Hangul_Codeinput 0xff37
+#define MVK_Hangul_Jeonja 0xff38
+#define MVK_Hangul_Banja 0xff39
+#define MVK_Hangul_PreHanja 0xff3a
+#define MVK_Hangul_PostHanja 0xff3b
+#define MVK_Hangul_SingleCandidate 0xff3c
+#define MVK_Hangul_MultipleCandidate 0xff3d
+#define MVK_Hangul_PreviousCandidate 0xff3e
+#define MVK_Hangul_Special 0xff3f
+#define MVK_Hangul_switch 0xff7e
+#define MVK_Hangul_Kiyeog 0xea1
+#define MVK_Hangul_SsangKiyeog 0xea2
+#define MVK_Hangul_KiyeogSios 0xea3
+#define MVK_Hangul_Nieun 0xea4
+#define MVK_Hangul_NieunJieuj 0xea5
+#define MVK_Hangul_NieunHieuh 0xea6
+#define MVK_Hangul_Dikeud 0xea7
+#define MVK_Hangul_SsangDikeud 0xea8
+#define MVK_Hangul_Rieul 0xea9
+#define MVK_Hangul_RieulKiyeog 0xeaa
+#define MVK_Hangul_RieulMieum 0xeab
+#define MVK_Hangul_RieulPieub 0xeac
+#define MVK_Hangul_RieulSios 0xead
+#define MVK_Hangul_RieulTieut 0xeae
+#define MVK_Hangul_RieulPhieuf 0xeaf
+#define MVK_Hangul_RieulHieuh 0xeb0
+#define MVK_Hangul_Mieum 0xeb1
+#define MVK_Hangul_Pieub 0xeb2
+#define MVK_Hangul_SsangPieub 0xeb3
+#define MVK_Hangul_PieubSios 0xeb4
+#define MVK_Hangul_Sios 0xeb5
+#define MVK_Hangul_SsangSios 0xeb6
+#define MVK_Hangul_Ieung 0xeb7
+#define MVK_Hangul_Jieuj 0xeb8
+#define MVK_Hangul_SsangJieuj 0xeb9
+#define MVK_Hangul_Cieuc 0xeba
+#define MVK_Hangul_Khieuq 0xebb
+#define MVK_Hangul_Tieut 0xebc
+#define MVK_Hangul_Phieuf 0xebd
+#define MVK_Hangul_Hieuh 0xebe
+#define MVK_Hangul_A 0xebf
+#define MVK_Hangul_AE 0xec0
+#define MVK_Hangul_YA 0xec1
+#define MVK_Hangul_YAE 0xec2
+#define MVK_Hangul_EO 0xec3
+#define MVK_Hangul_E 0xec4
+#define MVK_Hangul_YEO 0xec5
+#define MVK_Hangul_YE 0xec6
+#define MVK_Hangul_O 0xec7
+#define MVK_Hangul_WA 0xec8
+#define MVK_Hangul_WAE 0xec9
+#define MVK_Hangul_OE 0xeca
+#define MVK_Hangul_YO 0xecb
+#define MVK_Hangul_U 0xecc
+#define MVK_Hangul_WEO 0xecd
+#define MVK_Hangul_WE 0xece
+#define MVK_Hangul_WI 0xecf
+#define MVK_Hangul_YU 0xed0
+#define MVK_Hangul_EU 0xed1
+#define MVK_Hangul_YI 0xed2
+#define MVK_Hangul_I 0xed3
+#define MVK_Hangul_J_Kiyeog 0xed4
+#define MVK_Hangul_J_SsangKiyeog 0xed5
+#define MVK_Hangul_J_KiyeogSios 0xed6
+#define MVK_Hangul_J_Nieun 0xed7
+#define MVK_Hangul_J_NieunJieuj 0xed8
+#define MVK_Hangul_J_NieunHieuh 0xed9
+#define MVK_Hangul_J_Dikeud 0xeda
+#define MVK_Hangul_J_Rieul 0xedb
+#define MVK_Hangul_J_RieulKiyeog 0xedc
+#define MVK_Hangul_J_RieulMieum 0xedd
+#define MVK_Hangul_J_RieulPieub 0xede
+#define MVK_Hangul_J_RieulSios 0xedf
+#define MVK_Hangul_J_RieulTieut 0xee0
+#define MVK_Hangul_J_RieulPhieuf 0xee1
+#define MVK_Hangul_J_RieulHieuh 0xee2
+#define MVK_Hangul_J_Mieum 0xee3
+#define MVK_Hangul_J_Pieub 0xee4
+#define MVK_Hangul_J_PieubSios 0xee5
+#define MVK_Hangul_J_Sios 0xee6
+#define MVK_Hangul_J_SsangSios 0xee7
+#define MVK_Hangul_J_Ieung 0xee8
+#define MVK_Hangul_J_Jieuj 0xee9
+#define MVK_Hangul_J_Cieuc 0xeea
+#define MVK_Hangul_J_Khieuq 0xeeb
+#define MVK_Hangul_J_Tieut 0xeec
+#define MVK_Hangul_J_Phieuf 0xeed
+#define MVK_Hangul_J_Hieuh 0xeee
+#define MVK_Hangul_RieulYeorinHieuh 0xeef
+#define MVK_Hangul_SunkyeongeumMieum 0xef0
+#define MVK_Hangul_SunkyeongeumPieub 0xef1
+#define MVK_Hangul_PanSios 0xef2
+#define MVK_Hangul_KkogjiDalrinIeung 0xef3
+#define MVK_Hangul_SunkyeongeumPhieuf 0xef4
+#define MVK_Hangul_YeorinHieuh 0xef5
+#define MVK_Hangul_AraeA 0xef6
+#define MVK_Hangul_AraeAE 0xef7
+#define MVK_Hangul_J_PanSios 0xef8
+#define MVK_Hangul_J_KkogjiDalrinIeung 0xef9
+#define MVK_Hangul_J_YeorinHieuh 0xefa
+#define MVK_Korean_Won 0xeff
+#define MVK_Armenian_ligature_ew 0x587
+#define MVK_Armenian_full_stop 0x589
+#define MVK_Armenian_verjaket 0x589
+#define MVK_Armenian_separation_mark 0x55d
+#define MVK_Armenian_but 0x55d
+#define MVK_Armenian_hyphen 0x58a
+#define MVK_Armenian_yentamna 0x58a
+#define MVK_Armenian_exclam 0x55c
+#define MVK_Armenian_amanak 0x55c
+#define MVK_Armenian_accent 0x55b
+#define MVK_Armenian_shesht 0x55b
+#define MVK_Armenian_question 0x55e
+#define MVK_Armenian_paruyk 0x55e
+#define MVK_Armenian_AYB 0x531
+#define MVK_Armenian_ayb 0x561
+#define MVK_Armenian_BEN 0x532
+#define MVK_Armenian_ben 0x562
+#define MVK_Armenian_GIM 0x533
+#define MVK_Armenian_gim 0x563
+#define MVK_Armenian_DA 0x534
+#define MVK_Armenian_da 0x564
+#define MVK_Armenian_YECH 0x535
+#define MVK_Armenian_yech 0x565
+#define MVK_Armenian_ZA 0x536
+#define MVK_Armenian_za 0x566
+#define MVK_Armenian_E 0x537
+#define MVK_Armenian_e 0x567
+#define MVK_Armenian_AT 0x538
+#define MVK_Armenian_at 0x568
+#define MVK_Armenian_TO 0x539
+#define MVK_Armenian_to 0x569
+#define MVK_Armenian_ZHE 0x53a
+#define MVK_Armenian_zhe 0x56a
+#define MVK_Armenian_INI 0x53b
+#define MVK_Armenian_ini 0x56b
+#define MVK_Armenian_LYUN 0x53c
+#define MVK_Armenian_lyun 0x56c
+#define MVK_Armenian_KHE 0x53d
+#define MVK_Armenian_khe 0x56d
+#define MVK_Armenian_TSA 0x53e
+#define MVK_Armenian_tsa 0x56e
+#define MVK_Armenian_KEN 0x53f
+#define MVK_Armenian_ken 0x56f
+#define MVK_Armenian_HO 0x540
+#define MVK_Armenian_ho 0x570
+#define MVK_Armenian_DZA 0x541
+#define MVK_Armenian_dza 0x571
+#define MVK_Armenian_GHAT 0x542
+#define MVK_Armenian_ghat 0x572
+#define MVK_Armenian_TCHE 0x543
+#define MVK_Armenian_tche 0x573
+#define MVK_Armenian_MEN 0x544
+#define MVK_Armenian_men 0x574
+#define MVK_Armenian_HI 0x545
+#define MVK_Armenian_hi 0x575
+#define MVK_Armenian_NU 0x546
+#define MVK_Armenian_nu 0x576
+#define MVK_Armenian_SHA 0x547
+#define MVK_Armenian_sha 0x577
+#define MVK_Armenian_VO 0x548
+#define MVK_Armenian_vo 0x578
+#define MVK_Armenian_CHA 0x549
+#define MVK_Armenian_cha 0x579
+#define MVK_Armenian_PE 0x54a
+#define MVK_Armenian_pe 0x57a
+#define MVK_Armenian_JE 0x54b
+#define MVK_Armenian_je 0x57b
+#define MVK_Armenian_RA 0x54c
+#define MVK_Armenian_ra 0x57c
+#define MVK_Armenian_SE 0x54d
+#define MVK_Armenian_se 0x57d
+#define MVK_Armenian_VEV 0x54e
+#define MVK_Armenian_vev 0x57e
+#define MVK_Armenian_TYUN 0x54f
+#define MVK_Armenian_tyun 0x57f
+#define MVK_Armenian_RE 0x550
+#define MVK_Armenian_re 0x580
+#define MVK_Armenian_TSO 0x551
+#define MVK_Armenian_tso 0x581
+#define MVK_Armenian_VYUN 0x552
+#define MVK_Armenian_vyun 0x582
+#define MVK_Armenian_PYUR 0x553
+#define MVK_Armenian_pyur 0x583
+#define MVK_Armenian_KE 0x554
+#define MVK_Armenian_ke 0x584
+#define MVK_Armenian_O 0x555
+#define MVK_Armenian_o 0x585
+#define MVK_Armenian_FE 0x556
+#define MVK_Armenian_fe 0x586
+#define MVK_Armenian_apostrophe 0x55a
+#define MVK_Georgian_an 0x10d0
+#define MVK_Georgian_ban 0x10d1
+#define MVK_Georgian_gan 0x10d2
+#define MVK_Georgian_don 0x10d3
+#define MVK_Georgian_en 0x10d4
+#define MVK_Georgian_vin 0x10d5
+#define MVK_Georgian_zen 0x10d6
+#define MVK_Georgian_tan 0x10d7
+#define MVK_Georgian_in 0x10d8
+#define MVK_Georgian_kan 0x10d9
+#define MVK_Georgian_las 0x10da
+#define MVK_Georgian_man 0x10db
+#define MVK_Georgian_nar 0x10dc
+#define MVK_Georgian_on 0x10dd
+#define MVK_Georgian_par 0x10de
+#define MVK_Georgian_zhar 0x10df
+#define MVK_Georgian_rae 0x10e0
+#define MVK_Georgian_san 0x10e1
+#define MVK_Georgian_tar 0x10e2
+#define MVK_Georgian_un 0x10e3
+#define MVK_Georgian_phar 0x10e4
+#define MVK_Georgian_khar 0x10e5
+#define MVK_Georgian_ghan 0x10e6
+#define MVK_Georgian_qar 0x10e7
+#define MVK_Georgian_shin 0x10e8
+#define MVK_Georgian_chin 0x10e9
+#define MVK_Georgian_can 0x10ea
+#define MVK_Georgian_jil 0x10eb
+#define MVK_Georgian_cil 0x10ec
+#define MVK_Georgian_char 0x10ed
+#define MVK_Georgian_xan 0x10ee
+#define MVK_Georgian_jhan 0x10ef
+#define MVK_Georgian_hae 0x10f0
+#define MVK_Georgian_he 0x10f1
+#define MVK_Georgian_hie 0x10f2
+#define MVK_Georgian_we 0x10f3
+#define MVK_Georgian_har 0x10f4
+#define MVK_Georgian_hoe 0x10f5
+#define MVK_Georgian_fi 0x10f6
+#define MVK_Xabovedot 0x1e8a
+#define MVK_Ibreve 0x12c
+#define MVK_Zstroke 0x1b5
+#define MVK_Gcaron 0x1e6
+#define MVK_Ocaron 0x1d1
+#define MVK_Obarred 0x19f
+#define MVK_xabovedot 0x1e8b
+#define MVK_ibreve 0x12d
+#define MVK_zstroke 0x1b6
+#define MVK_gcaron 0x1e7
+#define MVK_ocaron 0x1d2
+#define MVK_obarred 0x275
+#define MVK_SCHWA 0x18f
+#define MVK_schwa 0x259
+#define MVK_Lbelowdot 0x1e36
+#define MVK_lbelowdot 0x1e37
+#define MVK_Abelowdot 0x1ea0
+#define MVK_abelowdot 0x1ea1
+#define MVK_Ahook 0x1ea2
+#define MVK_ahook 0x1ea3
+#define MVK_Acircumflexacute 0x1ea4
+#define MVK_acircumflexacute 0x1ea5
+#define MVK_Acircumflexgrave 0x1ea6
+#define MVK_acircumflexgrave 0x1ea7
+#define MVK_Acircumflexhook 0x1ea8
+#define MVK_acircumflexhook 0x1ea9
+#define MVK_Acircumflextilde 0x1eaa
+#define MVK_acircumflextilde 0x1eab
+#define MVK_Acircumflexbelowdot 0x1eac
+#define MVK_acircumflexbelowdot 0x1ead
+#define MVK_Abreveacute 0x1eae
+#define MVK_abreveacute 0x1eaf
+#define MVK_Abrevegrave 0x1eb0
+#define MVK_abrevegrave 0x1eb1
+#define MVK_Abrevehook 0x1eb2
+#define MVK_abrevehook 0x1eb3
+#define MVK_Abrevetilde 0x1eb4
+#define MVK_abrevetilde 0x1eb5
+#define MVK_Abrevebelowdot 0x1eb6
+#define MVK_abrevebelowdot 0x1eb7
+#define MVK_Ebelowdot 0x1eb8
+#define MVK_ebelowdot 0x1eb9
+#define MVK_Ehook 0x1eba
+#define MVK_ehook 0x1ebb
+#define MVK_Etilde 0x1ebc
+#define MVK_etilde 0x1ebd
+#define MVK_Ecircumflexacute 0x1ebe
+#define MVK_ecircumflexacute 0x1ebf
+#define MVK_Ecircumflexgrave 0x1ec0
+#define MVK_ecircumflexgrave 0x1ec1
+#define MVK_Ecircumflexhook 0x1ec2
+#define MVK_ecircumflexhook 0x1ec3
+#define MVK_Ecircumflextilde 0x1ec4
+#define MVK_ecircumflextilde 0x1ec5
+#define MVK_Ecircumflexbelowdot 0x1ec6
+#define MVK_ecircumflexbelowdot 0x1ec7
+#define MVK_Ihook 0x1ec8
+#define MVK_ihook 0x1ec9
+#define MVK_Ibelowdot 0x1eca
+#define MVK_ibelowdot 0x1ecb
+#define MVK_Obelowdot 0x1ecc
+#define MVK_obelowdot 0x1ecd
+#define MVK_Ohook 0x1ece
+#define MVK_ohook 0x1ecf
+#define MVK_Ocircumflexacute 0x1ed0
+#define MVK_ocircumflexacute 0x1ed1
+#define MVK_Ocircumflexgrave 0x1ed2
+#define MVK_ocircumflexgrave 0x1ed3
+#define MVK_Ocircumflexhook 0x1ed4
+#define MVK_ocircumflexhook 0x1ed5
+#define MVK_Ocircumflextilde 0x1ed6
+#define MVK_ocircumflextilde 0x1ed7
+#define MVK_Ocircumflexbelowdot 0x1ed8
+#define MVK_ocircumflexbelowdot 0x1ed9
+#define MVK_Ohornacute 0x1eda
+#define MVK_ohornacute 0x1edb
+#define MVK_Ohorngrave 0x1edc
+#define MVK_ohorngrave 0x1edd
+#define MVK_Ohornhook 0x1ede
+#define MVK_ohornhook 0x1edf
+#define MVK_Ohorntilde 0x1ee0
+#define MVK_ohorntilde 0x1ee1
+#define MVK_Ohornbelowdot 0x1ee2
+#define MVK_ohornbelowdot 0x1ee3
+#define MVK_Ubelowdot 0x1ee4
+#define MVK_ubelowdot 0x1ee5
+#define MVK_Uhook 0x1ee6
+#define MVK_uhook 0x1ee7
+#define MVK_Uhornacute 0x1ee8
+#define MVK_uhornacute 0x1ee9
+#define MVK_Uhorngrave 0x1eea
+#define MVK_uhorngrave 0x1eeb
+#define MVK_Uhornhook 0x1eec
+#define MVK_uhornhook 0x1eed
+#define MVK_Uhorntilde 0x1eee
+#define MVK_uhorntilde 0x1eef
+#define MVK_Uhornbelowdot 0x1ef0
+#define MVK_uhornbelowdot 0x1ef1
+#define MVK_Ybelowdot 0x1ef4
+#define MVK_ybelowdot 0x1ef5
+#define MVK_Yhook 0x1ef6
+#define MVK_yhook 0x1ef7
+#define MVK_Ytilde 0x1ef8
+#define MVK_ytilde 0x1ef9
+#define MVK_Ohorn 0x1a0
+#define MVK_ohorn 0x1a1
+#define MVK_Uhorn 0x1af
+#define MVK_uhorn 0x1b0
+#define MVK_EcuSign 0x20a0
+#define MVK_ColonSign 0x20a1
+#define MVK_CruzeiroSign 0x20a2
+#define MVK_FFrancSign 0x20a3
+#define MVK_LiraSign 0x20a4
+#define MVK_MillSign 0x20a5
+#define MVK_NairaSign 0x20a6
+#define MVK_PesetaSign 0x20a7
+#define MVK_RupeeSign 0x20a8
+#define MVK_WonSign 0x20a9
+#define MVK_NewSheqelSign 0x20aa
+#define MVK_DongSign 0x20ab
+#define MVK_EuroSign 0x20ac
+#define MVK_zerosuperior 0x2070
+#define MVK_foursuperior 0x2074
+#define MVK_fivesuperior 0x2075
+#define MVK_sixsuperior 0x2076
+#define MVK_sevensuperior 0x2077
+#define MVK_eightsuperior 0x2078
+#define MVK_ninesuperior 0x2079
+#define MVK_zerosubscript 0x2080
+#define MVK_onesubscript 0x2081
+#define MVK_twosubscript 0x2082
+#define MVK_threesubscript 0x2083
+#define MVK_foursubscript 0x2084
+#define MVK_fivesubscript 0x2085
+#define MVK_sixsubscript 0x2086
+#define MVK_sevensubscript 0x2087
+#define MVK_eightsubscript 0x2088
+#define MVK_ninesubscript 0x2089
+#define MVK_partdifferential 0x2202
+#define MVK_emptyset 0x2205
+#define MVK_elementof 0x2208
+#define MVK_notelementof 0x2209
+#define MVK_containsas 0x220b
+#define MVK_squareroot 0x221a
+#define MVK_cuberoot 0x221b
+#define MVK_fourthroot 0x221c
+#define MVK_dintegral 0x222c
+#define MVK_tintegral 0x222d
+#define MVK_because 0x2235
+#define MVK_approxeq 0x2248
+#define MVK_notapproxeq 0x2247
+#define MVK_notidentical 0x2262
+#define MVK_stricteq 0x2263
+#define MVK_braille_dot_1 0xfff1
+#define MVK_braille_dot_2 0xfff2
+#define MVK_braille_dot_3 0xfff3
+#define MVK_braille_dot_4 0xfff4
+#define MVK_braille_dot_5 0xfff5
+#define MVK_braille_dot_6 0xfff6
+#define MVK_braille_dot_7 0xfff7
+#define MVK_braille_dot_8 0xfff8
+#define MVK_braille_dot_9 0xfff9
+#define MVK_braille_dot_10 0xfffa
+#define MVK_braille_blank 0x2800
+#define MVK_braille_dots_1 0x2801
+#define MVK_braille_dots_2 0x2802
+#define MVK_braille_dots_12 0x2803
+#define MVK_braille_dots_3 0x2804
+#define MVK_braille_dots_13 0x2805
+#define MVK_braille_dots_23 0x2806
+#define MVK_braille_dots_123 0x2807
+#define MVK_braille_dots_4 0x2808
+#define MVK_braille_dots_14 0x2809
+#define MVK_braille_dots_24 0x280a
+#define MVK_braille_dots_124 0x280b
+#define MVK_braille_dots_34 0x280c
+#define MVK_braille_dots_134 0x280d
+#define MVK_braille_dots_234 0x280e
+#define MVK_braille_dots_1234 0x280f
+#define MVK_braille_dots_5 0x2810
+#define MVK_braille_dots_15 0x2811
+#define MVK_braille_dots_25 0x2812
+#define MVK_braille_dots_125 0x2813
+#define MVK_braille_dots_35 0x2814
+#define MVK_braille_dots_135 0x2815
+#define MVK_braille_dots_235 0x2816
+#define MVK_braille_dots_1235 0x2817
+#define MVK_braille_dots_45 0x2818
+#define MVK_braille_dots_145 0x2819
+#define MVK_braille_dots_245 0x281a
+#define MVK_braille_dots_1245 0x281b
+#define MVK_braille_dots_345 0x281c
+#define MVK_braille_dots_1345 0x281d
+#define MVK_braille_dots_2345 0x281e
+#define MVK_braille_dots_12345 0x281f
+#define MVK_braille_dots_6 0x2820
+#define MVK_braille_dots_16 0x2821
+#define MVK_braille_dots_26 0x2822
+#define MVK_braille_dots_126 0x2823
+#define MVK_braille_dots_36 0x2824
+#define MVK_braille_dots_136 0x2825
+#define MVK_braille_dots_236 0x2826
+#define MVK_braille_dots_1236 0x2827
+#define MVK_braille_dots_46 0x2828
+#define MVK_braille_dots_146 0x2829
+#define MVK_braille_dots_246 0x282a
+#define MVK_braille_dots_1246 0x282b
+#define MVK_braille_dots_346 0x282c
+#define MVK_braille_dots_1346 0x282d
+#define MVK_braille_dots_2346 0x282e
+#define MVK_braille_dots_12346 0x282f
+#define MVK_braille_dots_56 0x2830
+#define MVK_braille_dots_156 0x2831
+#define MVK_braille_dots_256 0x2832
+#define MVK_braille_dots_1256 0x2833
+#define MVK_braille_dots_356 0x2834
+#define MVK_braille_dots_1356 0x2835
+#define MVK_braille_dots_2356 0x2836
+#define MVK_braille_dots_12356 0x2837
+#define MVK_braille_dots_456 0x2838
+#define MVK_braille_dots_1456 0x2839
+#define MVK_braille_dots_2456 0x283a
+#define MVK_braille_dots_12456 0x283b
+#define MVK_braille_dots_3456 0x283c
+#define MVK_braille_dots_13456 0x283d
+#define MVK_braille_dots_23456 0x283e
+#define MVK_braille_dots_123456 0x283f
+#define MVK_braille_dots_7 0x2840
+#define MVK_braille_dots_17 0x2841
+#define MVK_braille_dots_27 0x2842
+#define MVK_braille_dots_127 0x2843
+#define MVK_braille_dots_37 0x2844
+#define MVK_braille_dots_137 0x2845
+#define MVK_braille_dots_237 0x2846
+#define MVK_braille_dots_1237 0x2847
+#define MVK_braille_dots_47 0x2848
+#define MVK_braille_dots_147 0x2849
+#define MVK_braille_dots_247 0x284a
+#define MVK_braille_dots_1247 0x284b
+#define MVK_braille_dots_347 0x284c
+#define MVK_braille_dots_1347 0x284d
+#define MVK_braille_dots_2347 0x284e
+#define MVK_braille_dots_12347 0x284f
+#define MVK_braille_dots_57 0x2850
+#define MVK_braille_dots_157 0x2851
+#define MVK_braille_dots_257 0x2852
+#define MVK_braille_dots_1257 0x2853
+#define MVK_braille_dots_357 0x2854
+#define MVK_braille_dots_1357 0x2855
+#define MVK_braille_dots_2357 0x2856
+#define MVK_braille_dots_12357 0x2857
+#define MVK_braille_dots_457 0x2858
+#define MVK_braille_dots_1457 0x2859
+#define MVK_braille_dots_2457 0x285a
+#define MVK_braille_dots_12457 0x285b
+#define MVK_braille_dots_3457 0x285c
+#define MVK_braille_dots_13457 0x285d
+#define MVK_braille_dots_23457 0x285e
+#define MVK_braille_dots_123457 0x285f
+#define MVK_braille_dots_67 0x2860
+#define MVK_braille_dots_167 0x2861
+#define MVK_braille_dots_267 0x2862
+#define MVK_braille_dots_1267 0x2863
+#define MVK_braille_dots_367 0x2864
+#define MVK_braille_dots_1367 0x2865
+#define MVK_braille_dots_2367 0x2866
+#define MVK_braille_dots_12367 0x2867
+#define MVK_braille_dots_467 0x2868
+#define MVK_braille_dots_1467 0x2869
+#define MVK_braille_dots_2467 0x286a
+#define MVK_braille_dots_12467 0x286b
+#define MVK_braille_dots_3467 0x286c
+#define MVK_braille_dots_13467 0x286d
+#define MVK_braille_dots_23467 0x286e
+#define MVK_braille_dots_123467 0x286f
+#define MVK_braille_dots_567 0x2870
+#define MVK_braille_dots_1567 0x2871
+#define MVK_braille_dots_2567 0x2872
+#define MVK_braille_dots_12567 0x2873
+#define MVK_braille_dots_3567 0x2874
+#define MVK_braille_dots_13567 0x2875
+#define MVK_braille_dots_23567 0x2876
+#define MVK_braille_dots_123567 0x2877
+#define MVK_braille_dots_4567 0x2878
+#define MVK_braille_dots_14567 0x2879
+#define MVK_braille_dots_24567 0x287a
+#define MVK_braille_dots_124567 0x287b
+#define MVK_braille_dots_34567 0x287c
+#define MVK_braille_dots_134567 0x287d
+#define MVK_braille_dots_234567 0x287e
+#define MVK_braille_dots_1234567 0x287f
+#define MVK_braille_dots_8 0x2880
+#define MVK_braille_dots_18 0x2881
+#define MVK_braille_dots_28 0x2882
+#define MVK_braille_dots_128 0x2883
+#define MVK_braille_dots_38 0x2884
+#define MVK_braille_dots_138 0x2885
+#define MVK_braille_dots_238 0x2886
+#define MVK_braille_dots_1238 0x2887
+#define MVK_braille_dots_48 0x2888
+#define MVK_braille_dots_148 0x2889
+#define MVK_braille_dots_248 0x288a
+#define MVK_braille_dots_1248 0x288b
+#define MVK_braille_dots_348 0x288c
+#define MVK_braille_dots_1348 0x288d
+#define MVK_braille_dots_2348 0x288e
+#define MVK_braille_dots_12348 0x288f
+#define MVK_braille_dots_58 0x2890
+#define MVK_braille_dots_158 0x2891
+#define MVK_braille_dots_258 0x2892
+#define MVK_braille_dots_1258 0x2893
+#define MVK_braille_dots_358 0x2894
+#define MVK_braille_dots_1358 0x2895
+#define MVK_braille_dots_2358 0x2896
+#define MVK_braille_dots_12358 0x2897
+#define MVK_braille_dots_458 0x2898
+#define MVK_braille_dots_1458 0x2899
+#define MVK_braille_dots_2458 0x289a
+#define MVK_braille_dots_12458 0x289b
+#define MVK_braille_dots_3458 0x289c
+#define MVK_braille_dots_13458 0x289d
+#define MVK_braille_dots_23458 0x289e
+#define MVK_braille_dots_123458 0x289f
+#define MVK_braille_dots_68 0x28a0
+#define MVK_braille_dots_168 0x28a1
+#define MVK_braille_dots_268 0x28a2
+#define MVK_braille_dots_1268 0x28a3
+#define MVK_braille_dots_368 0x28a4
+#define MVK_braille_dots_1368 0x28a5
+#define MVK_braille_dots_2368 0x28a6
+#define MVK_braille_dots_12368 0x28a7
+#define MVK_braille_dots_468 0x28a8
+#define MVK_braille_dots_1468 0x28a9
+#define MVK_braille_dots_2468 0x28aa
+#define MVK_braille_dots_12468 0x28ab
+#define MVK_braille_dots_3468 0x28ac
+#define MVK_braille_dots_13468 0x28ad
+#define MVK_braille_dots_23468 0x28ae
+#define MVK_braille_dots_123468 0x28af
+#define MVK_braille_dots_568 0x28b0
+#define MVK_braille_dots_1568 0x28b1
+#define MVK_braille_dots_2568 0x28b2
+#define MVK_braille_dots_12568 0x28b3
+#define MVK_braille_dots_3568 0x28b4
+#define MVK_braille_dots_13568 0x28b5
+#define MVK_braille_dots_23568 0x28b6
+#define MVK_braille_dots_123568 0x28b7
+#define MVK_braille_dots_4568 0x28b8
+#define MVK_braille_dots_14568 0x28b9
+#define MVK_braille_dots_24568 0x28ba
+#define MVK_braille_dots_124568 0x28bb
+#define MVK_braille_dots_34568 0x28bc
+#define MVK_braille_dots_134568 0x28bd
+#define MVK_braille_dots_234568 0x28be
+#define MVK_braille_dots_1234568 0x28bf
+#define MVK_braille_dots_78 0x28c0
+#define MVK_braille_dots_178 0x28c1
+#define MVK_braille_dots_278 0x28c2
+#define MVK_braille_dots_1278 0x28c3
+#define MVK_braille_dots_378 0x28c4
+#define MVK_braille_dots_1378 0x28c5
+#define MVK_braille_dots_2378 0x28c6
+#define MVK_braille_dots_12378 0x28c7
+#define MVK_braille_dots_478 0x28c8
+#define MVK_braille_dots_1478 0x28c9
+#define MVK_braille_dots_2478 0x28ca
+#define MVK_braille_dots_12478 0x28cb
+#define MVK_braille_dots_3478 0x28cc
+#define MVK_braille_dots_13478 0x28cd
+#define MVK_braille_dots_23478 0x28ce
+#define MVK_braille_dots_123478 0x28cf
+#define MVK_braille_dots_578 0x28d0
+#define MVK_braille_dots_1578 0x28d1
+#define MVK_braille_dots_2578 0x28d2
+#define MVK_braille_dots_12578 0x28d3
+#define MVK_braille_dots_3578 0x28d4
+#define MVK_braille_dots_13578 0x28d5
+#define MVK_braille_dots_23578 0x28d6
+#define MVK_braille_dots_123578 0x28d7
+#define MVK_braille_dots_4578 0x28d8
+#define MVK_braille_dots_14578 0x28d9
+#define MVK_braille_dots_24578 0x28da
+#define MVK_braille_dots_124578 0x28db
+#define MVK_braille_dots_34578 0x28dc
+#define MVK_braille_dots_134578 0x28dd
+#define MVK_braille_dots_234578 0x28de
+#define MVK_braille_dots_1234578 0x28df
+#define MVK_braille_dots_678 0x28e0
+#define MVK_braille_dots_1678 0x28e1
+#define MVK_braille_dots_2678 0x28e2
+#define MVK_braille_dots_12678 0x28e3
+#define MVK_braille_dots_3678 0x28e4
+#define MVK_braille_dots_13678 0x28e5
+#define MVK_braille_dots_23678 0x28e6
+#define MVK_braille_dots_123678 0x28e7
+#define MVK_braille_dots_4678 0x28e8
+#define MVK_braille_dots_14678 0x28e9
+#define MVK_braille_dots_24678 0x28ea
+#define MVK_braille_dots_124678 0x28eb
+#define MVK_braille_dots_34678 0x28ec
+#define MVK_braille_dots_134678 0x28ed
+#define MVK_braille_dots_234678 0x28ee
+#define MVK_braille_dots_1234678 0x28ef
+#define MVK_braille_dots_5678 0x28f0
+#define MVK_braille_dots_15678 0x28f1
+#define MVK_braille_dots_25678 0x28f2
+#define MVK_braille_dots_125678 0x28f3
+#define MVK_braille_dots_35678 0x28f4
+#define MVK_braille_dots_135678 0x28f5
+#define MVK_braille_dots_235678 0x28f6
+#define MVK_braille_dots_1235678 0x28f7
+#define MVK_braille_dots_45678 0x28f8
+#define MVK_braille_dots_145678 0x28f9
+#define MVK_braille_dots_245678 0x28fa
+#define MVK_braille_dots_1245678 0x28fb
+#define MVK_braille_dots_345678 0x28fc
+#define MVK_braille_dots_1345678 0x28fd
+#define MVK_braille_dots_2345678 0x28fe
+#define MVK_braille_dots_12345678 0x28ff
+
+/*-----------------RUSSIAN KEY PAD QWERTY STYLE-------------------------------*/
+/*---first row contains 12 keys---(all russian keys)---*/
+#define MVK_RUSSIAN_SMALL_YA 0x44F
+#define MVK_RUSSIAN_CAPITAL_YA 0x42F
+#define MVK_RUSSIAN_SMALL_ZHE 0x436
+#define MVK_RUSSIAN_CAPITAL_ZHE 0x416
+#define MVK_RUSSIAN_SMALL_IE 0x435
+#define MVK_RUSSIAN_CAPITAL_IE 0x415
+#define MVK_RUSSIAN_SMALL_ER 0x440
+#define MVK_RUSSIAN_CAPITAL_ER 0x420
+#define MVK_RUSSIAN_SMALL_TE 0x442
+#define MVK_RUSSIAN_CAPITAL_TE 0x422
+#define MVK_RUSSIAN_SMALL_YERU 0x44B
+#define MVK_RUSSIAN_CAPITAL_YERU 0x42B
+#define MVK_RUSSIAN_SMALL_U 0x443
+#define MVK_RUSSIAN_CAPITAL_U 0x423
+#define MVK_RUSSIAN_SMALL_I 0x438
+#define MVK_RUSSIAN_CAPITAL_I 0x418
+#define MVK_RUSSIAN_SMALL_O 0x43E
+#define MVK_RUSSIAN_CAPITAL_O 0x41E
+#define MVK_RUSSIAN_SMALL_PE 0x43F
+#define MVK_RUSSIAN_CAPITAL_PE 0x41F
+#define MVK_RUSSIAN_SMALL_SHA 0x448
+#define MVK_RUSSIAN_CAPITAL_SHA 0x428
+#define MVK_RUSSIAN_SMALL_SHCA 0x449
+#define MVK_RUSSIAN_CAPITAL_SHCA 0x429
+/*-----second row contains 11 keys----(all russian keys)-----------*/
+#define MVK_RUSSIAN_SMALL_A 0x430
+#define MVK_RUSSIAN_CAPITAL_A 0x410
+#define MVK_RUSSIAN_SMALL_ES 0x441
+#define MVK_RUSSIAN_CAPITAL_ES 0x421
+#define MVK_RUSSIAN_SMALL_DE 0x434
+#define MVK_RUSSIAN_CAPITAL_DE 0x414
+#define MVK_RUSSIAN_SMALL_EF 0x444
+#define MVK_RUSSIAN_CAPITAL_EF 0x424
+#define MVK_RUSSIAN_SMALL_GHE 0x433
+#define MVK_RUSSIAN_CAPITAL_GHE 0x413
+#define MVK_RUSSIAN_SMALL_HA 0x445
+#define MVK_RUSSIAN_CAPITAL_HA 0x425
+#define MVK_RUSSIAN_SMALL_SHRTI 0x439
+#define MVK_RUSSIAN_CAPITAL_SHRTI 0x419
+#define MVK_RUSSIAN_SMALL_KA 0x43A
+#define MVK_RUSSIAN_CAPITAL_KA 0x41A
+#define MVK_RUSSIAN_SMALL_EL 0x43B
+#define MVK_RUSSIAN_CAPITAL_EL 0x41B
+#define MVK_RUSSIAN_SMALL_CHE 0x447
+#define MVK_RUSSIAN_CAPITAL_CHE 0x427
+#define MVK_RUSSIAN_SMALL_E 0x44D
+#define MVK_RUSSIAN_CAPITAL_E 0x42D
+/*----third row contains 12 keys----(shift key + 10 russian keys + enter key)-----*/
+#define MVK_RUSSIAN_SMALL_ZE 0x437
+#define MVK_RUSSIAN_CAPITAL_ZE 0x417
+#define MVK_RUSSIAN_SMALL_SOFT 0x44C
+#define MVK_RUSSIAN_CAPITAL_SOFT 0x42C
+#define MVK_RUSSIAN_SMALL_TSE 0x446
+#define MVK_RUSSIAN_CAPITAL_TSE 0x426
+#define MVK_RUSSIAN_SMALL_VE 0x432
+#define MVK_RUSSIAN_CAPITAL_VE 0x412
+#define MVK_RUSSIAN_SMALL_BE 0x431
+#define MVK_RUSSIAN_CAPITAL_BE 0x411
+#define MVK_RUSSIAN_SMALL_EN 0x43D
+#define MVK_RUSSIAN_CAPITAL_EN 0x41D
+#define MVK_RUSSIAN_SMALL_EM 0x43C
+#define MVK_RUSSIAN_CAPITAL_EM 0x41C
+#define MVK_RUSSIAN_SMALL_HARD 0x44A
+#define MVK_RUSSIAN_CAPITAL_HARD 0x42A
+#define MVK_RUSSIAN_SMALL_YU 0x44E
+#define MVK_RUSSIAN_CAPITAL_YU 0x42E
+#define MVK_RUSSIAN_SMALL_IO 0x451
+#define MVK_RUSSIAN_CAPITAL_IO 0x401
+/*----forth row is same as normal english qwerty keypad ---------------*/
+
+
+#define MVK_NATIVE 0x30a1
+
+#define MVK_RESERVED_KEY 0x9000 /* limit about reserved key*/
+
+
+#endif //__SCL_KEY_DEFINES_H__
diff --git a/scl/sclkeyfocushandler.cpp b/scl/sclkeyfocushandler.cpp
new file mode 100644 (file)
index 0000000..9c892d7
--- /dev/null
@@ -0,0 +1,833 @@
+/*
+ * Copyright (c) 2012 - 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 "sclkeyfocushandler.h"
+#include <Elementary.h>
+#include <Evas.h>
+#include <dlog.h>
+#ifndef WAYLAND
+#include <Ecore_X.h>
+#endif
+#include "sclres_type.h"
+#include "scldebug.h"
+#include "sclcontext.h"
+#include "sclresourcecache.h"
+#include "sclwindows.h"
+#include "scleventhandler.h"
+#include "sclres_manager.h"
+#include "sclanimator.h"
+
+using namespace scl;
+
+/**
+ * Constructor
+ */
+CSCLKeyFocusHandler::CSCLKeyFocusHandler()
+{
+    SCL_DEBUG();
+#ifdef USING_KEY_GRAB
+    m_keyboard_grabbed = FALSE;
+#endif
+    m_focus_key = NOT_USED;
+    m_focus_window = SCLWINDOW_INVALID;
+
+#ifdef TARGET_EMULATOR
+    create_sniffer_window();
+#endif
+}
+
+/**
+ * Destructor
+ */
+CSCLKeyFocusHandler::~CSCLKeyFocusHandler()
+{
+    SCL_DEBUG();
+}
+
+CSCLKeyFocusHandler*
+CSCLKeyFocusHandler::get_instance()
+{
+    static CSCLKeyFocusHandler instance;
+    return &instance;
+}
+
+#ifdef USING_KEY_GRAB
+/**
+ * Grabs the navigation and Return keys
+ */
+bool
+CSCLKeyFocusHandler::grab_keyboard(const sclwindow parent)
+{
+#ifndef WAYLAND
+    Evas_Object *window = (Evas_Object *)parent;
+    Ecore_X_Window x_window = elm_win_xwindow_get(window);
+
+    Display *x_display = (Display *)ecore_x_display_get();
+    int grab_result;
+
+    grab_result = utilx_grab_key(x_display, x_window, "Return", EXCLUSIVE_GRAB);
+    if (0 == grab_result) {
+        LOGD("Return Key Grabbed successfully\n");
+    } else if (EXCLUSIVE_GRABBED_ALREADY == grab_result) {
+        LOGD("Return Key already grabbed in Exclusiv mode\n");
+    } else {
+        LOGD("Failed to Grab Return key\n");
+    }
+#endif
+    m_keyboard_grabbed = TRUE;
+    return TRUE;
+}
+
+/**
+ * UnGrabs the navigation and Return keys
+ */
+void
+CSCLKeyFocusHandler::ungrab_keyboard(const sclwindow parent)
+{
+#ifndef WAYLAND
+    Evas_Object *window = (Evas_Object *)parent;
+    Ecore_X_Window x_window = elm_win_xwindow_get(window);
+    Display *x_display = (Display *)ecore_x_display_get();
+    int grab_result;
+    grab_result = utilx_ungrab_key(x_display, x_window, "Return");
+    if (0 == grab_result) {
+        LOGD("Return Key UnGrabbed successfully\n");
+    } else {
+        LOGD("Failed to UnGrab Return key\n");
+    }
+#endif
+    m_keyboard_grabbed = FALSE;
+}
+
+#endif /*USING_KEY_GRAB*/
+
+
+void
+CSCLKeyFocusHandler::popup_opened(sclwindow window)
+{
+}
+
+void
+CSCLKeyFocusHandler::popup_closed(sclwindow window)
+{
+    sclshort layout = NOT_USED;
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = NULL;
+
+    if (context && windows && sclres_manager) {
+        sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
+        layout = context->get_popup_layout(m_focus_window);
+    }
+    if (windows && sclres_layout_key_coordinate_pointer_frame &&
+        scl_check_arrindex(layout, MAX_SCL_LAYOUT) && scl_check_arrindex(m_focus_key, MAX_KEY)) {
+            SclLayoutKeyCoordinatePointer cur = sclres_layout_key_coordinate_pointer_frame[layout][m_focus_key];
+            SclWindowContext *window_context = windows->get_window_context(m_focus_window);
+            SclRectangle cur_key_coordinate = {0, 0, 0, 0};
+            if (window_context) {
+                cur_key_coordinate.x = cur->x + window_context->geometry.x;
+                cur_key_coordinate.y = cur->y + window_context->geometry.y;
+                cur_key_coordinate.width = cur->width;
+                cur_key_coordinate.height = cur->height;
+            }
+
+            m_focus_window = windows->get_base_window();
+            m_focus_key = get_next_candidate_key(HIGHLIGHT_NAVIGATE_NONE, cur_key_coordinate, windows->get_base_window()).candidate;
+    }
+}
+
+/**
+ * Resets the navigation info
+ */
+void
+CSCLKeyFocusHandler::reset_key_navigation_info(sclwindow window)
+{
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    if (windows) {
+        if (windows->is_base_window(window)) {
+            m_focus_window = window;
+            m_focus_key = 0;
+        }
+    }
+}
+
+/**
+ * Compares the sub-layout values
+ */
+inline bool
+CSCLKeyFocusHandler::sub_layout_match(sclchar *layout1, sclchar *layout2)
+{
+    if (layout1) {
+        if (layout2) {
+            if (strcmp(layout1, layout2) == 0) {
+                return TRUE;
+            }
+        }
+    } else if (layout2) {
+        return FALSE;
+    } else {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/**
+ * Builds the key navigation info
+ */
+void
+CSCLKeyFocusHandler::update_key_navigation_info(sclwindow window, scl8 index, SclLayoutKeyCoordinatePointer p_next_key)
+{
+}
+
+/**
+ * Finalize the navigation info
+ */
+void
+CSCLKeyFocusHandler::finalize_key_navigation_info(sclwindow window)
+{
+}
+
+/**
+ * Initializes the key index to first key of first row
+ */
+void
+CSCLKeyFocusHandler::init_key_index()
+{
+}
+
+/**
+ * Returns the currently focused key index
+ */
+scl8
+CSCLKeyFocusHandler::get_current_focus_key(void)
+{
+    return m_focus_key;
+}
+
+/**
+ * Returns the currently focused window
+ */
+sclwindow
+CSCLKeyFocusHandler::get_current_focus_window(void)
+{
+    return m_focus_window;
+}
+
+#ifndef min
+#define min(a, b)    (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a, b)    (((a) > (b)) ? (a) : (b))
+#endif
+/* If 2 lines overlap, this will return minus value of overlapping length,
+    and return positive distance value otherwise */
+int calculate_distance(int start_1, int end_1, int start_2, int end_2)
+{
+    return -1 * (min(end_1, end_2) - max(start_1, start_2));
+}
+
+/**
+ * Computes and Returns the key index for next focussed key depending upon the navigation direction
+ */
+NEXT_CANDIDATE_INFO
+CSCLKeyFocusHandler::get_next_candidate_key(SCLHighlightNavigationDirection direction, SclRectangle cur, sclwindow window)
+{
+    NEXT_CANDIDATE_INFO ret;
+    ret.candidate = NOT_USED;
+    ret.candidate_otherside = NOT_USED;
+
+    int candidate = NOT_USED;
+    int candidate_distance_x = INT_MAX;
+    int candidate_distance_y = INT_MAX;
+    int startpos_identical = FALSE;
+
+    int otherside_candidate = NOT_USED;
+
+    sclshort layout = NOT_USED;
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = NULL;
+
+    if (context && windows && sclres_manager) {
+        sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
+
+        if (windows->is_base_window(window)) {
+            layout = context->get_base_layout();
+        } else {
+            layout = context->get_popup_layout(window);
+        }
+    }
+
+    if (windows && cache && context &&
+        sclres_layout_key_coordinate_pointer_frame && scl_check_arrindex(layout, MAX_SCL_LAYOUT)) {
+        for (sclint loop = 0;loop < MAX_KEY; loop++) {
+            SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout][loop];
+            if (p && (loop != m_focus_key || window != m_focus_window)) {
+                if (p->sub_layout && context->get_cur_sublayout()) {
+                    if (!sub_layout_match(p->sub_layout, context->get_cur_sublayout())) {
+                        continue;
+                    }
+                }
+                SclWindowContext *window_context = windows->get_window_context(window);
+                SclRectangle btn = {0, 0, 0, 0};
+                if (window_context) {
+                    btn.x = p->x + window_context->geometry.x;
+                    btn.y = p->y + window_context->geometry.y;
+                    btn.width = p->width;
+                    btn.height = p->height;
+                }
+                if (windows->is_base_window(window)) {
+                    btn.x += cache->get_custom_starting_coordinates().x;
+                    btn.y += cache->get_custom_starting_coordinates().y;
+                }
+
+                int temp_distance_x;
+                int temp_distance_y;
+
+                switch (direction) {
+                    case HIGHLIGHT_NAVIGATE_LEFT:
+                        temp_distance_y = calculate_distance(btn.y, btn.y + btn.height, cur.y, cur.y + cur.height);
+                        //if (temp_distance_y <= candidate_distance_y) {
+                        if (temp_distance_y <= candidate_distance_y && temp_distance_y < 0) {
+                            /* If the button is closer in Y axis, consider this to be the closer regardless of X */
+                            if (temp_distance_y < candidate_distance_y) {
+                                /* Only if the ypos were not the same */
+                                if (!startpos_identical) {
+                                    candidate_distance_x = INT_MAX;
+                                }
+                            }
+                            /* Save for otherside */
+                            otherside_candidate = loop;
+                            temp_distance_x = calculate_distance(btn.x, btn.x + btn.width, cur.x, cur.x + cur.width);
+                            if (temp_distance_x < candidate_distance_x) {
+                                if (btn.x < cur.x) {
+                                    candidate = loop;
+                                    candidate_distance_x = temp_distance_x;
+                                    candidate_distance_y = temp_distance_y;
+                                    startpos_identical = (btn.y == cur.y);
+                                }
+                            }
+                        }
+                        break;
+                    case HIGHLIGHT_NAVIGATE_RIGHT:
+                        temp_distance_y = calculate_distance(btn.y, btn.y + btn.height, cur.y, cur.y + cur.height);
+                        //if (temp_distance_y <= candidate_distance_y) {
+                        if (temp_distance_y <= candidate_distance_y && temp_distance_y < 0) {
+                            /* If the button is closer in Y axis, consider this to be the closer regardless of X */
+                            if (temp_distance_y < candidate_distance_y) {
+                                /* Only if the ypos were not the same */
+                                if (!startpos_identical) {
+                                    candidate_distance_x = INT_MAX;
+                                }
+                            }
+                            /* Save for otherside */
+                            if (otherside_candidate == NOT_USED) {
+                                otherside_candidate = loop;
+                            }
+                            temp_distance_x = calculate_distance(btn.x, btn.x + btn.width, cur.x, cur.x + cur.width);
+                            if (temp_distance_x < candidate_distance_x) {
+                                if (btn.x > cur.x) {
+                                    candidate = loop;
+                                    candidate_distance_x = temp_distance_x;
+                                    candidate_distance_y = temp_distance_y;
+                                    startpos_identical = (btn.y == cur.y);
+                                }
+                            }
+                        }
+                        break;
+                    case HIGHLIGHT_NAVIGATE_UP:
+                        temp_distance_x = calculate_distance(btn.x, btn.x + btn.width, cur.x, cur.x + cur.width);
+                        if (temp_distance_x <= candidate_distance_x) {
+                            /* If the button is closer in X axis, consider this to be the closer regardless of Y */
+                            if (temp_distance_x < candidate_distance_x) {
+                                /* Only if the xpos were not the same */
+                                if (!startpos_identical) {
+                                    candidate_distance_y = INT_MAX;
+                                }
+                            }
+                            temp_distance_y = calculate_distance(btn.y, btn.y + btn.height, cur.y, cur.y + cur.height);
+                            if (temp_distance_y < candidate_distance_y) {
+                                if (btn.y < cur.y) {
+                                    candidate = loop;
+                                    candidate_distance_x = temp_distance_x;
+                                    candidate_distance_y = temp_distance_y;
+                                    startpos_identical = (btn.x == cur.x);
+                                }
+                            }
+                        }
+                        break;
+                    case HIGHLIGHT_NAVIGATE_DOWN:
+                        temp_distance_x = calculate_distance(btn.x, btn.x + btn.width, cur.x, cur.x + cur.width);
+                        if (temp_distance_x <= candidate_distance_x) {
+                            /* If the button is closer in X axis, consider this to be the closer regardless of Y */
+                            if (temp_distance_x < candidate_distance_x) {
+                                /* Only if the xpos were not the same */
+                                if (!startpos_identical) {
+                                    candidate_distance_y = INT_MAX;
+                                }
+                            }
+                            temp_distance_y = calculate_distance(btn.y, btn.y + btn.height, cur.y, cur.y + cur.height);
+                            if (temp_distance_y < candidate_distance_y) {
+                                if (btn.y > cur.y) {
+                                    candidate = loop;
+                                    candidate_distance_x = temp_distance_x;
+                                    candidate_distance_y = temp_distance_y;
+                                    startpos_identical = (btn.x == cur.x);
+                                }
+                            }
+                        }
+                        break;
+                    default:
+                        temp_distance_y = calculate_distance(btn.y, btn.y + btn.height, cur.y, cur.y + cur.height);
+                        if (temp_distance_y <= candidate_distance_y) {
+                            temp_distance_x = calculate_distance(btn.x, btn.x + btn.width, cur.x, cur.x + cur.width);
+                            if (temp_distance_x <= candidate_distance_x) {
+                                candidate = loop;
+                                candidate_distance_x = temp_distance_x;
+                                candidate_distance_y = temp_distance_y;
+                            }
+                        }
+                        break;
+                }
+            }
+        }
+
+        ret.candidate = candidate;
+        ret.candidate_otherside = otherside_candidate;
+    }
+
+    return ret;
+}
+
+static void copy_rectangle(SclLayoutKeyCoordinatePointer src, SclRectangle *dest)
+{
+    if (src && dest) {
+        (dest)->x = (src)->x;
+        (dest)->y = (src)->y;
+        (dest)->width = (src)->width;
+        (dest)->height = (src)->height;
+    }
+}
+
+void
+CSCLKeyFocusHandler::process_navigation(SCLHighlightNavigationDirection direction)
+{
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!context || !windows || !handler || !cache || !sclres_manager) return;
+
+    sclshort layout = NOT_USED;
+
+    sclwindow prev_window = m_focus_window;
+    scl8 prev_key = m_focus_key;
+    sclwindow next_window = m_focus_window;
+    scl8 next_key = m_focus_key;
+
+    PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = NULL;
+
+    if (context && windows && handler && sclres_manager) {
+        sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
+
+        if (windows->is_base_window(m_focus_window)) {
+            layout = context->get_base_layout();
+        } else {
+            layout = context->get_popup_layout(m_focus_window);
+        }
+    }
+
+    if (sclres_layout_key_coordinate_pointer_frame && context->get_highlight_ui_enabled() &&
+        scl_check_arrindex(layout, MAX_SCL_LAYOUT) && scl_check_arrindex(m_focus_key, MAX_KEY)) {
+        SclLayoutKeyCoordinatePointer cur = sclres_layout_key_coordinate_pointer_frame[layout][m_focus_key];
+
+        /* To compare with buttons in popup window, let's convert to global coordinates */
+        SclWindowContext *window_context = windows->get_window_context(m_focus_window);
+        SclRectangle cur_key_coordinate = {0, 0, 0, 0};
+        if (window_context && cur && cache) {
+            cur_key_coordinate.x = cur->x + window_context->geometry.x;
+            cur_key_coordinate.y = cur->y + window_context->geometry.y;
+            cur_key_coordinate.width = cur->width;
+            cur_key_coordinate.height = cur->height;
+
+            if (windows->is_base_window(m_focus_window)) {
+                cur_key_coordinate.x += cache->get_custom_starting_coordinates().x;
+                cur_key_coordinate.y += cache->get_custom_starting_coordinates().y;
+            }
+        }
+
+        NEXT_CANDIDATE_INFO base_candidate;
+        base_candidate.candidate = base_candidate.candidate_otherside = NOT_USED;
+        NEXT_CANDIDATE_INFO popup_candidate;
+        popup_candidate.candidate = popup_candidate.candidate_otherside = NOT_USED;
+        sclboolean search_in_base_window = TRUE;
+        sclboolean exclude_popup_covered_area = FALSE;
+
+        if (windows && !windows->is_base_window(windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP))) {
+            if (cache && window_context && scl_check_arrindex(window_context->inputmode, MAX_SCL_INPUT_MODE)) {
+                const SclLayout *cur_layout =
+                    cache->get_cur_layout(windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP));
+                if (cur_layout) {
+                    if (!(cur_layout->use_sw_background) || cur_layout->bg_color.a != 0) {
+                        const PSclInputModeConfigure sclres_input_mode_configure =
+                            sclres_manager->get_input_mode_configure_table();
+                        if (sclres_input_mode_configure && sclres_input_mode_configure[window_context->inputmode].use_dim_window) {
+                            search_in_base_window = FALSE;
+                        } else {
+                            exclude_popup_covered_area = TRUE;
+                        }
+                    }
+                }
+            }
+            popup_candidate = get_next_candidate_key(direction, cur_key_coordinate,
+                windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP));
+        }
+        /* Now search buttons in base window */
+        if (search_in_base_window && windows) {
+            base_candidate = get_next_candidate_key(direction, cur_key_coordinate, windows->get_base_window());
+        }
+
+        if (popup_candidate.candidate == NOT_USED && base_candidate.candidate != NOT_USED) {
+            next_window = windows->get_base_window();
+            next_key = base_candidate.candidate;
+        } else if (popup_candidate.candidate != NOT_USED && base_candidate.candidate == NOT_USED) {
+            next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+            next_key = popup_candidate.candidate;
+        } else if (popup_candidate.candidate == NOT_USED && base_candidate.candidate == NOT_USED) {
+            if (base_candidate.candidate_otherside != NOT_USED) {
+                next_window = windows->get_base_window();
+                next_key = base_candidate.candidate_otherside;
+            } else if (popup_candidate.candidate_otherside != NOT_USED) {
+                next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                next_key = popup_candidate.candidate_otherside;
+            }
+        } else {
+            /* Compare those 2 candidates */
+            sclwindow popup_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+            sclshort base_layout = context->get_base_layout();
+            sclshort popup_layout = context->get_popup_layout(popup_window);
+
+            SclLayoutKeyCoordinatePointer base_key = NULL;
+            SclLayoutKeyCoordinatePointer popup_key = NULL;
+            SclWindowContext *base_window_context = NULL;
+            SclWindowContext *popup_window_context = NULL;
+
+            if (scl_check_arrindex(base_layout, MAX_SCL_LAYOUT) && scl_check_arrindex(popup_layout, MAX_SCL_LAYOUT)) {
+                base_key = sclres_layout_key_coordinate_pointer_frame[base_layout][base_candidate.candidate];
+                popup_key = sclres_layout_key_coordinate_pointer_frame[popup_layout][popup_candidate.candidate];
+                base_window_context = windows->get_window_context(windows->get_base_window());
+                popup_window_context = windows->get_window_context(popup_window);
+            }
+
+            SclRectangle base_key_coordinate = {0, 0, 0, 0};
+            if (base_window_context) {
+                base_key_coordinate.x = base_key->x + base_window_context->geometry.x;
+                base_key_coordinate.y = base_key->y + base_window_context->geometry.y;
+                base_key_coordinate.width = base_key->width;
+                base_key_coordinate.height = base_key->height;
+
+                base_key_coordinate.x += cache->get_custom_starting_coordinates().x;
+                base_key_coordinate.y += cache->get_custom_starting_coordinates().y;
+            }
+
+            SclRectangle popup_key_coordinate = {0, 0, 0, 0};
+            if (popup_window_context) {
+                popup_key_coordinate.x = popup_key->x + popup_window_context->geometry.x;
+                popup_key_coordinate.y = popup_key->y + popup_window_context->geometry.y;
+                popup_key_coordinate.width = popup_key->width;
+                popup_key_coordinate.height = popup_key->height;
+            }
+
+            if (exclude_popup_covered_area) {
+                CSCLUtils *utils = CSCLUtils::get_instance();
+                if (utils && popup_window_context) {
+                    /* If the base candidate key is covered by popup window, do not choose it */
+                    if (utils->is_rect_overlap(base_key_coordinate, popup_window_context->geometry)) {
+                        base_candidate.candidate = NOT_USED;
+                    }
+                }
+            }
+            /* If the base candidate key wasn't excluded */
+            if (base_candidate.candidate != NOT_USED) {
+                int base_distance_x = INT_MAX;
+                int base_distance_y = INT_MAX;
+                int popup_distance_x = INT_MAX;
+                int popup_distance_y = INT_MAX;
+
+                base_distance_x = calculate_distance(
+                    cur_key_coordinate.x, cur_key_coordinate.x + cur_key_coordinate.width,
+                    base_key_coordinate.x, base_key_coordinate.x + base_key_coordinate.width);
+                base_distance_y = calculate_distance(
+                    cur_key_coordinate.y, cur_key_coordinate.y + cur_key_coordinate.height,
+                    base_key_coordinate.y, base_key_coordinate.y + base_key_coordinate.height);
+
+                popup_distance_x = calculate_distance(
+                    cur_key_coordinate.x, cur_key_coordinate.x + cur_key_coordinate.width,
+                    popup_key_coordinate.x, popup_key_coordinate.x + popup_key_coordinate.width);
+                popup_distance_y = calculate_distance(
+                    cur_key_coordinate.y, cur_key_coordinate.y + cur_key_coordinate.height,
+                    popup_key_coordinate.y, popup_key_coordinate.y + popup_key_coordinate.height);
+
+                if (direction == HIGHLIGHT_NAVIGATE_LEFT || direction == HIGHLIGHT_NAVIGATE_RIGHT) {
+                    int minimum_distance = -1 * (cur_key_coordinate.height / 3);
+                    if (base_distance_y > minimum_distance && popup_distance_y > minimum_distance) {
+                        minimum_distance = 0;
+                    }
+                    if (base_distance_y < minimum_distance && popup_distance_y < minimum_distance) {
+                        if (base_distance_x < popup_distance_x) {
+                            next_window = windows->get_base_window();
+                            next_key = base_candidate.candidate;
+                        } else {
+                            next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                            next_key = popup_candidate.candidate;
+                        }
+                    } else if (base_distance_y < minimum_distance) {
+                        next_window = windows->get_base_window();
+                        next_key = base_candidate.candidate;
+                    } else {
+                        next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                        next_key = popup_candidate.candidate;
+                    }
+                } else if (direction == HIGHLIGHT_NAVIGATE_UP || direction == HIGHLIGHT_NAVIGATE_DOWN) {
+                    int minimum_distance = -1 * (cur_key_coordinate.width / 3);
+                    if (base_distance_x > minimum_distance && popup_distance_x > minimum_distance) {
+                        minimum_distance = 0;
+                    }
+                    if (base_distance_x < minimum_distance && popup_distance_x < minimum_distance) {
+                        if (base_distance_y < popup_distance_y) {
+                            next_window = windows->get_base_window();
+                            next_key = base_candidate.candidate;
+                        } else {
+                            next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                            next_key = popup_candidate.candidate;
+                        }
+                    } else if (base_distance_x < minimum_distance) {
+                        next_window = windows->get_base_window();
+                        next_key = base_candidate.candidate;
+                    } else {
+                        next_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                        next_key = popup_candidate.candidate;
+                    }
+                }
+            }
+        }
+
+        SclNotiHighlightNavigateDesc desc;
+        desc.direction = direction;
+        desc.window_from = prev_window;
+        desc.key_from = prev_key;
+        desc.window_to = next_window;
+        desc.key_to = next_key;
+        if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_HIGHLIGHT_NAVIGATE, &desc)) {
+            CSCLAnimator *animator = CSCLAnimator::get_instance();
+            if (animator) {
+                sclboolean start_animation = FALSE;
+                if (windows->is_base_window(desc.window_to) && windows->is_base_window(desc.window_from)) {
+                    if (desc.key_to != desc.key_from) {
+                        start_animation = TRUE;
+                    }
+                } else {
+                    SclWindowContext *window_context_from = windows->get_window_context(desc.window_from);
+                    SclWindowContext *window_context_to = windows->get_window_context(desc.window_to);
+                    if (window_context_from && window_context_to) {
+                        if ((windows->is_base_window(desc.window_from) || window_context_from->is_virtual) &&
+                            (windows->is_base_window(desc.window_to) || window_context_to->is_virtual)) {
+                                start_animation = TRUE;
+                        }
+                    }
+                }
+                sclshort layout_from = NOT_USED;
+                sclshort layout_to = NOT_USED;
+                if (windows->is_base_window(desc.window_from)) {
+                    layout_from = context->get_base_layout();
+                } else {
+                    layout_from = context->get_popup_layout(desc.window_from);
+                }
+                if (windows->is_base_window(desc.window_to)) {
+                    layout_to = context->get_base_layout();
+                } else {
+                    layout_to = context->get_popup_layout(desc.window_to);
+                }
+                if (!scl_check_arrindex(desc.key_from, MAX_KEY) || !scl_check_arrindex(desc.key_to, MAX_KEY) ||
+                    !scl_check_arrindex(layout_from, MAX_SCL_LAYOUT) || !scl_check_arrindex(layout_to, MAX_SCL_LAYOUT)) {
+                    start_animation = FALSE;
+                }
+                if (start_animation &&
+                    context->get_highlight_ui_enabled() &&
+                    context->get_highlight_ui_animation_enabled() &&
+                    animator->check_animation_supported()) {
+                        SclLayoutKeyCoordinatePointer prev_coordinate =
+                            sclres_layout_key_coordinate_pointer_frame[layout_from][desc.key_from];
+                        SclLayoutKeyCoordinatePointer next_coordinate =
+                            sclres_layout_key_coordinate_pointer_frame[layout_to][desc.key_to];
+
+                        SclRectangle prev_rect;
+                        SclRectangle next_rect;
+                        copy_rectangle(prev_coordinate, &(prev_rect));
+                        copy_rectangle(next_coordinate, &(next_rect));
+
+                        if (windows->is_base_window(desc.window_from)) {
+                            prev_rect.x += cache->get_custom_starting_coordinates().x;
+                            prev_rect.y += cache->get_custom_starting_coordinates().y;
+                        } else {
+                            /* Convert popup window coordinates relative to base window */
+                            SclWindowContext *base_window_context =
+                                windows->get_window_context(windows->get_base_window());
+                            SclWindowContext *prev_window_context =
+                                windows->get_window_context(desc.window_from);
+                            if (base_window_context && prev_window_context) {
+                                prev_rect.x += (prev_window_context->geometry.x - base_window_context->geometry.x);
+                                prev_rect.y += (prev_window_context->geometry.y - base_window_context->geometry.y);
+                            }
+                        }
+                        if (windows->is_base_window(desc.window_to)) {
+                            next_rect.x += cache->get_custom_starting_coordinates().x;
+                            next_rect.y += cache->get_custom_starting_coordinates().y;
+                        } else {
+                            /* Convert popup window coordinates relative to base window */
+                            SclWindowContext *base_window_context =
+                                windows->get_window_context(windows->get_base_window());
+                            SclWindowContext *next_window_context =
+                                windows->get_window_context(desc.window_to);
+                            if (base_window_context && next_window_context) {
+                                next_rect.x += (next_window_context->geometry.x - base_window_context->geometry.x);
+                                next_rect.y += (next_window_context->geometry.y - base_window_context->geometry.y);
+                            }
+                        }
+                        /* Let's check if the navigation animation should be in circular movement */
+                        sclboolean circular = FALSE;
+                        /* If our 2 buttons overlap in Y axis */
+                        if (calculate_distance(
+                            prev_rect.y, prev_rect.y + prev_rect.height,
+                            next_rect.y, next_rect.y + next_rect.height) < 0) {
+                                /* And if those 2 buttons are side buttons, let's run the animation in circular mode */
+                                if (prev_coordinate->is_side_button && next_coordinate->is_side_button) {
+                                    circular = TRUE;
+                                }
+                        }
+
+                        sclint id = animator->find_animator_by_type(ANIMATION_TYPE_HIGHLIGHT_UI);
+                        if (id == NOT_USED) {
+                            SclAnimationDesc animdesc;
+                            animdesc.type = ANIMATION_TYPE_HIGHLIGHT_UI;
+                            animdesc.length = SCL_ANIMATION_TIME;
+
+                            animdesc.rect_from = prev_rect;
+                            animdesc.rect_to = next_rect;
+
+                            animdesc.window_from = desc.window_from;
+                            animdesc.window_to = desc.window_to;
+                            animdesc.circular = circular;
+
+                            id = animator->create_animator(&animdesc);
+                            animator->start_animator(id);
+                        } else {
+                            SclAnimationState *state = animator->get_animation_state(id);
+                            if (state) {
+                                if (state->active) {
+                                    /* FIXME : When we have time later,
+                                        let's use the currect rect so that the animation starts from the current position,
+                                        considering the circular movement case */
+                                    //state->desc.rect_from = state->rect_cur;
+                                    state->desc.rect_from = prev_rect;
+                                } else {
+                                    state->active = TRUE;
+                                    state->desc.rect_from = prev_rect;
+                                }
+                                state->step = 0;
+                                state->desc.circular = circular;
+
+                                state->desc.rect_to = next_rect;
+
+                                state->desc.window_from = desc.window_from;
+                                state->desc.window_to = desc.window_to;
+                            }
+                            animator->start_animator(id);
+                        }
+                }
+            }
+            m_focus_window = desc.window_to;
+            m_focus_key = desc.key_to;
+        }
+    }
+}
+
+void
+CSCLKeyFocusHandler::set_current_focus(sclwindow window, scl8 index)
+{
+    m_focus_window = window;
+    m_focus_key = index;
+}
+
+#ifdef TARGET_EMULATOR
+
+/**
+ * callback for window show event (sniffer window)
+ */
+static void sniffer_window_show_cb(void *data, Evas *e, Evas_Object *obj, void *event)
+{
+    LOGD("INSIDE =-=-=-=- x_event_sniffer_window_show_cb, Trying to Grab Key Board : \n");
+#ifndef WAYLAND
+    Eina_Bool ret = ecore_x_keyboard_grab(x_window);
+
+    if (EINA_TRUE == ret) {
+        LOGD("Keyboard Grabbed successfully by sniffer\n");
+    } else {
+        LOGD("Failed to Grab keyboard by sniffer\n");
+    }
+#endif
+}
+
+/**
+ * sniffer window creation function, the keyboard would be grabbed by this window in case of Tizen Emulator
+ */
+void
+CSCLKeyFocusHandler::create_sniffer_window(void)
+{
+    LOGD("CSCLKeyFocusHandler : INSIDE =-=-=-=- create_sniffer_window : \n");
+    Evas_Object *win = NULL;
+
+    win = elm_win_add(NULL, "KEY_SNIFFER", ELM_WIN_UTILITY);
+
+    elm_win_borderless_set(win, EINA_TRUE);
+    elm_win_alpha_set(win, EINA_FALSE);
+    elm_win_title_set(win, "KEY_SNIFFER");
+    elm_win_fullscreen_set(win, EINA_FALSE);
+    set_window_accepts_focus(win, FALSE);
+    evas_object_show(win);
+    evas_object_resize(win, 100, 100);
+    m_sniffer = win;
+
+    evas_object_event_callback_add(win, EVAS_CALLBACK_SHOW, sniffer_window_show_cb, NULL);
+}
+
+void
+CSCLKeyFocusHandler::set_window_accepts_focus(const sclwindow window, sclboolean acceptable)
+{
+    elm_win_prop_focus_skip_set(static_cast<Evas_Object*>(window), !acceptable);
+}
+
+
+#endif
+
+
diff --git a/scl/sclkeyfocushandler.h b/scl/sclkeyfocushandler.h
new file mode 100644 (file)
index 0000000..9f0e81c
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2012 - 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 "scltypes.h"
+#include "sclres_type.h"
+#ifndef __SCL_KEY_FOCUS_HANDLER_H__
+#define __SCL_KEY_FOCUS_HANDLER_H__
+
+//#define TARGET_EMULATOR
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+
+#define NAVI_INFO_MAX_ROWS  20
+#define NAVI_INFO_MAX_COLS  20
+
+typedef struct {
+    scl8 candidate;
+    scl8 candidate_otherside;
+} NEXT_CANDIDATE_INFO;
+
+/*
+typedef struct _SclKeyboardRowInfo {
+    sclbyte start_index;
+    sclbyte size;
+    sclchar *sub_layout;
+    sclshort col_coord[NAVI_INFO_MAX_COLS];
+}SclKeyboardRowInfo;
+
+typedef struct _SclKeyFocusNavigationInfo {
+    sclbyte total_rows;
+    sclshort row_coord;
+    SclKeyboardRowInfo* rows[NAVI_INFO_MAX_ROWS];
+}SclKeyFocusNavigationInfo;
+
+typedef struct _SclPopupRelativeKeyInfo {
+    sclbyte index;
+    sclwindow window;
+}SclPopupRelativeKeyInfo;
+
+typedef struct _SclPopupRowInfo {
+    sclbyte start_index;
+    sclbyte size;
+    sclshort col_coord[NAVI_INFO_MAX_COLS];
+    SclPopupRelativeKeyInfo nexts[NAVI_INFO_MAX_COLS][NAVIGATE_MAX];
+}SclPopupRowInfo;
+
+typedef struct _SclPopupNavigationInfo {
+    sclbyte total_rows;
+    sclshort row_coord;
+    SclPopupRowInfo* rows[NAVI_INFO_MAX_ROWS];
+}SclPopupNavigationInfo;
+*/
+
+/**
+* @brief The class to store key focus navigation information
+*
+* This class implements functions to support key focus navigation on the software keyboard
+* using remote controller input. It generates navigation information for the currently loaded
+* keyboard layout and provides the index of next key depending upon the navigation direction.
+* The key information can be retrieved from the array of key coordinates from Resource Cache.
+*
+* Apart from key navigation information, this class also provides functions to grab and ungrab
+* the remote controller keys.
+*
+* The public interface can be divided in three categories :
+* 1. Focus grab/ungrab API : Invoked while showing and hiding the software keyboard
+* - Client class: CSCLWindowsImplEfl
+* 2. Focus navigation info building API : Invoked while computing layout of the current keyboard
+* - Client class/function: CSCLResourceCache::recompute_layout
+* 3. Focus navigation API: Invoked while handling remote controller key press events
+* - Client class: CSCLEventsImplEfl
+*/
+class CSCLKeyFocusHandler
+{
+public:
+    virtual ~CSCLKeyFocusHandler();
+
+    static CSCLKeyFocusHandler* get_instance();
+
+#ifdef USING_KEY_GRAB
+    /*Focus grab/ungrab API*/
+    bool grab_keyboard(const sclwindow parent);
+    void ungrab_keyboard(const sclwindow parent);
+#endif
+
+    /*Focus navigation info building API*/
+    void reset_key_navigation_info(sclwindow window);
+    void update_key_navigation_info(sclwindow window, scl8 index, SclLayoutKeyCoordinatePointer p_next_key);
+    void finalize_key_navigation_info(sclwindow window);
+
+    void popup_opened(sclwindow window);
+    void popup_closed(sclwindow window);
+
+    /*Focus navigation API*/
+    void init_key_index();
+    scl8 get_current_focus_key(void);
+    sclwindow get_current_focus_window(void);
+    void process_navigation(SCLHighlightNavigationDirection direction);
+
+    void set_current_focus(sclwindow window, scl8 index);
+
+private:
+    NEXT_CANDIDATE_INFO get_next_candidate_key(SCLHighlightNavigationDirection direction, SclRectangle cur, sclwindow window);
+
+    sclwindow m_focus_window;
+    scl8 m_focus_key;
+
+#ifdef USING_KEY_GRAB
+    bool m_keyboard_grabbed;
+#endif
+    bool sub_layout_match(sclchar *layout1, sclchar *layout2);
+
+    CSCLKeyFocusHandler();
+#ifdef TARGET_EMULATOR
+    sclwindow m_sniffer;
+    void create_sniffer_window(void);
+    void set_window_accepts_focus(const sclwindow window, sclboolean acceptable);
+#endif
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif
diff --git a/scl/sclres.cpp b/scl/sclres.cpp
new file mode 100644 (file)
index 0000000..c6abfd0
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012 - 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 "sclres.h"
+
+using namespace sclres;
+
+SclRes::SclRes()
+{
+    m_resource_directory.clear();
+}
+
+SclRes::~SclRes()
+{
+}
+
+void
+SclRes::set_resource_directory(const char *directory)
+{
+    m_resource_directory = directory;
+}
+
+const char*
+SclRes::get_resource_directory()
+{
+    return m_resource_directory.c_str();
+}
diff --git a/scl/sclres.h b/scl/sclres.h
new file mode 100644 (file)
index 0000000..dbbbf92
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012 - 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 __SCLRES__
+#define __SCLRES__
+#include "sclres_type.h"
+#include <string>
+
+namespace sclres {
+class SclRes{
+public:
+    SclRes();
+    virtual ~SclRes();
+
+    /* Inform the SclRes where the resource files are */
+    virtual void set_resource_directory(const char *directory);
+    /* Returns the current filepath where the resource files are */
+    virtual const char* get_resource_directory();
+
+public: /* These are the functions need to be implemented by the descendants of SclRes */
+    /* Initialize SclRes, with the given entry file that exists under the resource directory */
+    virtual void init(const char *entry_filename) = 0;
+    virtual void reload() = 0;
+
+    /* These functions are for dynamic (lazy) loading layouts */
+    virtual void load(int layout_id) = 0;
+    virtual void unload() = 0;
+    virtual bool loaded(int layout_id) = 0;
+
+    /* Functions returning the SCL structure containing the information described in resource files */
+    virtual PSclInputModeConfigure get_input_mode_configure_table() = 0;
+    virtual PSclLayout get_layout_table() = 0;
+    virtual PSclLayoutKeyCoordinatePointerTable get_key_coordinate_pointer_frame() = 0;
+    virtual PSclModifierDecoration get_modifier_decoration_table() = 0;
+    virtual PSclLabelPropertiesTable get_label_properties_frame() = 0;
+    virtual PSclDefaultConfigure get_default_configure() = 0;
+    virtual PSclAutoPopupConfigure get_autopopup_configure() = 0;
+    virtual PSclMagnifierWndConfigure get_magnifier_configure() = 0;
+
+    /* Functions returning specific data described in resource files */
+    virtual int get_inputmode_id(const char* name) = 0;
+    virtual const char* get_inputmode_name(int id) = 0;
+    virtual int get_inputmode_size() = 0;
+    virtual int get_layout_id(const char* name) = 0;
+    virtual int get_layout_size() = 0;
+    virtual int get_labelproperty_size() = 0;
+    virtual int get_modifier_decoration_id(const char *name) = 0;
+    virtual bool get_nine_patch_info(const char *filename, SclNinePatchInfo *info) = 0;
+
+    /* Function returning the name of current SclRes instance */
+    virtual const char* get_name() = 0;
+
+private:
+    std::string m_resource_directory;
+};
+}
+
+#endif
+
diff --git a/scl/sclres_manager.cpp b/scl/sclres_manager.cpp
new file mode 100644 (file)
index 0000000..b0a3769
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2012 - 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 "sclres_manager.h"
+#include "xmlresource.h"
+#include "binary_xmlresource.h"
+#include <assert.h>
+#include "simple_debug.h"
+using namespace xmlresource;
+using namespace binary_xmlresource;
+using namespace sclres;
+#include "put_record.h"
+
+static sclres::SclRes *_current_parser = NULL;
+
+SclResParserManager::~SclResParserManager() {
+    _current_parser = NULL;
+    m_initialized = false;
+}
+
+SclResParserManager*
+SclResParserManager::get_instance() {
+    static SclResParserManager instance;
+    return &instance;
+}
+
+SclResParserManager::SclResParserManager() {
+    _current_parser = NULL;
+    m_initialized = false;
+}
+
+void
+SclResParserManager::init(const SCLParserType parser_type, const char *entry_filepath) {
+    if (!m_initialized) {
+        if (parser_type == SCL_PARSER_TYPE_XML) {
+            SCLLOG(SclLog::MESSAGE, "Use text xml\n");
+            _current_parser = XMLResource::get_instance();
+        } else if (parser_type == SCL_PARSER_TYPE_BINARY_XML) {
+            SCLLOG(SclLog::MESSAGE, "Use binary xml\n");
+            _current_parser = BinResource::get_instance();
+        }
+
+        /* Let's acquire the directory information from filepath */
+        std::string str = entry_filepath;
+        size_t found;
+        found = str.find_last_of("/\\");
+
+        std::string filepath = str.substr(0, found);
+        std::string filename = str.substr(found + 1);
+
+        //assert(_current_parser != NULL);
+        if (_current_parser != NULL) {
+            /* Assume the directory where the main entry file exists, is the default resource directory */
+            _current_parser->set_resource_directory(filepath.c_str());
+            _current_parser->init(filename.c_str());
+#ifdef __SCL_TXT_DEBUG
+            put_autopopup_configure(PARSER, *(_current_parser->get_autopopup_configure()));
+            put_default_configure(PARSER, *(_current_parser->get_default_configure()));
+            put_input_mode_configure_table(PARSER, _current_parser->get_input_mode_configure_table());
+            put_key_coordinate_frame(PARSER, _current_parser->get_key_coordinate_pointer_frame());
+            put_label_properties_frame(PARSER, _current_parser->get_label_properties_frame());
+            put_layout_table(PARSER, _current_parser->get_layout_table());
+            put_magnifier_wnd_configure(PARSER, *(_current_parser->get_magnifier_configure()));
+            put_modifier_decoration(PARSER, _current_parser->get_modifier_decoration_table());
+            //put_nine_patch_info(PARSER, _current_parser->get_nine_patch_file_list());
+#endif
+        }
+        m_initialized = true;
+    }
+}
+
+void
+SclResParserManager::load(int layout_id) {
+    if (_current_parser) {
+        _current_parser->load(layout_id);
+    }
+}
+
+void
+SclResParserManager::unload() {
+    if (_current_parser) {
+        _current_parser->unload();
+    }
+}
+
+bool
+SclResParserManager::loaded(int layout_id) {
+    if (_current_parser == NULL) return false;
+
+    return _current_parser->loaded(layout_id);
+}
+
+void
+SclResParserManager::reload() {
+    if (_current_parser) {
+        _current_parser->reload();
+    }
+}
+
+PSclInputModeConfigure
+SclResParserManager::get_input_mode_configure_table() {
+    if (_current_parser == NULL) return NULL;
+
+    return _current_parser->get_input_mode_configure_table();
+}
+
+PSclLayout
+SclResParserManager::get_layout_table() {
+    if (_current_parser == NULL) return NULL;
+
+    return _current_parser->get_layout_table();
+}
+
+PSclLayoutKeyCoordinatePointerTable
+SclResParserManager::get_key_coordinate_pointer_frame() {
+    if (_current_parser == NULL) return NULL;
+
+    return _current_parser->get_key_coordinate_pointer_frame();
+}
+
+PSclModifierDecoration
+SclResParserManager::get_modifier_decoration_table() {
+    if (_current_parser == NULL) return NULL;
+
+    return _current_parser->get_modifier_decoration_table();
+}
+
+PSclLabelPropertiesTable
+SclResParserManager::get_label_properties_frame() {
+    if (_current_parser == NULL) return NULL;
+
+    return _current_parser->get_label_properties_frame();
+}
+
+PSclDefaultConfigure
+SclResParserManager::get_default_configure() {
+    if (_current_parser == NULL) return NULL;
+
+    return _current_parser->get_default_configure();
+}
+
+PSclAutoPopupConfigure
+SclResParserManager::get_autopopup_configure() {
+    if (_current_parser == NULL) return NULL;
+
+    return _current_parser->get_autopopup_configure();
+}
+
+PSclMagnifierWndConfigure
+SclResParserManager::get_magnifier_configure() {
+    if (_current_parser == NULL) return NULL;
+
+    return _current_parser->get_magnifier_configure();
+}
+
+const char*
+SclResParserManager::get_resource_directory() {
+    if (_current_parser == NULL) return NULL;
+
+    return _current_parser->get_resource_directory();
+}
+
+int
+SclResParserManager::get_inputmode_id(const char *name) {
+    if (_current_parser == NULL) return -1;
+
+    return _current_parser->get_inputmode_id(name);
+}
+
+const char*
+SclResParserManager::get_inputmode_name(int id) {
+    if (_current_parser == NULL) return NULL;
+
+    return _current_parser->get_inputmode_name(id);
+}
+
+int
+SclResParserManager::get_inputmode_size() {
+    if (_current_parser == NULL) return 0;
+
+    return _current_parser->get_inputmode_size();
+}
+
+int
+SclResParserManager::get_layout_size() {
+    if (_current_parser == NULL) return 0;
+
+    return _current_parser->get_layout_size();
+}
+
+int
+SclResParserManager::get_layout_id(const char *name) {
+    if (_current_parser == NULL) return -1;
+
+    return _current_parser->get_layout_id(name);
+}
+
+int
+SclResParserManager::get_labelproperty_size() {
+    if (_current_parser == NULL) return 0;
+
+    return _current_parser->get_labelproperty_size();
+}
+
+int
+SclResParserManager::get_modifier_decoration_id(const char *name) {
+    if (_current_parser == NULL) return -1;
+
+    return _current_parser->get_modifier_decoration_id(name);
+}
+
+bool
+SclResParserManager::get_nine_patch_info(const char *filename, SclNinePatchInfo *info) {
+    if (_current_parser == NULL) return false;
+
+    return _current_parser->get_nine_patch_info(filename, info);
+}
+
+const char*
+SclResParserManager::get_name() {
+    if (_current_parser == NULL) return NULL;
+
+    return _current_parser->get_name();
+}
diff --git a/scl/sclres_manager.h b/scl/sclres_manager.h
new file mode 100644 (file)
index 0000000..4c4cb32
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012 - 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 __SCLRES_MANAGER__
+#define __SCLRES_MANAGER__
+#include "sclres_type.h"
+
+class SclResParserManager{
+    public:
+        ~SclResParserManager();
+        static SclResParserManager* get_instance();
+
+    public:
+        void init(const SCLParserType parser_type, const char *entry_filepath);
+
+        /* These functions are for dynamic (lazy) loading layouts */
+        void load(int layout_id);
+        void unload();
+        bool loaded(int layout_id);
+
+        void reload();
+
+        PSclInputModeConfigure get_input_mode_configure_table();
+        PSclLayout get_layout_table();
+        PSclLayoutKeyCoordinatePointerTable get_key_coordinate_pointer_frame();
+        PSclModifierDecoration get_modifier_decoration_table();
+        PSclLabelPropertiesTable get_label_properties_frame();
+        PSclDefaultConfigure get_default_configure();
+        PSclAutoPopupConfigure get_autopopup_configure();
+        PSclMagnifierWndConfigure get_magnifier_configure();
+
+        const char* get_resource_directory();
+        int get_inputmode_id(const char* name);
+        const char* get_inputmode_name(int id);
+        int get_inputmode_size();
+        int get_layout_size();
+        int get_layout_id(const char *name);
+        int get_labelproperty_size();
+        int get_modifier_decoration_id(const char *name);
+        bool get_nine_patch_info(const char *filename, SclNinePatchInfo *info);
+
+        const char* get_name();
+        void destroy();
+
+    private:
+        SclResParserManager();
+        bool m_initialized;
+};
+
+#endif
diff --git a/scl/sclres_type.h b/scl/sclres_type.h
new file mode 100644 (file)
index 0000000..506dcf0
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 - 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 __SCLRES_TYPE_H__
+#define __SCLRES_TYPE_H__
+
+#include "sclstructs.h"
+#include "sclresource.h"
+
+#define MAX_SCL_INPUT_MODE 128
+#define MAX_SCL_LAYOUT 128
+#define MAX_SCL_LABEL_PROPERTIES 128
+#define MAX_SCL_MODIFIER_DECORATION_NUM 64
+
+using namespace scl;
+
+typedef SclInputModeConfigure (*PSclInputModeConfigure);
+typedef SclLayout (*PSclLayout);
+
+typedef SclLayoutKeyCoordinate (*PSclLayoutKeyCoordinate);
+typedef SclLayoutKeyCoordinate (*PSclLayoutKeyCoordinateTable)[MAX_KEY];
+
+typedef SclLayoutKeyCoordinate (*SclLayoutKeyCoordinatePointer);
+typedef SclLayoutKeyCoordinatePointer (*PSclLayoutKeyCoordinatePointerTable)[MAX_KEY];
+
+typedef SclModifierDecoration (*PSclModifierDecoration);
+
+typedef SclLabelProperties (*PSclLabelProperties);
+typedef SclLabelProperties (*PSclLabelPropertiesTable)[MAX_SIZE_OF_LABEL_FOR_ONE];
+
+typedef SclDefaultConfigure (*PSclDefaultConfigure);
+typedef SclAutoPopupConfigure (*PSclAutoPopupConfigure);
+typedef SclMagnifierWndConfigure (*PSclMagnifierWndConfigure);
+
+#endif
+
diff --git a/scl/sclresourcecache.cpp b/scl/sclresourcecache.cpp
new file mode 100644 (file)
index 0000000..21b49ea
--- /dev/null
@@ -0,0 +1,1864 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+#include "sclresourcekeys.h"
+#include "sclresourcecache.h"
+#include "scldebug.h"
+#include "sclcontext.h"
+
+//#include "sclresource.h"
+#include "scluibuilder.h"
+#include "sclres_manager.h"
+#include <assert.h>
+#include <dlog.h>
+
+//Includes for CSCLKeyFocusHandler
+#include "sclkeyfocushandler.h"
+using namespace scl;
+
+CSCLResourceCache::CSCLResourceCache()
+{
+    SCL_DEBUG();
+
+    memset(mCurThemename, 0x00, sizeof(mCurThemename));
+
+    memset(&mCurBaseLayout, 0x00, sizeof(mCurBaseLayout));
+    memset(mCurPopupLayout, 0x00, sizeof(mCurPopupLayout));
+
+    memset(mCurBaseLayoutKeyCoordinates, 0x00, sizeof(mCurBaseLayoutKeyCoordinates));
+    memset(mCurPopupLayoutKeyCoordinates, 0x00, sizeof(mCurPopupLayoutKeyCoordinates));
+
+    memset(mCurBaseButtonContext, 0x00, sizeof(mCurBaseButtonContext));
+    memset(mCurPopupButtonContext, 0x00, sizeof(mCurPopupButtonContext));
+
+    mCurStartingCoordinates.x = 0;
+    mCurStartingCoordinates.y = 0;
+    mCurStartingCoordinatesOption = SCL_STARTING_COORDINATES_OPTION_ALL;
+}
+
+CSCLResourceCache::~CSCLResourceCache()
+{
+    SCL_DEBUG();
+}
+
+CSCLResourceCache*
+CSCLResourceCache::get_instance()
+{
+    static CSCLResourceCache instance;
+    return &instance;
+}
+
+
+sclboolean
+CSCLResourceCache::init()
+{
+    clear_private_keys();
+
+    resize_resource_elements_by_resolution();
+
+    mCurStartingCoordinates.x = 0;
+    mCurStartingCoordinates.y = 0;
+    mCurStartingCoordinatesOption = SCL_STARTING_COORDINATES_OPTION_ALL;
+
+    return TRUE;
+}
+
+/**
+ * Returns the current layout data
+ */
+const SclLayout*
+CSCLResourceCache::get_cur_layout(sclwindow window) const
+{
+    SCL_DEBUG();
+
+    const SclLayout *ret = NULL;
+    CSCLWindows *windows = CSCLWindows::get_instance();
+
+    if (windows) {
+        if (windows->get_base_window() == window) {
+            ret = &mCurBaseLayout;
+        } else {
+            sclbyte popupindex = windows->find_popup_window_index(window);
+            scl_assert_return_false(popupindex < MAX_POPUP_WINDOW);
+            if (popupindex < MAX_POPUP_WINDOW) {
+                ret = &mCurPopupLayout[popupindex];
+            }
+        }
+    }
+    return ret;
+}
+
+/**
+ * Translates each key's x,y,width,height by the current screen resolution
+ * This func should be called when the class init / or after lazy loading
+ */
+sclboolean
+CSCLResourceCache::resize_layout_by_resolution(sclbyte layout_index, sclboolean resize_key_only)
+{
+    sclint innerLoop;
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (utils && sclres_manager && context) {
+        const PSclDefaultConfigure sclres_default_configure = sclres_manager->get_default_configure();
+        const PSclLayout sclres_layout = sclres_manager->get_layout_table();
+        const PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame =
+            sclres_manager->get_key_coordinate_pointer_frame();
+
+        assert(sclres_default_configure != NULL);
+        assert(sclres_layout != NULL);
+        assert(sclres_layout_key_coordinate_pointer_frame != NULL);
+
+        sclboolean invert_display = FALSE;
+
+        if (sclres_default_configure->auto_detect_landscape) {
+            sclint width, height;
+            utils->get_screen_resolution(&width, &height);
+            /* If the width of screen is bigger than the height, switch portrait mode and landscape mode */
+            if (width > height && context->get_display_mode() == DISPLAYMODE_PORTRAIT) {
+                invert_display = TRUE;
+            }
+        }
+
+        sclfloat scale_value_x, scale_value_y;
+        if (invert_display) {
+            if (sclres_layout[layout_index].display_mode == DISPLAYMODE_PORTRAIT) {
+                scale_value_x = utils->get_scale_rate_y();
+                scale_value_y = utils->get_scale_rate_x();
+            } else {
+                scale_value_x = utils->get_scale_rate_x();
+                scale_value_y = utils->get_scale_rate_y();
+            }
+        } else {
+            if (sclres_layout[layout_index].display_mode == DISPLAYMODE_PORTRAIT) {
+                scale_value_x = utils->get_scale_rate_x();
+                scale_value_y = utils->get_scale_rate_y();
+            } else {
+                scale_value_x = utils->get_scale_rate_y();
+                scale_value_y = utils->get_scale_rate_x();
+            }
+        }
+
+        ///* FIXME : We should apply this constraint to other scaling routines also! */
+        ///* If the current screen resolution Y is bigger than our target height */
+        //if (scale_value_y > 1.0f) {
+        //    /* And if we have to scale Y-axis more than the X-axis, limit the scale value to X-axis rate */
+        //    if (scale_value_y > scale_value_x) {
+        //        scale_value_y = scale_value_x;
+        //    }
+        //} else if (scale_value_y < 1.0f) { /* Or current screen is smaller than our target resolution */
+        //    /* And if we have to scale Y-axis more than the X-axis, limit the scale value to X-axis rate */
+        //    if (scale_value_y < scale_value_x) {
+        //        scale_value_y = scale_value_x;
+        //    }
+        //}
+
+        if (!resize_key_only) {
+            sclres_layout[layout_index].width *= scale_value_x;
+            sclres_layout[layout_index].height *= scale_value_y;
+        }
+
+        for (innerLoop = 0;innerLoop < MAX_KEY;innerLoop++) {
+            SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout_index][innerLoop];
+            if (p && p->valid) {
+                p->x *= scale_value_x;
+                p->y *= scale_value_y;
+                p->width *= scale_value_x;
+                p->height *= scale_value_y;
+                p->add_hit_left *= scale_value_x;
+                p->add_hit_right *= scale_value_x;
+                p->add_hit_top *= scale_value_y;
+                p->add_hit_bottom *= scale_value_y;
+                p->popup_relative_x *= scale_value_x;
+                p->popup_relative_y *= scale_value_y;
+                p->extract_offset_x *= scale_value_x;
+                p->extract_offset_y *= scale_value_y;
+                p->magnifier_offset_x *= scale_value_x;
+                p->magnifier_offset_y *= scale_value_y;
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * Translates the current x,y,width,height by the current screen resolution
+ * This func should be called when the class init
+ */
+sclboolean
+CSCLResourceCache::resize_resource_elements_by_resolution()
+{
+    sclint loop, innerLoop;
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (utils && sclres_manager) {
+        const PSclDefaultConfigure sclres_default_configure = sclres_manager->get_default_configure();
+        const PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+        const PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
+        const PSclLabelPropertiesTable sclres_label_properties = sclres_manager->get_label_properties_frame();
+        const PSclAutoPopupConfigure sclres_autopopup_configure = sclres_manager->get_autopopup_configure();
+        const PSclMagnifierWndConfigure sclres_magnifier_configure = sclres_manager->get_magnifier_configure();
+
+        assert(sclres_default_configure != NULL);
+        assert(sclres_input_mode_configure != NULL);
+        assert(sclres_modifier_decoration != NULL);
+        assert(sclres_label_properties != NULL);
+        assert(sclres_autopopup_configure != NULL);
+        assert(sclres_magnifier_configure != NULL);
+
+        sclboolean invert_display = FALSE;
+
+        if (sclres_default_configure->auto_detect_landscape) {
+            sclint width, height;
+            utils->get_screen_resolution(&width, &height);
+            /* If the width of screen is bigger than the height, switch portrait mode and landscape mode */
+            if (width > height) {
+                invert_display = TRUE;
+            }
+        }
+
+        /* First we recalculate all the coordinates of each keys and sizes of layouts structure */
+        /* FIXME */
+        //for (loop = 0;loop < MAX_LAYOUT;loop++) {
+        for (loop = 0;loop < MAX_SCL_LAYOUT;loop++) {
+            resize_layout_by_resolution(loop);
+        }
+
+        /* And resize the font labels, adjusting the size of padding also */
+        /* FIXME */
+        //for (loop = 0;loop < MAX_LABEL_PROPERTIES;loop++) {
+        for (loop = 0;loop < MAX_SCL_LABEL_PROPERTIES;loop++) {
+            for (innerLoop = 0;innerLoop < MAX_SIZE_OF_LABEL_FOR_ONE;innerLoop++) {
+                if (sclres_label_properties[loop][innerLoop].valid)
+                    sclres_label_properties[loop][innerLoop].font_size *= utils->get_smallest_scale_rate();
+                sclres_label_properties[loop][innerLoop].padding_x *= utils->get_smallest_scale_rate();
+                sclres_label_properties[loop][innerLoop].padding_y *= utils->get_smallest_scale_rate();
+                sclres_label_properties[loop][innerLoop].inner_width *= utils->get_smallest_scale_rate();
+                sclres_label_properties[loop][innerLoop].inner_height *= utils->get_smallest_scale_rate();
+                sclres_label_properties[loop][innerLoop].shadow_distance *= utils->get_smallest_scale_rate();
+            }
+        }
+
+        /* FIXME - Let's check if these variables also need to be calculated by AutoLandscapeDection */
+        sclres_autopopup_configure->decoration_size *= utils->get_smallest_scale_rate();
+        sclres_autopopup_configure->bg_padding *= utils->get_smallest_scale_rate();
+        sclres_autopopup_configure->button_spacing *= utils->get_smallest_scale_rate();
+        sclres_autopopup_configure->button_width *= utils->get_scale_rate_x();
+        sclres_autopopup_configure->button_height *= utils->get_scale_rate_y();
+
+        sclres_magnifier_configure->width *= utils->get_scale_rate_x();
+        sclres_magnifier_configure->height *= utils->get_scale_rate_y();
+        sclres_magnifier_configure->label_area_rect.left *= utils->get_scale_rate_x();
+        sclres_magnifier_configure->label_area_rect.right *= utils->get_scale_rate_x();
+        sclres_magnifier_configure->label_area_rect.top *= utils->get_scale_rate_y();
+        sclres_magnifier_configure->label_area_rect.bottom *= utils->get_scale_rate_y();
+        sclres_magnifier_configure->padding_x *= utils->get_scale_rate_x();
+        sclres_magnifier_configure->padding_y *= utils->get_scale_rate_y();
+
+        /* The size of magnifier window is fixed at initialization stage, so we need to change it
+           if the screen resolution has been changed. */
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        if (windows) {
+            windows->resize_window(windows->get_magnifier_window(),
+                sclres_magnifier_configure->width, sclres_magnifier_configure->height);
+        }
+
+        if (invert_display) {
+            /* FIXME */
+            //for (loop = 0;loop < MAX_INPUT_MODE;loop++) {
+            for (loop = 0;loop < MAX_SCL_INPUT_MODE;loop++) {
+                sclchar *temp = sclres_input_mode_configure[loop].layouts[0];
+                sclres_input_mode_configure[loop].layouts[0] = sclres_input_mode_configure[loop].layouts[1];
+                sclres_input_mode_configure[loop].layouts[1] = temp;
+            }
+            /* FIXME */
+            //for (loop = 0;loop < MODIFIER_DECORATION_NUM;loop++) {
+            for (loop = 0;loop < MAX_SCL_MODIFIER_DECORATION_NUM;loop++) {
+                for (innerLoop = 0;innerLoop < KEY_MODIFIER_MAX;innerLoop++) {
+                    sclchar *temp;
+                    temp = sclres_modifier_decoration[loop].bg_image_path[0][innerLoop];
+                    sclres_modifier_decoration[loop].bg_image_path[0][innerLoop] = sclres_modifier_decoration[loop].bg_image_path[1][innerLoop];
+                    sclres_modifier_decoration[loop].bg_image_path[1][innerLoop] = temp;
+                }
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * Changes the current key properties by the current screen resolution
+ * This func should be called when the class init
+ */
+sclboolean
+CSCLResourceCache::change_by_privatekey(const sclbyte input_mode_index, const sclbyte layout_index, const sclbyte key_index, SclLayoutKeyCoordinate* coordinate)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(coordinate);
+
+    if (coordinate) {
+        for (int loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
+            if (mPrivateKeyProperties[loop].valid &&
+                !(mPrivateKeyProperties[loop].custom_id.empty()) && coordinate->custom_id) {
+                if (mPrivateKeyProperties[loop].custom_id.compare(coordinate->custom_id) == 0) {
+                    /* sets the current properties to private key properties */
+                    copy_from_privatekeyproperties(&mPrivateKeyProperties[loop], coordinate);
+                }
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * Copys the given private properties data to the given key properties
+ */
+sclboolean
+CSCLResourceCache::copy_from_privatekeyproperties(const SclPrivateKeyProperties* privProperties, SclLayoutKeyCoordinate* coordinate)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(privProperties);
+    scl_assert_return_false(coordinate);
+
+    sclint loop;
+    sclint inner_loop;
+    if (privProperties && coordinate) {
+        /* Copy customizing-allowed properties only if those properties are valid */
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_LABEL_FOR_ONE;inner_loop++) {
+                if (!(privProperties->label[loop][inner_loop].empty())) {
+                    if (coordinate->label_count < inner_loop + 1) {
+                        coordinate->label_count = inner_loop + 1;
+                    }
+                    coordinate->label[loop][inner_loop] =
+                        const_cast<sclchar*>(privProperties->label[loop][inner_loop].c_str());
+                }
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
+                if (!(privProperties->image_label_path[loop][inner_loop].empty())) {
+                    coordinate->image_label_path[loop][inner_loop] =
+                        const_cast<sclchar*>(privProperties->image_label_path[loop][inner_loop].c_str());
+                }
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
+                if (!(privProperties->bg_image_path[loop][inner_loop].empty())) {
+                    coordinate->bg_image_path[loop][inner_loop] =
+                        const_cast<sclchar*>(privProperties->bg_image_path[loop][inner_loop].c_str());
+                }
+            }
+        }
+
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                if (!(privProperties->key_value[loop][inner_loop].empty())) {
+                    coordinate->key_value[loop][inner_loop] =
+                        const_cast<sclchar*>(privProperties->key_value[loop][inner_loop].c_str());
+                }
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                if (privProperties->key_event[loop][inner_loop] != 0) {
+                    coordinate->key_event[loop][inner_loop] =
+                        privProperties->key_event[loop][inner_loop];
+                }
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                if (!(privProperties->hint_string[loop][inner_loop].empty())) {
+                    coordinate->hint_string[loop][inner_loop] =
+                        const_cast<sclchar*>(privProperties->hint_string[loop][inner_loop].c_str());
+                }
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * Copys the given properties data to the given private key properties
+ */
+sclboolean
+CSCLResourceCache::copy_to_privatekeyproperties(const SclLayoutKeyCoordinate *coordinate, SclPrivateKeyProperties* privProperties)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(privProperties);
+    scl_assert_return_false(coordinate);
+
+    /* sets the current key Properties to private key privProperties */
+
+    sclint loop;
+    sclint inner_loop;
+    if (privProperties && coordinate) {
+        /* Configure */
+        if (coordinate->custom_id) {
+            privProperties->custom_id = coordinate->custom_id;
+        }
+        privProperties->button_type = coordinate->button_type;
+        privProperties->key_type = coordinate->key_type;
+        privProperties->popup_type = coordinate->popup_type;
+        privProperties->use_magnifier = coordinate->use_magnifier;
+        privProperties->use_long_key_magnifier = coordinate->use_long_key_magnifier;
+        if (coordinate->sound_style) {
+            privProperties->sound_style = coordinate->sound_style;
+        }
+        if (coordinate->vibe_style) {
+            privProperties->vibe_style = coordinate->vibe_style;
+        }
+
+        for (loop = 0;loop < SCL_DRAG_STATE_MAX;loop++) {
+            if (coordinate->popup_input_mode[loop]) {
+                privProperties->popup_input_mode[loop] = coordinate->popup_input_mode[loop];
+            }
+        }
+
+        /* Properties */
+        privProperties->label_count = coordinate->label_count;
+        privProperties->key_value_count = coordinate->key_value_count;
+        privProperties->long_key_type = coordinate->long_key_type;
+        if (coordinate->long_key_value) {
+            privProperties->long_key_value = coordinate->long_key_value;
+        }
+        privProperties->long_key_event = coordinate->long_key_event;
+        privProperties->use_repeat_key = coordinate->use_repeat_key;
+        privProperties->dont_close_popup = coordinate->dont_close_popup;
+        privProperties->extra_option = coordinate->extra_option;
+        if (coordinate->label_type) {
+            privProperties->label_type = coordinate->label_type;
+        }
+        if (coordinate->image_label_type) {
+            privProperties->image_label_type = coordinate->image_label_type;
+        }
+
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_LABEL_FOR_ONE;inner_loop++) {
+                if (coordinate->label[loop][inner_loop]) {
+                    privProperties->label[loop][inner_loop] =
+                        coordinate->label[loop][inner_loop];
+                }
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
+                if (coordinate->image_label_path[loop][inner_loop]) {
+                    privProperties->image_label_path[loop][inner_loop] =
+                        coordinate->image_label_path[loop][inner_loop];
+                }
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
+                if (coordinate->bg_image_path[loop][inner_loop]) {
+                    privProperties->bg_image_path[loop][inner_loop] =
+                        coordinate->bg_image_path[loop][inner_loop];
+                }
+            }
+        }
+
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                if (coordinate->key_value[loop][inner_loop]) {
+                    privProperties->key_value[loop][inner_loop] =
+                        coordinate->key_value[loop][inner_loop];
+                }
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                if (coordinate->key_event[loop][inner_loop]) {
+                    privProperties->key_event[loop][inner_loop] =
+                        coordinate->key_event[loop][inner_loop];
+                }
+            }
+        }
+
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
+                if (coordinate->autopopup_key_labels[loop][inner_loop]) {
+                    privProperties->autopopup_key_labels[loop][inner_loop] =
+                        coordinate->autopopup_key_labels[loop][inner_loop];
+                }
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
+                if (coordinate->autopopup_key_events[loop][inner_loop]) {
+                    privProperties->autopopup_key_events[loop][inner_loop] =
+                        coordinate->autopopup_key_events[loop][inner_loop];
+                }
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
+                if (coordinate->autopopup_key_values[loop][inner_loop]) {
+                    privProperties->autopopup_key_values[loop][inner_loop] =
+                        coordinate->autopopup_key_values[loop][inner_loop];
+                }
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                if (coordinate->hint_string[loop][inner_loop]) {
+                    privProperties->hint_string[loop][inner_loop] =
+                        coordinate->hint_string[loop][inner_loop];
+                }
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * Copys the given private properties data to the other private properties
+ */
+sclboolean
+CSCLResourceCache::copy_privatekeyproperties(const SclPrivateKeyProperties* source, SclPrivateKeyProperties* target)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(source);
+    scl_assert_return_false(target);
+
+    sclint loop;
+    sclint inner_loop;
+    if (source && target) {
+        target->input_mode_index = source->input_mode_index;
+        target->layout_index = source->layout_index;
+        target->key_index = source->key_index;
+
+        /* Configure */
+        target->custom_id = source->custom_id;
+        target->button_type = source->button_type;
+        target->key_type = source->key_type;
+        target->popup_type = source->popup_type;
+        target->use_magnifier = source->use_magnifier;
+        target->use_long_key_magnifier = source->use_long_key_magnifier;
+        target->sound_style = source->sound_style;
+        target->vibe_style = source->vibe_style;
+
+        for (loop = 0;loop < SCL_DRAG_STATE_MAX;loop++) {
+            target->popup_input_mode[loop] = source->popup_input_mode[loop];
+        }
+
+        /* Properties */
+        target->label_count = source->label_count;
+        target->key_value_count = source->key_value_count;
+        target->long_key_type = source->long_key_type;
+        target->long_key_value = source->long_key_value;
+        target->long_key_event = source->long_key_event;
+        target->use_repeat_key = source->use_repeat_key;
+        target->dont_close_popup = source->dont_close_popup;
+        target->extra_option = source->extra_option;
+        target->label_type = source->label_type;
+        target->image_label_type = source->image_label_type;
+
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_LABEL_FOR_ONE;inner_loop++) {
+                target->label[loop][inner_loop] =
+                    source->label[loop][inner_loop];
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
+                target->image_label_path[loop][inner_loop] =
+                    source->image_label_path[loop][inner_loop];
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
+                target->bg_image_path[loop][inner_loop] =
+                    source->bg_image_path[loop][inner_loop];
+            }
+        }
+
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                target->key_value[loop][inner_loop] =
+                    source->key_value[loop][inner_loop];
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                target->key_event[loop][inner_loop] =
+                    source->key_event[loop][inner_loop];
+            }
+        }
+
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
+                target->autopopup_key_labels[loop][inner_loop] =
+                    source->autopopup_key_labels[loop][inner_loop];
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
+                target->autopopup_key_events[loop][inner_loop] =
+                    source->autopopup_key_events[loop][inner_loop];
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
+                target->autopopup_key_values[loop][inner_loop] =
+                    source->autopopup_key_values[loop][inner_loop];
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                target->hint_string[loop][inner_loop] =
+                    source->hint_string[loop][inner_loop];
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * Clears the given private properties data
+ */
+sclboolean
+CSCLResourceCache::clear_privatekeyproperties(SclPrivateKeyProperties* privProperties)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(privProperties);
+
+    /* sets the current key Properties to private key privProperties */
+
+    sclint loop;
+    sclint inner_loop;
+    if (privProperties) {
+        /* Configure */
+        privProperties->valid = FALSE;
+        privProperties->input_mode_index = NOT_USED;
+        privProperties->layout_index = NOT_USED;
+        privProperties->key_index = NOT_USED;
+
+        privProperties->custom_id.clear();
+        privProperties->button_type = BUTTON_TYPE_NORMAL;
+        privProperties->key_type = KEY_TYPE_NONE;
+        privProperties->popup_type = POPUP_TYPE_NONE;
+        privProperties->use_magnifier = FALSE;
+        privProperties->use_long_key_magnifier = FALSE;
+        privProperties->sound_style.clear();
+        privProperties->vibe_style.clear();
+
+        for (loop = 0;loop < SCL_DRAG_STATE_MAX;loop++) {
+            privProperties->popup_input_mode[loop].clear();
+        }
+
+        /* Properties */
+        privProperties->label_count = 0;
+        privProperties->key_value_count = 0;
+        privProperties->long_key_type = KEY_TYPE_NONE;
+        privProperties->long_key_value.clear();
+        privProperties->long_key_event = 0;
+        privProperties->use_repeat_key = FALSE;
+        privProperties->dont_close_popup = FALSE;
+        privProperties->extra_option = 0;
+        privProperties->label_type.clear();
+        privProperties->image_label_type.clear();
+
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_LABEL_FOR_ONE;inner_loop++) {
+                privProperties->label[loop][inner_loop].clear();
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
+                privProperties->image_label_path[loop][inner_loop].clear();
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < SCL_BUTTON_STATE_MAX;inner_loop++) {
+                privProperties->bg_image_path[loop][inner_loop].clear();
+            }
+        }
+
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                privProperties->key_value[loop][inner_loop].clear();
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                privProperties->key_event[loop][inner_loop] = 0;
+            }
+        }
+
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
+                privProperties->autopopup_key_labels[loop][inner_loop].clear();
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
+                privProperties->autopopup_key_events[loop][inner_loop] = 0;
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_AUTOPOPUP_STRING;inner_loop++) {
+                privProperties->autopopup_key_values[loop][inner_loop].clear();
+            }
+        }
+        for (loop = 0;loop < SCL_SHIFT_STATE_MAX;loop++) {
+            for (inner_loop = 0;inner_loop < MAX_SIZE_OF_MULTITAP_CHAR;inner_loop++) {
+                privProperties->hint_string[loop][inner_loop].clear();
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * Adds a new private key
+ * It will update it to the current cache properties context because the application can call it anytime
+ * For adapting it in realtime, you should explicitly call the draw_button function.
+ *
+ * @param[out] fNeedInvalid It will return true if the current private can be adapt into the current display.
+ * @return id an array index of the private key
+ */
+sclint
+CSCLResourceCache::add_private_key(SclPrivateKeyProperties* privProperties, sclboolean *fNeedInvalid)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(privProperties);
+    sclint ret = NOT_USED;
+    *fNeedInvalid = FALSE; /* don't need to update now */
+
+    if (privProperties->custom_id.empty())
+        return ret;
+
+    /* Finds an index to be set */
+    sclint loop = 0;
+    for (loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
+        if (mPrivateKeyProperties[loop].custom_id.compare(privProperties->custom_id) == 0) {
+            break;
+        }
+    }
+
+    if (loop == MAX_PRIVATE_KEY) {
+        for (loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
+            if (mPrivateKeyProperties[loop].valid == FALSE) break;
+        }
+        if (loop == MAX_PRIVATE_KEY) {
+            LOGW("Out of buffer!! could not insert new private data into buffer");
+            return ret;
+        }
+    }
+
+    copy_privatekeyproperties(privProperties, &mPrivateKeyProperties[loop]);
+    mPrivateKeyProperties[loop].valid = TRUE;
+    ret = loop;
+
+    SclPrivateKeyProperties* newPrivProperties = &mPrivateKeyProperties[loop];
+
+    sclboolean found = FALSE;
+    for (loop = 0;loop < MAX_KEY; loop++) {
+        if ((!(newPrivProperties->custom_id.empty())) && mCurBaseLayoutKeyCoordinates[loop].custom_id) {
+            if (newPrivProperties->custom_id.compare(mCurBaseLayoutKeyCoordinates[loop].custom_id) == 0) {
+                /* sets the current properties to private key properties */
+                copy_from_privatekeyproperties(newPrivProperties, &mCurBaseLayoutKeyCoordinates[loop]);
+                found = TRUE;
+            }
+        }
+    }
+    if (found) {
+        *fNeedInvalid = TRUE;
+        return ret;
+    }
+
+#if 0
+    /* For popup layout */
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    for (int ploop = 0; ploop < MAX_POPUP_WINDOW; ploop++) {
+        layout = context->get_popup_layout(windows->get_nth_popup_window(ploop));
+        if (privProperties->input_mode_index == inputmode && privProperties->layout_index == layout) {
+            /* sets the current properties to private key properties */
+            copy_privatekeyproperties_to_keyproperties(privProperties, &mCurPopupLayoutKeyProperties[ploop][privProperties->key_index]);
+            return ret;
+            *fNeedInvalid = TRUE;
+        }
+    }
+#endif
+
+    return ret;
+}
+
+/**
+ * Removes the private data of the given id from SclPrivateKeyProperties buffer
+ */
+sclboolean
+CSCLResourceCache::remove_private_key(sclint id)
+{
+    SCL_DEBUG();
+    sclint loop;
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    if (!context || !utils) return FALSE;
+
+    /* resets the current properties to predefined properties */
+    sclshort layout =  context->get_base_layout();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (!sclres_manager) return FALSE;
+
+    PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame =
+        sclres_manager->get_key_coordinate_pointer_frame();
+
+    if (sclres_layout_key_coordinate_pointer_frame == NULL) {
+        return FALSE;
+    }
+    if (scl_check_arrindex(layout, MAX_SCL_LAYOUT)) {
+        for (loop = 0;loop < MAX_KEY; loop++) {
+            if ((!(mPrivateKeyProperties[id].custom_id.empty())) && mCurBaseLayoutKeyCoordinates[loop].custom_id) {
+                if (mPrivateKeyProperties[id].custom_id.compare(mCurBaseLayoutKeyCoordinates[loop].custom_id) == 0) {
+                    SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout][loop];
+                    if (p == NULL) {
+                        continue;
+                    }
+                    SclLayoutKeyCoordinatePointer the_key = mCurBaseLayoutKeyCoordinates + loop;
+                    if (the_key) {
+                        memcpy(the_key, p, sizeof(SclLayoutKeyCoordinate));
+
+                        /* Apply the custom scale rate value */
+                        the_key->x *= utils->get_custom_scale_rate_x();
+                        the_key->y *= utils->get_custom_scale_rate_y();
+                        the_key->width *= utils->get_custom_scale_rate_x();
+                        the_key->height *= utils->get_custom_scale_rate_y();
+                        the_key->add_hit_left *= utils->get_custom_scale_rate_x();
+                        the_key->add_hit_right *= utils->get_custom_scale_rate_x();
+                        the_key->add_hit_top *= utils->get_custom_scale_rate_y();
+                        the_key->add_hit_bottom *= utils->get_custom_scale_rate_y();
+                        the_key->popup_relative_x *= utils->get_custom_scale_rate_x();
+                        the_key->popup_relative_y *= utils->get_custom_scale_rate_y();
+                        the_key->extract_offset_x *= utils->get_custom_scale_rate_x();
+                        the_key->extract_offset_y *= utils->get_custom_scale_rate_y();
+                        the_key->magnifier_offset_x *= utils->get_custom_scale_rate_x();
+                        the_key->magnifier_offset_y *= utils->get_custom_scale_rate_y();
+
+                        /* Apply the custom starting coordinates */
+                        the_key->x += mCurStartingCoordinates.x;
+                        the_key->y += mCurStartingCoordinates.y;
+                    }
+                }
+            }
+        }
+    }
+
+    /* Shift all the privatekey properties to the left by 1, starting from the item next to the id th element */
+    for (loop = id;loop < MAX_PRIVATE_KEY - 1; loop++) {
+        copy_privatekeyproperties(&mPrivateKeyProperties[loop + 1], &mPrivateKeyProperties[loop]);
+    }
+    /* Clear the last element */
+    clear_privatekeyproperties(&mPrivateKeyProperties[MAX_PRIVATE_KEY - 1]);
+    return TRUE;
+}
+
+/**
+ * Clears all private keys
+ */
+sclboolean
+CSCLResourceCache::clear_private_keys()
+{
+    SCL_DEBUG();
+    for (sclint loop = 0; loop < MAX_PRIVATE_KEY;loop++) {
+        clear_privatekeyproperties(&mPrivateKeyProperties[loop]);
+    }
+    return TRUE;
+}
+
+/**
+ * Re-computes the cache data of the given window. The cache data has been including the current key properties, button context, layout etc,,
+ * Another role of this func is to adjust the current coordinate according to the current resolution.
+ * This func will be called when a newly window is created
+ */
+sclboolean
+CSCLResourceCache::recompute_layout(sclwindow window)
+{
+    SCL_DEBUG();
+
+    sclint loop;
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (!windows || !context || !utils || !sclres_manager) return FALSE;
+
+    const PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+    const PSclLayout sclres_layout = sclres_manager->get_layout_table();
+    const PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame =
+        sclres_manager->get_key_coordinate_pointer_frame();
+    const PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
+    const PSclLabelPropertiesTable sclres_label_properties = sclres_manager->get_label_properties_frame();
+
+    if (!sclres_input_mode_configure || !sclres_layout || !sclres_layout_key_coordinate_pointer_frame ||
+        !sclres_modifier_decoration || !sclres_label_properties)
+        return FALSE;
+
+    /* FIXME */
+    scl8 popupindex = NOT_USED;
+
+    SclLayout *pCurLayout = NULL;
+    SclLayoutKeyCoordinate (*pCurLayoutKeyCoordinate)[MAX_KEY] = NULL;
+    SclButtonContext (*pCurButtonContext)[MAX_KEY] = NULL;
+
+    sclshort layout =  NOT_USED;
+    if (windows && context && utils) {
+        sclbyte inputmode = context->get_input_mode();
+
+        if (windows->is_base_window(window)) {
+            SCLDisplayMode display_mode = context->get_display_mode();
+            layout = sclres_manager->get_layout_id(
+                sclres_input_mode_configure[inputmode].layouts[display_mode]);
+            if (layout != context->get_base_layout()) {
+                sclres_manager->unload();
+            }
+            if (!(sclres_manager->loaded(layout))) {
+                sclres_manager->load(layout);
+                resize_layout_by_resolution(layout);
+            }
+            SCLDisplayMode pair_mode = ((display_mode == DISPLAYMODE_PORTRAIT) ? DISPLAYMODE_LANDSCAPE : DISPLAYMODE_PORTRAIT);
+            sclshort pair_layout = sclres_manager->get_layout_id(
+                sclres_input_mode_configure[inputmode].layouts[pair_mode]);
+            if (!(sclres_manager->loaded(pair_layout))) {
+                sclres_manager->load(pair_layout);
+                resize_layout_by_resolution(pair_layout);
+            }
+            context->set_base_layout(layout);
+
+            pCurLayout = &mCurBaseLayout;
+            pCurLayoutKeyCoordinate = &mCurBaseLayoutKeyCoordinates;
+            pCurButtonContext = &mCurBaseButtonContext;
+        } else {
+            popupindex = windows->find_popup_window_index(window);
+            /* Check if the popup index is in valid range */
+            scl_assert_return_false(popupindex >= 0 && popupindex < MAX_POPUP_WINDOW);
+
+            layout = context->get_popup_layout(window);
+
+            if (!(sclres_manager->loaded(layout))) {
+                sclres_manager->load(layout);
+                resize_layout_by_resolution(layout);
+            }
+            context->set_popup_layout(window, layout);
+
+            if (popupindex >= 0 && popupindex < MAX_POPUP_WINDOW) {
+                if (!(windows->is_base_window(window))) {
+                    SclWindowContext *window_context = windows->get_window_context(window);
+                    if (window_context) {
+                        if (window_context->inputmode != NOT_USED) {
+                            inputmode = window_context->inputmode;
+                        }
+                        if (window_context->layout != NOT_USED) {
+                            layout = window_context->layout;
+                        }
+                    }
+                }
+
+                pCurLayout = &mCurPopupLayout[popupindex];
+                pCurLayoutKeyCoordinate = &mCurPopupLayoutKeyCoordinates[popupindex];
+
+                pCurButtonContext = &mCurPopupButtonContext[popupindex];
+            }
+        }
+
+        if (pCurLayout && pCurLayoutKeyCoordinate && pCurButtonContext) {
+            memset(pCurButtonContext, 0x00, sizeof(SclButtonContext) * MAX_KEY);
+            /* If the layout index represents system-defined autopopup, generate layout and key properties data */
+            if (layout == SCL_LAYOUT_AUTOPOPUP) {
+                const SclLayoutKeyCoordinate *coordinate =
+                    get_cur_layout_key_coordinate(context->get_cur_pressed_window(context->get_last_touch_device_id()),
+                        context->get_cur_pressed_key(context->get_last_touch_device_id()));
+
+                generate_autopopup_layout(coordinate, pCurLayout, pCurLayoutKeyCoordinate, pCurButtonContext);
+            } else {
+                if (scl_check_arrindex(layout, MAX_SCL_LAYOUT)) {
+                    memcpy(pCurLayout, &sclres_layout[layout], sizeof(SclLayout));
+
+                    memset(pCurLayoutKeyCoordinate, 0x00, sizeof(SclLayoutKeyCoordinate) * (MAX_KEY));
+                    for (int i = 0; i < MAX_KEY; ++i) {
+                        SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout][i];
+                        if (!p) break;
+                        memcpy((SclLayoutKeyCoordinatePointer)pCurLayoutKeyCoordinate + i, p, sizeof(SclLayoutKeyCoordinate));
+                    }
+
+                    CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+                    if (focus_handler) {
+                        //reset navigation info
+                        focus_handler->reset_key_navigation_info(window);
+                    }
+                    for (loop = 0;loop < MAX_KEY;loop++) {
+                        SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout][loop];
+                        if (p && p->valid) {
+                            if (focus_handler) {
+                                //BUILDING KEY NAVIGATION INFO
+                                focus_handler->update_key_navigation_info(window, loop, p);
+                            }
+                            //BUILDING KEY NAVIGATION INFO COMPLETED
+                            (*pCurButtonContext)[loop].used = TRUE;
+                            if (popupindex != NOT_USED) {
+                                change_by_privatekey(inputmode, layout, loop, &(mCurPopupLayoutKeyCoordinates[popupindex][loop]));
+                            } else {
+                                change_by_privatekey(inputmode, layout, loop, &(mCurBaseLayoutKeyCoordinates[loop]));
+                            }
+                            /* if this button is UIITEM type, set the state of this button disabled */
+                            if ((*pCurLayoutKeyCoordinate)[loop].button_type == BUTTON_TYPE_UIITEM) {
+                                (*pCurButtonContext)[loop].state = BUTTON_STATE_DISABLED;
+                            }
+
+                            /* If this button's custom id is in the disabled key list, make it disabled */
+                            sclboolean found = false;
+                            if ((*pCurLayoutKeyCoordinate)[loop].custom_id) {
+                                for (sclint inner_loop = 0;inner_loop < MAX_DISABLED_KEY;inner_loop++) {
+                                    if (!(mDisabledKeyList[inner_loop].empty())) {
+                                        if (mDisabledKeyList[inner_loop].compare(
+                                            (*pCurLayoutKeyCoordinate)[loop].custom_id) == 0) {
+                                                (*pCurButtonContext)[loop].state = BUTTON_STATE_DISABLED;
+                                                found = true;
+                                        }
+                                    }
+                                }
+                            }
+                            if (!found) {
+                                (*pCurButtonContext)[loop].state = BUTTON_STATE_NORMAL;
+                            }
+                            (*pCurButtonContext)[loop].toggled = FALSE;
+
+                            /* Apply the custom scale rate value */
+                            (*pCurLayoutKeyCoordinate)[loop].x *= utils->get_custom_scale_rate_x();
+                            (*pCurLayoutKeyCoordinate)[loop].y *= utils->get_custom_scale_rate_y();
+                            (*pCurLayoutKeyCoordinate)[loop].width *= utils->get_custom_scale_rate_x();
+                            (*pCurLayoutKeyCoordinate)[loop].height *= utils->get_custom_scale_rate_y();
+                            (*pCurLayoutKeyCoordinate)[loop].add_hit_left *= utils->get_custom_scale_rate_x();
+                            (*pCurLayoutKeyCoordinate)[loop].add_hit_right *= utils->get_custom_scale_rate_x();
+                            (*pCurLayoutKeyCoordinate)[loop].add_hit_top *= utils->get_custom_scale_rate_y();
+                            (*pCurLayoutKeyCoordinate)[loop].add_hit_bottom *= utils->get_custom_scale_rate_y();
+                            (*pCurLayoutKeyCoordinate)[loop].popup_relative_x *= utils->get_custom_scale_rate_x();
+                            (*pCurLayoutKeyCoordinate)[loop].popup_relative_y *= utils->get_custom_scale_rate_y();
+                            (*pCurLayoutKeyCoordinate)[loop].extract_offset_x *= utils->get_custom_scale_rate_x();
+                            (*pCurLayoutKeyCoordinate)[loop].extract_offset_y *= utils->get_custom_scale_rate_y();
+                            (*pCurLayoutKeyCoordinate)[loop].magnifier_offset_x *= utils->get_custom_scale_rate_x();
+                            (*pCurLayoutKeyCoordinate)[loop].magnifier_offset_y *= utils->get_custom_scale_rate_y();
+
+                            if (windows->is_base_window(window)) {
+                                /* Apply the custom starting coordinates */
+                                (*pCurLayoutKeyCoordinate)[loop].x += mCurStartingCoordinates.x;
+                                (*pCurLayoutKeyCoordinate)[loop].y += mCurStartingCoordinates.y;
+                            }
+                        }
+                    }
+
+                    if (focus_handler) {
+                        //finalize navigation info
+                        focus_handler->finalize_key_navigation_info(window);
+                    }
+                }
+
+                /* Apply the custom scale rate value */
+                (*pCurLayout).width *= utils->get_custom_scale_rate_x();
+                (*pCurLayout).height *= utils->get_custom_scale_rate_y();
+
+                (*pCurLayout).add_grab_left *= utils->get_custom_scale_rate_x();
+                (*pCurLayout).add_grab_right *= utils->get_custom_scale_rate_x();
+                (*pCurLayout).add_grab_top *= utils->get_custom_scale_rate_y();
+                (*pCurLayout).add_grab_bottom *= utils->get_custom_scale_rate_y();
+
+                (*pCurLayout).mouse_manipulate_x *= utils->get_custom_scale_rate_x();
+                (*pCurLayout).mouse_manipulate_y *= utils->get_custom_scale_rate_y();
+            }
+
+            /* Resize window */
+            if (windows->is_base_window(window)) {
+                windows->resize_window(window, mCurBaseLayout.width, mCurBaseLayout.height);
+                windows->resize_window(windows->get_dim_window(), mCurBaseLayout.width, mCurBaseLayout.height);
+            }
+
+            /* EFL testing */
+            if (window) {
+                windows->update_window(window);
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * Returns the current key_coordinate data
+ */
+SclLayoutKeyCoordinate*
+CSCLResourceCache::get_cur_layout_key_coordinate(sclwindow window, sclbyte key_index)
+{
+    SCL_DEBUG();
+    scl_assert_return_null(key_index < MAX_KEY);
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    if (!windows) return NULL;
+
+    if (windows->get_base_window() == window) {
+        if (key_index < MAX_KEY) {
+            return &mCurBaseLayoutKeyCoordinates[key_index];
+        }
+    } else {
+        sclbyte popupindex = windows->find_popup_window_index(window);
+        scl_assert_return_false(popupindex < MAX_POPUP_WINDOW);
+        if (key_index < MAX_KEY && popupindex < MAX_POPUP_WINDOW) {
+            return &mCurPopupLayoutKeyCoordinates[popupindex][key_index];
+        }
+    }
+
+    return NULL;
+}
+
+/**
+ * FIXME : This must be very SLOW - let's refine this function ASAP
+ * Returns the current label_properties data
+ */
+const SclLabelProperties*
+CSCLResourceCache::get_label_properties(sclchar *label_type, sclbyte index) const
+{
+    SCL_DEBUG();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (!sclres_manager) return NULL;
+
+    PSclLabelPropertiesTable sclres_label_properties = sclres_manager->get_label_properties_frame();
+    assert(sclres_label_properties != NULL);
+    if (sclres_label_properties && label_type) {
+        /* FIXME */
+        //if (scl_check_arrindex(labeltype, MAX_LABEL_PROPERTIES) && scl_check_arrindex(index, MAX_SIZE_OF_LABEL_FOR_ONE)) {
+        for (sclshort labeltype = 0;
+            labeltype < MAX_SCL_LABEL_PROPERTIES && labeltype < sclres_manager->get_labelproperty_size();
+            labeltype++) {
+                if (sclres_label_properties[labeltype][0].label_type) {
+                    if (strcmp(sclres_label_properties[labeltype][0].label_type, label_type) == 0) {
+                    if (scl_check_arrindex_unsigned(index, MAX_SIZE_OF_LABEL_FOR_ONE)) {
+                        return &sclres_label_properties[labeltype][index];
+                    }
+                }
+            }
+        }
+    }
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    if (utils && label_type) {
+        utils->log("WARNING!!!!!!!!!!!!!!!!!! LABEL NAME %s COULD NOT BE FOUND!!!!!\n", label_type);
+    }
+
+    return NULL;
+}
+
+/**
+ * Returns the current button_context data
+ */
+SclButtonContext*
+CSCLResourceCache::get_cur_button_context(sclwindow window, sclbyte key_index)
+{
+    SCL_DEBUG();
+    scl_assert_return_null(key_index < MAX_KEY);
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    if (!windows) return NULL;
+
+    if (windows->get_base_window() == window) {
+        if (key_index < MAX_KEY) {
+            return &mCurBaseButtonContext[key_index];
+        }
+    } else {
+        sclbyte popupindex = windows->find_popup_window_index(window);
+        scl_assert_return_null(popupindex < MAX_POPUP_WINDOW);
+        if (key_index < MAX_KEY && popupindex < MAX_POPUP_WINDOW) {
+            return &mCurPopupButtonContext[popupindex][key_index];
+        }
+    }
+
+    return NULL;
+}
+
+/* Generate and fill autopopup layout data */
+void CSCLResourceCache::generate_autopopup_layout(const SclLayoutKeyCoordinate *coordinate,
+        SclLayout *pCurLayout, SclLayoutKeyCoordinate (*pCurLayoutKeyCoordinates)[MAX_KEY],
+        SclButtonContext (*pCurButtonContext)[MAX_KEY] )
+{
+    SCL_DEBUG();
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    PSclAutoPopupConfigure autopopup_configure = NULL;
+    if (sclres_manager) {
+        autopopup_configure = sclres_manager->get_autopopup_configure();
+    }
+
+    int loop;
+    if (utils && context && coordinate && autopopup_configure) {
+        sclbyte num_keys, num_columns, num_rows;
+        sclint x, y, width, height;
+        SCLShiftState shift_index = context->get_shift_state();
+        if (shift_index >= SCL_SHIFT_STATE_MAX) shift_index = SCL_SHIFT_STATE_OFF;
+        if (context->get_caps_lock_mode()) {
+            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+        }
+        if (utils->get_autopopup_window_variables(coordinate->autopopup_key_labels[shift_index], &num_keys, &num_columns, &num_rows, &width, &height)) {
+            int row = 0, column = 0;
+
+            pCurLayout->use_magnifier_window = FALSE;
+            pCurLayout->valid = TRUE;
+            pCurLayout->style = LAYOUT_STYLE_POPUP_GRAB;
+            pCurLayout->name = NULL;
+            pCurLayout->width = width;
+            pCurLayout->height = height;
+            memset(pCurLayout->image_path, 0x00, sizeof(pCurLayout->image_path));
+            pCurLayout->use_sw_background = TRUE;
+            if (autopopup_configure->bg_image_path != NULL) {
+                pCurLayout->image_path[0] = autopopup_configure->bg_image_path;
+                pCurLayout->use_sw_background = FALSE;
+            }
+            pCurLayout->use_sw_button = TRUE;
+            /* If button image path is set, use images instead of SW buttons */
+            if (autopopup_configure->button_image_path[0] != NULL) {
+                pCurLayout->use_sw_button = FALSE;
+            }
+            pCurLayout->use_magnifier_window = FALSE;
+            pCurLayout->extract_background = FALSE;
+            pCurLayout->bg_color = autopopup_configure->bg_color;
+            pCurLayout->bg_line_width = autopopup_configure->bg_line_width * utils->get_smallest_custom_scale_rate();
+            pCurLayout->bg_line_color = autopopup_configure->bg_line_color;
+            pCurLayout->add_grab_left = autopopup_configure->add_grab_left * utils->get_custom_scale_rate_x();
+            pCurLayout->add_grab_right = autopopup_configure->add_grab_right * utils->get_custom_scale_rate_x();
+            pCurLayout->add_grab_top = autopopup_configure->add_grab_top * utils->get_custom_scale_rate_y();
+            pCurLayout->add_grab_bottom = autopopup_configure->add_grab_bottom * utils->get_custom_scale_rate_y();
+            pCurLayout->mouse_manipulate_x = 0;
+            pCurLayout->mouse_manipulate_y = (autopopup_configure->button_height * utils->get_custom_scale_rate_y() * -1);
+
+            memset((*pCurLayoutKeyCoordinates), 0x00, sizeof(SclLayoutKeyCoordinate) * MAX_KEY);
+
+            memset((*pCurButtonContext), 0x00, sizeof(SclButtonContext) * MAX_KEY);
+
+            int button_index = 0;
+
+            if (autopopup_configure->line_image_path &&
+                strlen(autopopup_configure->line_image_path) > 0) {
+                for (loop = 0;loop < num_columns - 1;loop++) {
+                    if (button_index < MAX_KEY) {
+                        (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+
+                        (*pCurLayoutKeyCoordinates)[button_index].x =
+                            autopopup_configure->bg_padding * utils->get_smallest_custom_scale_rate() +
+                            (autopopup_configure->button_width * utils->get_custom_scale_rate_x() * (loop + 1)) +
+                            (autopopup_configure->button_spacing * utils->get_smallest_custom_scale_rate() * loop);
+                        (*pCurLayoutKeyCoordinates)[button_index].y = pCurLayout->bg_line_width;
+                        (*pCurLayoutKeyCoordinates)[button_index].width =
+                            autopopup_configure->button_spacing * utils->get_smallest_custom_scale_rate();
+                        (*pCurLayoutKeyCoordinates)[button_index].height = height - (pCurLayout->bg_line_width * 2);
+
+                        (*pCurButtonContext)[button_index].used = TRUE;
+                        (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+                        (*pCurLayoutKeyCoordinates)[button_index].button_type = BUTTON_TYPE_UIITEM;
+                        (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+                        (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[0][0] =
+                            (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[0][1] =
+                            (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[1][0] =
+                            (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[1][1] =
+                            autopopup_configure->line_image_path;
+                        button_index++;
+                    }
+                }
+
+                for (loop = 0;loop < num_rows - 1;loop++) {
+                    if (button_index < MAX_KEY) {
+                        (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+
+                        (*pCurLayoutKeyCoordinates)[button_index].x = pCurLayout->bg_line_width;
+                        (*pCurLayoutKeyCoordinates)[button_index].y =
+                            autopopup_configure->bg_padding * utils->get_smallest_custom_scale_rate() +
+                            (autopopup_configure->button_height * utils->get_custom_scale_rate_y() * (loop + 1)) +
+                            (autopopup_configure->button_spacing * utils->get_smallest_custom_scale_rate() * loop);
+                        (*pCurLayoutKeyCoordinates)[button_index].width = width - (pCurLayout->bg_line_width * 2);
+                        (*pCurLayoutKeyCoordinates)[button_index].height =
+                            autopopup_configure->button_spacing * utils->get_smallest_custom_scale_rate();
+
+                        (*pCurButtonContext)[button_index].used = TRUE;
+                        (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+                        (*pCurLayoutKeyCoordinates)[button_index].button_type = BUTTON_TYPE_UIITEM;
+                        (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+                        (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[0][0] =
+                            (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[0][1] =
+                            (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[1][0] =
+                            (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[1][1] =
+                            autopopup_configure->line_image_path;
+                        button_index++;
+                    }
+                }
+            }
+
+            for (loop = 0;loop < (num_columns * num_rows) && button_index < MAX_KEY && loop < MAX_SIZE_OF_AUTOPOPUP_STRING;loop++) {
+                column = (loop % num_columns);
+                row = loop / num_columns;
+                x = autopopup_configure->bg_padding * utils->get_smallest_custom_scale_rate() +
+                    (autopopup_configure->button_width * utils->get_custom_scale_rate_x() * column) +
+                    (autopopup_configure->button_spacing * utils->get_smallest_custom_scale_rate() * column);
+                y = autopopup_configure->bg_padding * utils->get_smallest_custom_scale_rate() +
+                    (autopopup_configure->button_height * utils->get_custom_scale_rate_y() * (num_rows - row - 1)) +
+                    (autopopup_configure->button_spacing * utils->get_smallest_custom_scale_rate() * row);
+
+                (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+                (*pCurLayoutKeyCoordinates)[button_index].x = x +
+                    autopopup_configure->decoration_size * utils->get_smallest_custom_scale_rate();
+                (*pCurLayoutKeyCoordinates)[button_index].y = y +
+                    autopopup_configure->decoration_size * utils->get_smallest_custom_scale_rate();
+                (*pCurLayoutKeyCoordinates)[button_index].width =
+                    autopopup_configure->button_width * utils->get_custom_scale_rate_x();
+                (*pCurLayoutKeyCoordinates)[button_index].height =
+                    autopopup_configure->button_height * utils->get_custom_scale_rate_y();
+                (*pCurLayoutKeyCoordinates)[button_index].popup_relative_x = 0;
+                (*pCurLayoutKeyCoordinates)[button_index].popup_relative_y = 0;
+                (*pCurLayoutKeyCoordinates)[button_index].extract_offset_x = 0;
+                (*pCurLayoutKeyCoordinates)[button_index].extract_offset_y = 0;
+                (*pCurLayoutKeyCoordinates)[button_index].sub_layout = NULL;
+
+                (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+                if (loop < num_keys) {
+                    (*pCurLayoutKeyCoordinates)[button_index].button_type = BUTTON_TYPE_NORMAL;
+                } else {
+                    (*pCurLayoutKeyCoordinates)[button_index].button_type = BUTTON_TYPE_UIITEM;
+                }
+                (*pCurLayoutKeyCoordinates)[button_index].key_type = KEY_TYPE_STRING;
+                (*pCurLayoutKeyCoordinates)[button_index].popup_type = POPUP_TYPE_NONE;
+                (*pCurLayoutKeyCoordinates)[button_index].use_magnifier = FALSE;
+                (*pCurLayoutKeyCoordinates)[button_index].use_long_key_magnifier = TRUE;
+                memset((*pCurLayoutKeyCoordinates)[button_index].popup_input_mode, NOT_USED, sizeof((*pCurLayoutKeyCoordinates)[loop].popup_input_mode));
+
+                (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+                (*pCurLayoutKeyCoordinates)[button_index].label_count = 1;
+                if (context->get_caps_lock_mode()) {
+                    (*pCurLayoutKeyCoordinates)[button_index].label[SCL_SHIFT_STATE_OFF][0] =
+                        coordinate->autopopup_key_labels[SCL_SHIFT_STATE_ON][loop];
+                    (*pCurLayoutKeyCoordinates)[button_index].label[SCL_SHIFT_STATE_ON][0] =
+                        coordinate->autopopup_key_labels[SCL_SHIFT_STATE_OFF][loop];
+                    (*pCurLayoutKeyCoordinates)[button_index].label[SCL_SHIFT_STATE_LOCK][0] =
+                        coordinate->autopopup_key_labels[SCL_SHIFT_STATE_OFF][loop];
+                } else {
+                    (*pCurLayoutKeyCoordinates)[button_index].label[SCL_SHIFT_STATE_OFF][0] =
+                        coordinate->autopopup_key_labels[SCL_SHIFT_STATE_OFF][loop];
+                    (*pCurLayoutKeyCoordinates)[button_index].label[SCL_SHIFT_STATE_ON][0] =
+                        coordinate->autopopup_key_labels[SCL_SHIFT_STATE_ON][loop];
+                    (*pCurLayoutKeyCoordinates)[button_index].label[SCL_SHIFT_STATE_LOCK][0] =
+                        coordinate->autopopup_key_labels[SCL_SHIFT_STATE_LOCK][loop];
+                }
+                //(*pCurLayoutKeyProperties)[loop].labelPropId = SCL_LABEL_PROPERTY_AUTOPOPUP;
+                (*pCurLayoutKeyCoordinates)[button_index].label_type = autopopup_configure->label_type;
+                memset((*pCurLayoutKeyCoordinates)[button_index].image_label_path, 0x00, sizeof((*pCurLayoutKeyCoordinates)[loop].image_label_path));
+                memset((*pCurLayoutKeyCoordinates)[button_index].bg_image_path, 0x00, sizeof((*pCurLayoutKeyCoordinates)[loop].bg_image_path));
+                for (int innerLoop = 0;innerLoop < SCL_BUTTON_STATE_MAX;innerLoop++) {
+                    (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[SCL_SHIFT_STATE_OFF][innerLoop] =
+                        (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[SCL_SHIFT_STATE_ON][innerLoop] =
+                        (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[SCL_SHIFT_STATE_LOCK][innerLoop] =
+                            autopopup_configure->button_image_path[innerLoop];
+                }
+
+                (*pCurLayoutKeyCoordinates)[button_index].key_value_count = 1;
+
+                if (coordinate->autopopup_key_values[0][loop] == NULL) {
+                    (*pCurLayoutKeyCoordinates)[button_index].key_value[0][0] = coordinate->autopopup_key_labels[0][loop];
+                } else {
+                    (*pCurLayoutKeyCoordinates)[button_index].key_value[0][0] = coordinate->autopopup_key_values[0][loop];
+                }
+                if (coordinate->autopopup_key_values[1][loop] == NULL) {
+                    (*pCurLayoutKeyCoordinates)[button_index].key_value[1][0] = coordinate->autopopup_key_labels[1][loop];
+                } else {
+                    (*pCurLayoutKeyCoordinates)[button_index].key_value[1][0] = coordinate->autopopup_key_values[1][loop];
+                }
+                if (coordinate->autopopup_key_values[2][loop] == NULL) {
+                    (*pCurLayoutKeyCoordinates)[button_index].key_value[2][0] = coordinate->autopopup_key_labels[2][loop];
+                } else {
+                    (*pCurLayoutKeyCoordinates)[button_index].key_value[2][0] = coordinate->autopopup_key_values[2][loop];
+                }
+                (*pCurLayoutKeyCoordinates)[button_index].key_event[0][0] = coordinate->autopopup_key_events[0][loop];
+                (*pCurLayoutKeyCoordinates)[button_index].key_event[1][0] = coordinate->autopopup_key_events[1][loop];
+                (*pCurLayoutKeyCoordinates)[button_index].key_event[2][0] = coordinate->autopopup_key_events[2][loop];
+                (*pCurLayoutKeyCoordinates)[button_index].long_key_type = KEY_TYPE_NONE;
+                (*pCurLayoutKeyCoordinates)[button_index].long_key_value = NULL;
+                (*pCurLayoutKeyCoordinates)[button_index].long_key_event = 0;
+
+                (*pCurLayoutKeyCoordinates)[button_index].autopopup_key_labels[0][0] = NULL;
+                (*pCurLayoutKeyCoordinates)[button_index].autopopup_key_labels[1][0] = NULL;
+                (*pCurLayoutKeyCoordinates)[button_index].autopopup_key_labels[2][0] = NULL;
+                (*pCurLayoutKeyCoordinates)[button_index].autopopup_key_events[0][0] = 0;
+                (*pCurLayoutKeyCoordinates)[button_index].autopopup_key_events[1][0] = 0;
+                (*pCurLayoutKeyCoordinates)[button_index].autopopup_key_events[2][0] = 0;
+                (*pCurLayoutKeyCoordinates)[button_index].autopopup_key_values[0][0] = NULL;
+                (*pCurLayoutKeyCoordinates)[button_index].autopopup_key_values[1][0] = NULL;
+                (*pCurLayoutKeyCoordinates)[button_index].autopopup_key_values[2][0] = NULL;
+                (*pCurLayoutKeyCoordinates)[button_index].extra_option = 0;
+
+                (*pCurButtonContext)[button_index].used = TRUE;
+                button_index++;
+            }
+
+            for (loop = 0;loop < MAX_WND_DECORATOR;loop++) {
+                if (button_index < MAX_KEY &&
+                    autopopup_configure->decoration_image_path[loop] &&
+                    strlen(autopopup_configure->decoration_image_path[loop]) > 0) {
+                    (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+                    int decoration_size = autopopup_configure->decoration_size * utils->get_smallest_custom_scale_rate();
+                    switch (loop) {
+                        case WND_DECORATOR_TOP_LEFT:
+                            (*pCurLayoutKeyCoordinates)[button_index].x = 0;
+                            (*pCurLayoutKeyCoordinates)[button_index].y = 0;
+                            (*pCurLayoutKeyCoordinates)[button_index].width = decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].height = decoration_size;
+                        break;
+                        case WND_DECORATOR_TOP_CENTER:
+                            (*pCurLayoutKeyCoordinates)[button_index].x = decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].y = 0;
+                            (*pCurLayoutKeyCoordinates)[button_index].width = width - (2 * decoration_size);
+                            (*pCurLayoutKeyCoordinates)[button_index].height = decoration_size;
+                            break;
+                        case WND_DECORATOR_TOP_RIGHT:
+                            (*pCurLayoutKeyCoordinates)[button_index].x = width - decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].y = 0;
+                            (*pCurLayoutKeyCoordinates)[button_index].width = decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].height = decoration_size;
+                            break;
+                        case WND_DECORATOR_MIDDLE_LEFT:
+                            (*pCurLayoutKeyCoordinates)[button_index].x = 0;
+                            (*pCurLayoutKeyCoordinates)[button_index].y = decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].width = decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].height = height - (2 * decoration_size);
+                            break;
+                        case WND_DECORATOR_MIDDLE_CENTER:
+                            (*pCurLayoutKeyCoordinates)[button_index].x = 0;
+                            (*pCurLayoutKeyCoordinates)[button_index].y = 0;
+                            (*pCurLayoutKeyCoordinates)[button_index].width = width;
+                            (*pCurLayoutKeyCoordinates)[button_index].height = height;
+                            break;
+                        case WND_DECORATOR_MIDDLE_RIGHT:
+                            (*pCurLayoutKeyCoordinates)[button_index].x = width - decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].y = decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].width = decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].height = height - (2 * decoration_size);
+                            break;
+                        case WND_DECORATOR_BOTTOM_LEFT:
+                            (*pCurLayoutKeyCoordinates)[button_index].x = 0;
+                            (*pCurLayoutKeyCoordinates)[button_index].y = height - decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].width = decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].height = decoration_size;
+                            break;
+                        case WND_DECORATOR_BOTTOM_CENTER:
+                            (*pCurLayoutKeyCoordinates)[button_index].x = decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].y = height - decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].width = width - (2 * decoration_size);
+                            (*pCurLayoutKeyCoordinates)[button_index].height = decoration_size;
+                            break;
+                        case WND_DECORATOR_BOTTOM_RIGHT:
+                            (*pCurLayoutKeyCoordinates)[button_index].x = width - decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].y = height - decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].width = decoration_size;
+                            (*pCurLayoutKeyCoordinates)[button_index].height = decoration_size;
+                            break;
+                    }
+
+                    (*pCurButtonContext)[button_index].used = TRUE;
+                    (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+                    (*pCurLayoutKeyCoordinates)[button_index].button_type = BUTTON_TYPE_UIITEM;
+                    (*pCurLayoutKeyCoordinates)[button_index].valid = TRUE;
+                    (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[0][0] =
+                        (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[0][1] =
+                        (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[1][0] =
+                        (*pCurLayoutKeyCoordinates)[button_index].bg_image_path[1][1] =
+                        autopopup_configure->decoration_image_path[loop];
+                }
+                button_index++;
+            }
+        }
+    }
+}
+
+/**
+* Sets the current theme name
+*/
+sclboolean
+CSCLResourceCache::set_cur_themename(const sclchar *themename)
+{
+    if (themename) {
+        strncpy(mCurThemename, themename, _POSIX_PATH_MAX - 1);
+        mCurThemename[_POSIX_PATH_MAX - 1] = '\0';
+    }
+
+    return TRUE;
+}
+
+const sclchar*
+CSCLResourceCache::get_cur_themename()
+{
+    return mCurThemename;
+}
+
+/**
+ * Returns a template private key properties using key properties of the given context
+ */
+void
+CSCLResourceCache::clone_keyproperties(SclPrivateKeyProperties* priv, sclbyte input_mode_index, sclbyte layout_index, sclbyte key_index)
+{
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (!sclres_manager) return;
+
+    const PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
+
+    SCL_DEBUG();
+    if (priv && sclres_layout_key_coordinate_pointer_frame) {
+        clear_privatekeyproperties(priv);
+
+        /* gets the value of the previous key properties */
+        SclLayoutKeyCoordinate keyCoordinate;
+        memset(&keyCoordinate, 0x00, sizeof(keyCoordinate));
+        if (scl_check_arrindex_unsigned(layout_index, MAX_SCL_LAYOUT) &&
+            scl_check_arrindex_unsigned(key_index, MAX_KEY)) {
+            SclLayoutKeyCoordinatePointer p = sclres_layout_key_coordinate_pointer_frame[layout_index][key_index];
+            if (p) {
+                memcpy(&keyCoordinate, p, sizeof(SclLayoutKeyCoordinate));
+            }
+        }
+
+        scl_assert_return(keyCoordinate.valid == TRUE);
+
+        /* Sets the default properties base on the properties values of the given context */
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        if (cache) {
+            cache->copy_to_privatekeyproperties(&keyCoordinate, priv);
+        }
+    }
+}
+
+/**
+ * Sets a private key to the current context
+ *
+ * @Usage
+ *       SclPrivateKeyProperties privProperties;
+ *       gCore->clone_keyproperties(&privProperties, INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0);
+ *       // change
+ *       gCore->set_private_key(&privProperties, TRUE);
+ */
+sclint
+CSCLResourceCache::set_private_key(SclPrivateKeyProperties* properties, sclboolean fRedraw, sclboolean fPendingUpdate)
+{
+    SCL_DEBUG();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    sclint privateId = NOT_USED;
+    sclboolean isNeedUpdate = FALSE;
+    if (cache && context && properties) {
+        privateId = cache->add_private_key(properties, &isNeedUpdate);
+        if (fRedraw && isNeedUpdate && !fPendingUpdate && privateId != NOT_USED) {
+            CSCLWindows *windows = CSCLWindows::get_instance();
+            if (windows) {
+                /* Fix me (we should consider popupwindow later)*/
+                windows->update_window(windows->get_base_window());
+            }
+        }
+    }
+    return privateId;
+}
+
+/**
+ * Sets a private key to the current context
+ * The other properties except given parameters will keep to the original value.
+ * @Usage
+ * gCore->set_private_key(INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0, "private", 999, TRUE);
+ *
+ * @param fRedraw If true, it will redraw the current key
+ */
+sclint
+CSCLResourceCache::set_private_key(const sclchar* custom_id, sclchar* label, sclchar* imagelabel[SCL_BUTTON_STATE_MAX], sclchar* imagebg[SCL_BUTTON_STATE_MAX], sclulong key_event, sclchar *key_value, sclboolean fRedraw, sclboolean fPendingUpdate)
+{
+    SCL_DEBUG();
+
+    SclPrivateKeyProperties privProperties;
+    clear_privatekeyproperties(&privProperties);
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (!sclres_manager) return NOT_USED;
+
+    PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame = sclres_manager->get_key_coordinate_pointer_frame();
+    assert(sclres_layout_key_coordinate_pointer_frame != NULL);
+
+    sclint loop;
+
+    privProperties.valid = TRUE;
+    privProperties.custom_id = custom_id;
+
+    privProperties.key_event[SCL_SHIFT_STATE_LOCK][0] = privProperties.key_event[SCL_SHIFT_STATE_ON][0] =
+        privProperties.key_event[SCL_SHIFT_STATE_OFF][0] = key_event;
+    if (label) {
+        privProperties.label[SCL_SHIFT_STATE_LOCK][0] = label;
+        privProperties.label[SCL_SHIFT_STATE_ON][0] = label;
+        privProperties.label[SCL_SHIFT_STATE_OFF][0] = label;
+    }
+    if (key_value) {
+        privProperties.key_value[SCL_SHIFT_STATE_LOCK][0] = privProperties.key_value[SCL_SHIFT_STATE_ON][0] =
+            privProperties.key_value[SCL_SHIFT_STATE_OFF][0] = key_value;
+    }
+    if (imagelabel) {
+        for (loop =0;loop < SCL_BUTTON_STATE_MAX;loop++) {
+            if (imagelabel[loop])
+                privProperties.image_label_path[SCL_SHIFT_STATE_LOCK][loop] =
+                    privProperties.image_label_path[SCL_SHIFT_STATE_ON][loop] =
+                    privProperties.image_label_path[SCL_SHIFT_STATE_OFF][loop] = imagelabel[loop];
+            }
+        }
+    if (imagebg) {
+        for (loop =0;loop < SCL_BUTTON_STATE_MAX;loop++) {
+            if (imagebg[loop]) {
+                privProperties.bg_image_path[SCL_SHIFT_STATE_LOCK][loop] =
+                    privProperties.bg_image_path[SCL_SHIFT_STATE_ON][loop] =
+                    privProperties.bg_image_path[SCL_SHIFT_STATE_OFF][loop] = imagebg[loop];
+            }
+        }
+    }
+    return set_private_key(&privProperties, fRedraw, fPendingUpdate);
+}
+
+/**
+* Unset private key for specific key
+* @Usage
+* gCore->unset_private_key(INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0);
+*/
+void
+CSCLResourceCache::unset_private_key(sclshort input_mode_index, sclbyte layout_index, sclbyte key_index)
+{
+    sclint loop = 0;
+    for (loop = 0;loop < MAX_PRIVATE_KEY; loop++) {
+        if ((mPrivateKeyProperties[loop].input_mode_index == input_mode_index) &&
+            mPrivateKeyProperties[loop].layout_index == layout_index &&
+            mPrivateKeyProperties[loop].key_index == key_index) {
+                remove_private_key(loop);
+        }
+    }
+}
+
+/**
+* Unset private by custom_id, effective when removing all private keys with same custom_id
+* @Usage
+* gCore->unset_private_key(3);
+*/
+void
+CSCLResourceCache::unset_private_key(const sclchar* custom_id)
+{
+    int loop;
+    if (custom_id) {
+        for (loop = 0;loop < MAX_PRIVATE_KEY;loop++) {
+            if (mPrivateKeyProperties[loop].valid &&
+                mPrivateKeyProperties[loop].custom_id.compare(custom_id) == 0) {
+                remove_private_key(loop);
+            }
+        }
+    }
+}
+
+/**
+* Enable/disable button for handling mouse events
+*/
+void CSCLResourceCache::enable_button(const sclchar *custom_id, sclboolean enabled)
+{
+    SCL_DEBUG();
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!windows || !context || !sclres_manager) return;
+
+    sclint loop;
+    if (custom_id) {
+        sclbyte layout_index = NOT_USED;
+        PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame =
+            sclres_manager->get_key_coordinate_pointer_frame();
+        if (!sclres_layout_key_coordinate_pointer_frame) return;
+
+        if (context) {
+            layout_index = context->get_base_layout();
+        }
+        if (scl_check_arrindex_unsigned(layout_index, MAX_SCL_LAYOUT)) {
+            for (loop = 0;loop < MAX_KEY;loop++) {
+                SclLayoutKeyCoordinatePointer p =
+                    sclres_layout_key_coordinate_pointer_frame[layout_index][loop];
+                if (!p || !(p->valid)) break;
+                if (p->custom_id) {
+                    if (strcmp(p->custom_id, custom_id) == 0) {
+                        if (enabled) {
+                            mCurBaseButtonContext[loop].state = BUTTON_STATE_NORMAL;
+                        } else {
+                            mCurBaseButtonContext[loop].state = BUTTON_STATE_DISABLED;
+                        }
+                    }
+                }
+            }
+        }
+
+        /* Fix me (we should decide by which way we would redraw the button's region - direct or indirect?)*/
+        if (windows) {
+            windows->update_window(windows->get_base_window());
+        }
+
+        sclboolean found = FALSE;
+        sclint empty_index = -1;
+
+        for (loop = 0;loop < MAX_DISABLED_KEY;loop++) {
+            if (!(mDisabledKeyList[loop].empty())) {
+                if (mDisabledKeyList[loop].compare(custom_id) == 0) {
+                    if (enabled) {
+                        /* Erase this item from the disabled key list */
+                        mDisabledKeyList[loop].clear();
+                    }
+                    found = TRUE;
+                }
+            } else {
+                empty_index = loop;
+            }
+        }
+
+        if (!found) {
+            if (!enabled) {
+                if (scl_check_arrindex(empty_index, MAX_DISABLED_KEY)) {
+                    /* Add to the disabled key */
+                    mDisabledKeyList[empty_index] = custom_id;
+                }
+            }
+        }
+    }
+}
+
+/**
+* Get geometry information of a button with given custom_id
+*/
+sclboolean CSCLResourceCache::get_button_geometry(const sclchar* custom_id, SclRectangle *rectangle)
+{
+    SCL_DEBUG();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!context || !sclres_manager) return FALSE;
+
+    sclint loop;
+    if (custom_id && rectangle) {
+        sclbyte layout_index = NOT_USED;
+        PSclLayoutKeyCoordinatePointerTable sclres_layout_key_coordinate_pointer_frame =
+            sclres_manager->get_key_coordinate_pointer_frame();
+        if (!sclres_layout_key_coordinate_pointer_frame) return FALSE;
+
+        if (context) {
+            layout_index = context->get_base_layout();
+        }
+        if (scl_check_arrindex_unsigned(layout_index, MAX_SCL_LAYOUT)) {
+            for (loop = 0;loop < MAX_KEY;loop++) {
+                SclLayoutKeyCoordinatePointer p = &mCurBaseLayoutKeyCoordinates[loop];
+                if (!p || !(p->valid)) break;
+                if (p->custom_id) {
+                    if (strcmp(p->custom_id, custom_id) == 0) {
+                        rectangle->x = p->x;
+                        rectangle->y = p->y;
+                        rectangle->width = p->width;
+                        rectangle->height = p->height;
+
+                        return TRUE;
+                    }
+                }
+            }
+        }
+    }
+
+    return FALSE;
+}
+
+sclboolean
+CSCLResourceCache::set_string_substitution(const sclchar *original, const sclchar *substitute)
+{
+    if (original && substitute) {
+        if (mStringSubstitutor[std::string(original)].compare(substitute) == 0) {
+            return false;
+        }
+        mStringSubstitutor[std::string(original)] = std::string(substitute);
+    }
+    return true;
+}
+
+void
+CSCLResourceCache::unset_string_substitution(const sclchar *original)
+{
+    if (original) {
+        mStringSubstitutor.erase(std::string(original));
+    }
+}
+
+const sclchar*
+CSCLResourceCache::find_substituted_string(const sclchar *original)
+{
+    const sclchar* ret = original;
+
+    if (original) {
+        std::map<std::string, std::string>::iterator iter = mStringSubstitutor.find(std::string(original));
+        if (iter != mStringSubstitutor.end()) {
+            ret = iter->second.c_str();
+        }
+    }
+
+    return ret;
+}
+
+void
+CSCLResourceCache::set_custom_starting_coordinates(sclint x, sclint y)
+{
+    mCurStartingCoordinates.x = x;
+    mCurStartingCoordinates.y = y;
+}
+
+SclPoint
+CSCLResourceCache::get_custom_starting_coordinates()
+{
+    return mCurStartingCoordinates;
+}
+
+void
+CSCLResourceCache::set_custom_starting_coordinates_option(SCLStartingCoordinatesOption option)
+{
+    mCurStartingCoordinatesOption = option;
+}
+
+SCLStartingCoordinatesOption
+CSCLResourceCache::get_custom_starting_coordinates_option()
+{
+    return mCurStartingCoordinatesOption;
+}
diff --git a/scl/sclresourcecache.h b/scl/sclresourcecache.h
new file mode 100644 (file)
index 0000000..df1af1a
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012 - 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 "sclgwes.h"
+#include "sclutils.h"
+#include "sclresource.h"
+
+#ifndef __SCL_RESOURCE_CACHE_H__
+#define __SCL_RESOURCE_CACHE_H__
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+
+typedef struct _SclButtonContext {
+    sclboolean used;
+    sclbyte multitap_index;
+    sclboolean toggled;
+    SCLButtonState state;
+} SclButtonContext;
+/**
+* @brief The class to store current state of key layout
+*
+* This class implements all functions for working as a soft-based keyboard
+* In side of ISE developer, they can modify it by their requirements.
+*/
+class CSCLResourceCache
+{
+private:
+    CSCLResourceCache();
+
+public:
+    virtual ~CSCLResourceCache();
+
+    static CSCLResourceCache* get_instance();
+
+    sclboolean init();
+    sclboolean recompute_layout(sclwindow window);
+
+    const SclLayout* get_cur_layout(sclwindow window) const;
+    SclLayoutKeyCoordinate* get_cur_layout_key_coordinate(sclwindow window, sclbyte key_index);
+
+    const SclLabelProperties* get_label_properties(sclchar *label_type, sclbyte index) const;
+
+    SclButtonContext* get_cur_button_context(sclwindow window, sclbyte key_index);
+
+    sclboolean clear_private_keys();
+    sclint add_private_key(SclPrivateKeyProperties* properties, sclboolean *fNeedInvalid);
+    sclboolean remove_private_key(sclint id);
+
+    sclboolean copy_from_privatekeyproperties(const SclPrivateKeyProperties* privProperties, SclLayoutKeyCoordinate* coordinate);
+    sclboolean copy_to_privatekeyproperties(const SclLayoutKeyCoordinate *coordinate, SclPrivateKeyProperties* privProperties);
+    sclboolean copy_privatekeyproperties(const SclPrivateKeyProperties* source, SclPrivateKeyProperties* target);
+    sclboolean clear_privatekeyproperties(SclPrivateKeyProperties* privProperties);
+
+    sclboolean set_cur_themename(const sclchar *themename);
+    const sclchar* get_cur_themename();
+
+    sclint set_private_key(SclPrivateKeyProperties* properties, sclboolean fRedraw, sclboolean fPendingUpdate);
+    sclint set_private_key(const sclchar* custom_id, sclchar* label, sclchar* imagelabel[SCL_BUTTON_STATE_MAX], sclchar* imagebg[SCL_BUTTON_STATE_MAX], sclulong key_event, sclchar *key_value, sclboolean fRedraw, sclboolean fPendingUpdate);
+    void unset_private_key(sclshort input_mode_index, sclbyte layout_index, sclbyte key_index);
+    void unset_private_key(const sclchar* custom_id);
+
+    void clone_keyproperties(SclPrivateKeyProperties* priv, sclbyte input_mode_index, sclbyte layout_index, sclbyte key_index);
+
+    void enable_button(const sclchar* custom_id, sclboolean enabled);
+    sclboolean get_button_geometry(const sclchar* custom_id, SclRectangle *rectangle);
+
+    sclboolean set_string_substitution(const sclchar *original, const sclchar *substitute);
+    void unset_string_substitution(const sclchar *original);
+    const sclchar* find_substituted_string(const sclchar *original);
+
+    void set_custom_starting_coordinates(sclint x, sclint y);
+    SclPoint get_custom_starting_coordinates();
+
+    void set_custom_starting_coordinates_option(SCLStartingCoordinatesOption option);
+    SCLStartingCoordinatesOption get_custom_starting_coordinates_option();
+
+    sclboolean resize_resource_elements_by_resolution();
+private:
+    sclboolean resize_layout_by_resolution(sclbyte layout_index, sclboolean resize_key_only = FALSE);
+    sclboolean change_by_privatekey(const sclbyte input_mode_index, const sclbyte layout_index, const sclbyte key_index, SclLayoutKeyCoordinate* coordinate);
+
+    void generate_autopopup_layout(const SclLayoutKeyCoordinate *coordinate,
+                                   SclLayout *pCurLayout,
+                                   SclLayoutKeyCoordinate (*pCurLayoutKeyCoordinates)[MAX_KEY],
+                                   SclButtonContext (*pCurButtonContext)[MAX_KEY]);
+
+protected:
+    SclLayout mCurBaseLayout;
+    SclLayoutKeyCoordinate mCurBaseLayoutKeyCoordinates[MAX_KEY];
+
+    SclButtonContext mCurBaseButtonContext[MAX_KEY];
+
+    SclLayout mCurPopupLayout[MAX_POPUP_WINDOW];
+    SclLayoutKeyCoordinate mCurPopupLayoutKeyCoordinates[MAX_POPUP_WINDOW][MAX_KEY];
+
+    SclButtonContext mCurPopupButtonContext[MAX_POPUP_WINDOW][MAX_KEY];
+
+    SclPrivateKeyProperties mPrivateKeyProperties[MAX_PRIVATE_KEY];
+    std::string mDisabledKeyList[MAX_DISABLED_KEY];
+    std::map<std::string, std::string> mStringSubstitutor;
+
+    sclchar mCurThemename[_POSIX_PATH_MAX];
+
+    SclPoint mCurStartingCoordinates;
+    SCLStartingCoordinatesOption mCurStartingCoordinatesOption;
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif
diff --git a/scl/sclstructs.h b/scl/sclstructs.h
new file mode 100644 (file)
index 0000000..7058f09
--- /dev/null
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2012 - 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 <string>
+#include "scltypes.h"
+#include "sclconfig.h"
+
+#ifndef __SCL_STRUCTS_H__
+#define __SCL_STRUCTS_H__
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+
+/**
+  *@brief SCL input mode configuration structure, which indicates a type of SW keyboard
+  */
+typedef struct _SclInputModeConfigure {
+    sclchar* name;                                             /* Name of this inputmode */
+    sclchar* layouts[DISPLAYMODE_MAX]; /* This contains the filename of each layouts */
+    sclboolean use_virtual_window;             /* Whether to use a new window or make a popup window as a layer of existing base window */
+    sclboolean use_dim_window;                 /* Whether to use a dim window */
+    sclint timeout;                                            /* fTimeout seconds of idle state will close this popup window. Set 0 to disable */
+}SclInputModeConfigure;
+
+/**
+  *@brief SCL Layout structure, which is a physical keyboard representation defined by a group of SclLayoutKeyCoordinates
+  */
+typedef struct _SclLayout {
+    sclboolean valid;                                  /* Indicates whether this information is in use or not */
+
+    sclchar* name;                                             /* Name of this layout */
+    SCLDisplayMode display_mode;               /* Indicates whether this layout is for portrait mode or landscape display */
+    SCLLayoutStyle style;                              /* Desribes the style of this layout */
+
+    sclshort width;                                            /* Width of this layout */
+    sclshort height;                                   /* Height of this layout*/
+
+    sclboolean use_sw_button;                  /* Whether to draw buttons by SW or not */
+    sclboolean use_magnifier_window;   /* Whether to use magnifier window or not */
+    sclboolean extract_background;             /* Whether to display only some part of background image */
+
+    sclshort key_width;                                        /* Default width of key */
+    sclshort key_height;                               /* Default height of keys */
+    sclshort key_spacing;                              /* Default spacing amount between keys */
+    sclshort row_spacing;                              /* Default spacing amount between rows */
+
+    sclshort add_hit_left;                             /* Left value for expanded hit area */
+    sclshort add_hit_right;                            /* Right value for expanded hit area */
+    sclshort add_hit_top;                              /* Left value for expanded hit area */
+    sclshort add_hit_bottom;                   /* Left value for expanded hit area */
+
+    sclboolean use_sw_background;              /* Whether to draw background by SW or not */
+    SclColor bg_color;                                 /* If drawn by SW, describes the background color */
+    scldouble bg_line_width;                   /* If drawn by SW, describes the background border width */
+    SclColor bg_line_color;                            /* If drawn by SW, describes the background border color */
+
+    sclshort add_grab_left;                            /* If this layout's style is POPUP_GRAB, desribes the left pixel for grab area */
+    sclshort add_grab_right;                   /* If this layout's style is POPUP_GRAB, desribes the right pixel for grab area */
+    sclshort add_grab_top;                             /* If this layout's style is POPUP_GRAB, desribes the top pixel for grab area */
+    sclshort add_grab_bottom;                  /* If this layout's style is POPUP_GRAB, desribes the bottom pixel for grab area */
+
+    sclshort mouse_manipulate_x;               /* The X-point that this layout needs to manipulate the position of mouse event */
+    sclshort mouse_manipulate_y;               /* The Y-point that this layout needs to manipulate the position of mouse event */
+
+    /* Background image of each button state */
+    sclchar* image_path[SCL_BUTTON_STATE_MAX];
+
+    /* Default background images for keys */
+    sclchar* key_background_image[SCL_SHIFT_STATE_MAX][SCL_BUTTON_STATE_MAX];
+
+    sclchar* sound_style;                              /* A default sound feedback style when buttons are clicked */
+    sclchar* vibe_style;                               /* A default vibration feedback style when this buttons are clicked */
+    sclchar* label_type;                               /* Default label property type for specifying the appearance of label strings */
+
+    /* If the button should be displayed differently depending on the modifier, describe a decorator and provide its ID here */
+    sclchar* modifier_decorator;
+}SclLayout;
+
+/**
+  *@brief SCL Layout key coordinate structure, which represents a key's position-related information
+  */
+typedef struct _SclLayoutKeyCoordinate {
+    sclboolean valid;                                  /* Indicates whether this information is in use or not */
+    sclshort x;                                                        /* X coordinate of this button */
+    sclshort y;                                                        /* Y coordinate of this button */
+    sclshort width;                                            /* Width of this button */
+    sclshort height;                                   /* Height of this button */
+    sclshort add_hit_left;                             /* Left value for expanded hit area */
+    sclshort add_hit_right;                            /* Right value for expanded hit area */
+    sclshort add_hit_top;                              /* Left value for expanded hit area */
+    sclshort add_hit_bottom;                   /* Left value for expanded hit area */
+    sclshort popup_relative_x;                 /* Relative X offset for popup window */
+    sclshort popup_relative_y;                 /* Relative Y offset for popup window */
+    sclshort extract_offset_x;                 /* If the popup layout has ExtractBG, this value provides the X offset inside the BG image */
+    sclshort extract_offset_y;                 /* If the popup layout has ExtractBG, this value provides the Y offset inside the BG image */
+    sclchar* sub_layout;                               /* Indicates which sublayout this button belongs to */
+    sclshort magnifier_offset_x;               /* Relative X offset for magnifier window */
+    sclshort magnifier_offset_y;               /* Relative Y offset for magnifier window */
+
+    sclchar* custom_id;                                        /* A value for indentifying a button when handling private keys or disable key. */
+    SCLButtonType button_type;                 /* Indicates the behavioral type of this button */
+    SCLKeyType key_type;                               /* Delivered key type when the button event is emitted */
+    SCLPopupType popup_type;                   /* Popup type when this button is activated */
+    sclboolean use_magnifier;                  /* Indicates whether this button needs to display magnifier window when clicked */
+    sclboolean use_long_key_magnifier; /* Indicates whether this button needs to display magnifier window when long-pressed */
+    /* Popup inputmode IDs depending on the direction of the drag action */
+    sclchar* popup_input_mode[SCL_DRAG_STATE_MAX];
+    sclchar* sound_style;                              /* A sound feedback style when this button is clicked */
+    sclchar* vibe_style;                               /* A vibration feedback style when this button is clicked */
+    sclboolean is_side_button;                 /* Indicates whether this button is located on the very left or right of the layout */
+
+    sclbyte label_count;                               /* Number of labels for this button (Max value :MAX_SIZE_OF_LABEL_FOR_ONE )*/
+    /* Label strings depending on the shift state */
+    sclchar* label[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_LABEL_FOR_ONE];
+    sclchar* label_type;                               /* Label propery name for specifying the appearance of label strings */
+    /* image_path for the case of image label */
+    sclchar* image_label_path[SCL_SHIFT_STATE_MAX][SCL_BUTTON_STATE_MAX];
+    sclchar* image_label_type;                 /* Label propery name for specifying the appearance of image labels */
+    /* If bg_image_path is NULL, background will not be drawn. If "", layout image will be used instead */
+    /* image_path for the button's background */
+    sclchar* bg_image_path[SCL_SHIFT_STATE_MAX][SCL_BUTTON_STATE_MAX];
+    sclbyte key_value_count;                   /* Number of key events in case of multitap or rotation button */
+    /* A string value delivered to ISE when clicked */
+    sclchar* key_value[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_MULTITAP_CHAR];
+    /* A long int value delivered to ISE when clicked */
+    sclulong key_event[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_MULTITAP_CHAR];
+    SCLKeyType long_key_type;                          /* A key type delivered to ISE when long key clicked */
+    sclchar* long_key_value;                   /* A string value delivered to ISE when long key clicked */
+    sclulong long_key_event;                   /* A long int value delivered to ISE when long key clicked */
+    sclboolean use_repeat_key;                 /* Indicates whether this button allows repeated key events when pressed for a long time */
+    /* optional */
+    /* A string of candidate characters that will be shown in an autopopup window */
+    sclchar* autopopup_key_labels[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_AUTOPOPUP_STRING];
+    sclulong autopopup_key_events[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_AUTOPOPUP_STRING];
+    sclchar* autopopup_key_values[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_AUTOPOPUP_STRING];
+    /* When set, any events raised from this button will not close opened popup window */
+    sclboolean dont_close_popup;
+    /* Extra options for each types of buttons :
+        BUTTON_TYPE_ROTATION - Set to 1 if the button should return to initial state when other key is pressed
+        BUTTON_TYPE_DIRECTION -
+            use definitions below, that are declared in sclconfig.h file
+
+            #define DIRECTION_EXTRA_OPTION_4_DIRECTIONS 0
+            #define DIRECTION_EXTRA_OPTION_8_DIRECTIONS 1
+            #define DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_LONG 2
+            #define DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG 3
+            #define DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN 4
+            #define DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN 5
+            #define DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE 6
+    */
+    sclbyte extra_option;
+    sclbyte multitouch_type;                   /* Indicates what kind of multitouch type this button supports */
+    /* If the button should be displayed differently depending on the modifier, describe a decorator and provide its ID here */
+    sclchar* modifier_decorator;
+    /* For the case if this button needs to display multiple labels or different string from the label string */
+    sclchar* magnifier_label[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_LABEL_FOR_ONE];
+
+    sclchar* hint_string[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_MULTITAP_CHAR];
+}SclLayoutKeyCoordinate;
+
+///**
+//*@brief SCL Layout keyset structure, indicates which keyset should be used for specific inputmode and layout combination
+//*/
+//typedef struct _SclLayoutKeyset {
+//    sclint inputmodeID;              /* Target inputmode ID */
+//    sclint layoutID;         /* Target layout ID */
+//    sclint keysetID;         /* Keyset ID that should be selected when the above inputmodeID and layoutID are given */
+//    sclboolean popupEntry;   /* Whether this entry is for popup layout */
+//} SclLayoutKeyset;
+
+///**
+//  *@brief SCL Layout key configure structure
+//  */
+//typedef struct _SclLayoutKeyConfigure {
+//    sclboolean valid;                        /* Indicates whether this information is in use or not */
+//    sclchar* custom_id;                      /* A value for indentifying a button when handling private keys or disable key. */
+//    SCLButtonType button_type;       /* Indicates the behavioral type of this button */
+//    SCLKeyType key_type;                     /* Delivered key type when the button event is emitted */
+//    SCLPopupType popup_type;         /* Popup type when this button is activated */
+//    sclboolean use_magnifier;        /* Indicates whether this button needs to display magnifier window when clicked */
+//    sclboolean use_long_key_magnifier;       /* Indicates whether this button needs to display magnifier window when long-pressed */
+//    sclboolean enabled;                      /* Indicates whether this button needs to be automatically enabled */ /* SEEMS TO BE NEEDLESS */
+//    sclbyte popup_input_mode[SCL_DRAG_STATE_MAX];    /* Popup inputmode IDs depending on the direction of the drag action */
+//    sclchar* sound_style;    /* A sound feedback style when this button is clicked */
+//    sclchar* vibe_style;             /* A vibration feedback style when this button is clicked */
+//    sclboolean is_side_button;       /* Indicates whether this button is located on the very left or right of the layout */
+//}SclLayoutKeyConfigure;
+
+/**
+  *@brief SCL Label properties structure
+  */
+typedef struct _SclLabelProperties {
+    sclboolean valid;                                          /* Indicates whether this information is in use or not */
+    sclchar* label_type;                                       /* Identifies the current label property */
+    sclchar* font_name;                                                /* Font name of this label property */
+    sclbyte font_size;                                         /* Font size of this label property */
+    /* Font color depending on the button and shift state */
+    SclColor font_color[SCL_SHIFT_STATE_MAX][SCL_BUTTON_STATE_MAX];
+    SCLLabelAlignment alignment;                       /* Alignment option for this label property */
+    sclshort padding_x;                                                /* X padding value for alignment option above */
+    sclshort padding_y;                                                /* Y padding value for alignment option above */
+    sclbyte inner_width;                                       /* Inner width value for making a inner rect padded in above values */
+    sclbyte inner_height;                                      /* Inner height value for making a inner rect padded in above values */
+    sclbyte shadow_distance;                           /* A distance value for drawing shadow */
+    SCLShadowDirection shadow_direction;       /* A direction option for drawing shadown */
+    /* Shadow color depeding on the button and shift state */
+       SclColor shadow_color[SCL_SHIFT_STATE_MAX][SCL_BUTTON_STATE_MAX];
+}SclLabelProperties;
+
+/**
+  *@brief SCL Layout key properties structure
+  */
+/* SCL Supports drawing button's background using SclLayout's image_path - use below macro to bg_image_path for this feature */
+#define SCL_BACKGROUND_IMAGE_STRING "BACKGROUND_IMAGE"
+#define _Label_
+#define _LabelImg_
+#define _BGImg_
+#define _KeyVal_
+#define _KeyEvt_
+//typedef struct _SclLayoutKeyProperties {
+//    sclboolean valid;                        /* Indicates whether this information is in use or not */
+//    sclbyte label_count;                     /* Number of labels for this button (Max value :MAX_SIZE_OF_LABEL_FOR_ONE )*/
+//    sclchar* label[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_LABEL_FOR_ONE]; /* Label strings depending on the shift state */
+//    sclchar* label_name;                     /* Label propery name for specifying the appearance of label strings */
+//    sclchar* label_image_path[SCL_SHIFT_STATE_MAX][SCL_BUTTON_STATE_MAX];    /* image_path for the case of image label */
+//    /** If bg_image_path is NULL, background will not be drawn. If "", layout image will be used instead */
+//    sclchar* bg_image_path[SCL_SHIFT_STATE_MAX][SCL_BUTTON_STATE_MAX];       /* image_path for the button's background */
+//    sclbyte key_value_count;         /* Number of key events in case of multitap or rotation button */
+//    sclchar* key_value[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_MULTITAP_CHAR];      /* A string value delivered to ISE when clicked */
+//    sclulong key_event[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_MULTITAP_CHAR];      /* A long int value delivered to ISE when clicked */
+//    sclchar* long_key_value;         /* A string value delivered to ISE when long key clicked */
+//    sclulong long_key_event;         /* A long int value delivered to ISE when long key clicked */
+//    sclboolean use_repeat_key;       /* Indicates whether this button allows repeated key events when pressed for a long time */
+//    /* optional */
+//    /* A string of candidate characters that will be shown in an autopopup window */
+//    sclchar* autopopup_keys[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_AUTOPOPUP_STRING];
+//    /* When set, any events raised from this button will not close opened popup window */
+//    sclboolean dont_close_popup;
+//    /* Extra options for each types of buttons :
+//        BUTTON_TYPE_ROTATION - Set to 1 if the button should return to initial state when other key is pressed
+//        BUTTON_TYPE_DIRECTION -
+//            use definitions below, that are declared in sclconfig.h file
+//
+//            #define DIRECTION_EXTRA_OPTION_4_DIRECTIONS 0
+//            #define DIRECTION_EXTRA_OPTION_8_DIRECTIONS 1
+//            #define DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_LONG 2
+//            #define DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG 3
+//            #define DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN 4
+//            #define DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN 5
+//            #define DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE 6
+//    */
+//    sclbyte extra_option;
+//    sclbyte multitouch_type;         /* Indicates what kind of multitouch type this button supports */
+//    /* If the button should be displayed differently depending on the modifier, describe a decorator and provide its ID here */
+//    sclbyte modifier_decorator;
+//    /* For the case if this button needs to display multiple labels or different string from the label string */
+//    sclchar* magnifier_label[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_LABEL_FOR_ONE];
+//}SclLayoutKeyProperties;
+
+/**
+  *@brief SCL private key structure for application, to change the configuration and property of a specific key
+  */
+typedef struct _SclPrivateKeyProperties {
+    sclboolean valid;                          /* Indicates whether this information is in use or not */
+    sclshort input_mode_index;         /* Target inputmode index that this private key wants to affect */
+    sclshort layout_index;                     /* Target layout index that this private key wants to affect */
+    sclbyte key_index;                         /* Target key index that this private key wants to affect */
+
+    /* Configurations */ /* Has same purpose with the SclLayoutKeyConfiguration's member variable */
+    std::string custom_id;
+    SCLButtonType button_type;
+    SCLKeyType key_type;
+    SCLPopupType popup_type;
+    sclboolean use_magnifier;
+    sclboolean use_long_key_magnifier;
+    sclboolean enabled;
+    std::string popup_input_mode[SCL_DRAG_STATE_MAX];
+    std::string sound_style;
+    std::string vibe_style;
+
+    /* Properties */ /* Has same purpose with the SclLayoutKeyProperties' member variable */
+    sclbyte label_count;
+    std::string label[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_LABEL_FOR_ONE];
+    std::string label_type;
+    std::string image_label_path[SCL_SHIFT_STATE_MAX][SCL_BUTTON_STATE_MAX];
+    std::string image_label_type;
+    std::string bg_image_path[SCL_SHIFT_STATE_MAX][SCL_BUTTON_STATE_MAX];
+    sclbyte key_value_count;
+    std::string key_value[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_MULTITAP_CHAR];
+    sclulong key_event[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_MULTITAP_CHAR];
+    SCLKeyType long_key_type;
+    std::string long_key_value;
+    sclulong long_key_event;
+    sclboolean use_repeat_key;
+    std::string autopopup_key_labels[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_AUTOPOPUP_STRING];
+    sclulong autopopup_key_events[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_AUTOPOPUP_STRING];
+    std::string autopopup_key_values[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_AUTOPOPUP_STRING];
+    sclboolean dont_close_popup;
+    sclbyte extra_option;
+    sclbyte multitouch_type;
+    sclbyte modifier_decorator;
+
+    std::string hint_string[SCL_SHIFT_STATE_MAX][MAX_SIZE_OF_MULTITAP_CHAR];
+}SclPrivateKeyProperties;
+
+/**
+  *@brief SCL S/W button style structure
+  */
+typedef struct _SclSWButtonStyle {
+    scldouble line_width[SCL_BUTTON_STATE_MAX];        /* A border line width when drawing a SW button */
+    SclColor line_color[SCL_BUTTON_STATE_MAX]; /* A border line color when drawing a SW buttton */
+    SclColor bg_color[SCL_BUTTON_STATE_MAX];   /* A background color when drawing a SW button */
+    scldouble line_curve;                                              /* A line curve value for drawing round rectangle. This can be ignored in some platforms */
+    sclfloat bg_alpha;                                                 /* A alpha value used when painting background. This can be ignored in some platforms */
+}SclSWButtonStyle;
+
+/**
+  *@brief SCL input mode configuration structure
+  */
+typedef struct _SclDefaultConfigure {
+    SCLDisplayMode display_mode;                       /* Initial display mode */
+    sclchar *input_mode;                                       /* Initial input mode */
+    sclchar *image_file_base_path;                     /* Default image files directory */
+    sclint target_screen_width;                                /* Targeting screen width */
+    sclint target_screen_height;                       /* Targeting screen height */
+    sclboolean auto_detect_landscape;          /* A flag for switching portrait-landscape if screen width is bigger than height */
+    sclboolean use_magnifier_window;           /* A flag for enabling magnifer window */
+    sclboolean use_auto_popup;                         /* A flag for enabling autopopup window */
+    sclboolean use_zoom_window;                                /* A flag for enabling zoom window */
+    sclboolean on_error_noti_send;                     /* A flag for playing error sound */
+    sclboolean use_word_deletion;                      /* A flag for using word deletion mode when repeating delete key */
+    sclbyte sw_button_style;                           /* Describes which SW button style should be used */
+    /* Touch offset adjustment level description */
+    SCLTouchOffsetLevel touch_offset_level[DISPLAYMODE_MAX];
+    SclPoint touch_offset[DISPLAYMODE_MAX];    /* Touch offset adjustment value description */
+    sclchar *default_sub_layout;                       /* Initial sub_layout_name */
+    sclboolean use_actual_dim_window;          /* Whether to use a new window or make a dim window as a layer of existing base window */
+    SclColor dim_color;                                                /* Color setting for dim window */
+}SclDefaultConfigure;
+
+/**
+  *@brief SCL magnifier(preview) window configuration structure. It will show the selected key label on the magnifier window
+  */
+typedef struct _SclMagnifierWndConfigure {
+    SCLMagnifierStyle style;                   /* Magnifier style description */
+    sclshort width;                                            /* Width of magnifier window */
+    sclshort height;                                   /* Height of magnifier window */
+    SclRect label_area_rect;                   /* Area description for displaying label string */
+    sclchar* bg_image_path;                            /* File path for background image */
+    sclchar* bg_shift_image_path;              /* File path for background image in shift key state */
+    sclchar* bg_shift_lock_image_path; /* File path for background image in shift lock key state */
+    sclchar* bg_long_key_image_path;   /* File path for background image in longkey state */
+    sclboolean use_actual_window;              /* Whether to use a new window or make a popup window as a layer of existing base window */
+    sclchar* label_type;                               /* Label property name for each strings */
+    sclshort padding_x;                                        /* Padding value X for displaying label string */
+    sclshort padding_y;                                        /* Padding value Y for displaying label string */
+    sclboolean show_shift_label;               /* Whether a shift label or a default label string should be displayed in shift mode */
+    /* A 8-way decotation images for magnifier window */
+    sclchar* decoration_image_path[MAX_WND_DECORATOR];
+    sclbyte decoration_size;                   /* Size of window decoration images */
+}SclMagnifierWndConfigure;
+
+/**
+*@brief SCL auto-generated popup configuration structure. Mostly used for umlaut alternate characters in european languages
+*/
+typedef struct _SclAutoPopupConfigure {
+    sclchar* bg_image_path;                            /* File path for background image */
+    SclColor bg_color;                                 /* Background color for SW background */
+    scldouble bg_line_width;                   /* Background SW border width */
+    SclColor bg_line_color;                            /* Background SW border color */
+    sclbyte bg_padding;                                        /* Padding amount between the bg border and buttons */
+    /* A filepath for each button's background image */
+    sclchar* button_image_path[SCL_BUTTON_STATE_MAX];
+    sclbyte sw_button_style;                   /* Describes which SW button style should be used */
+    sclshort button_width;                             /* Each button's width */
+    sclshort button_height;                            /* Each button's height */
+    sclbyte button_spacing;                            /* Spacing amount between buttons */
+    sclchar* line_image_path;           /* Line image between buttons */
+    sclchar* label_type;                               /* Label property name for each strings */
+    /* A 8-way decotation images for autopopup window */
+    sclchar* decoration_image_path[MAX_WND_DECORATOR];
+    sclbyte decoration_size;                   /* Size of window decoration images */
+    sclbyte max_column;                                        /* Maximum number of items in a row */
+
+    sclshort add_grab_left;                            /* If this layout's style is POPUP_GRAB, desribes the left pixel for grab area */
+    sclshort add_grab_right;                   /* If this layout's style is POPUP_GRAB, desribes the right pixel for grab area */
+    sclshort add_grab_top;                             /* If this layout's style is POPUP_GRAB, desribes the top pixel for grab area */
+    sclshort add_grab_bottom;                  /* If this layout's style is POPUP_GRAB, desribes the bottom pixel for grab area */
+}SclAutoPopupConfigure;
+
+/**
+*@brief 9 patch image information struct - image files registered here would be displayed in 9 patch style
+*/
+typedef struct _SclNinePatchInfo {
+    sclchar *image_path;                                       /* File path for identifying nine patch image file */
+    sclshort left;                                             /* Amount of left pixels for describing area that should not be scaled */
+    sclshort right;                                            /* Amount of right pixels for describing area that should not be scaled */
+    sclshort top;                                              /* Amount of top pixels for describing area that should not be scaled */
+    sclshort bottom;                                   /* Amount of bottom pixels for describing area that should not be scaled */
+}SclNinePatchInfo;
+
+/**
+*@brief A struct for decorating a button depending on the current modifier state
+*/
+typedef struct _SclModifierDecoration {
+    sclboolean valid;                                  /* Indicates whether this information is in use or not */
+    sclboolean extract_background;             /* Whether to display only some part of background image */
+    sclchar *name;
+    /* Background image file for decoration */
+    sclchar *bg_image_path[DISPLAYMODE_MAX][KEY_MODIFIER_MAX];
+}SclModifierDecoration;
+
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_STRUCTS_H__
diff --git a/scl/sclui.cpp b/scl/sclui.cpp
new file mode 100644 (file)
index 0000000..0579f8d
--- /dev/null
@@ -0,0 +1,726 @@
+/*
+ * Copyright (c) 2012 - 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 "sclui.h"
+#include "scluiimpl.h"
+
+using namespace scl;
+
+CSCLUI::CSCLUI()
+{
+    m_impl = CSCLUIImpl::get_instance();
+}
+
+CSCLUI::~CSCLUI()
+{
+    m_impl = NULL;
+}
+
+sclboolean CSCLUI::init(sclwindow parent, const SCLParserType parser_type, const char *entry_filepath)
+{
+    sclboolean ret = FALSE;
+    if (m_impl) {
+        ret = m_impl->init(parent, parser_type, entry_filepath);
+    }
+    return ret;
+}
+
+void
+CSCLUI::fini()
+{
+    if (m_impl) {
+        m_impl->fini();
+    }
+}
+
+/**
+ * Shows the SCL main window
+ * For displaying the SCL UI, you should explicitly call this function after CSCLUI class is created
+ */
+void
+//CSCLUI::show(sclboolean auto_relocate /* = TRUE */ )
+CSCLUI::show()
+{
+    if (m_impl) {
+        m_impl->show();
+    }
+}
+
+/**
+ * Hides the SCL main window
+ * The real hide action does not work about base window because that is child of the active window
+ */
+void
+CSCLUI::hide()
+{
+    if (m_impl) {
+        m_impl->hide();
+    }
+}
+
+
+/**
+ * Registers an event callback function
+ * so that the user which uses SCL can recevies all events occuring in running
+ */
+void
+CSCLUI::set_ui_event_callback(ISCLUIEventCallback *callback, const sclchar *input_mode)
+{
+    if (m_impl) {
+        m_impl->set_ui_event_callback(callback, input_mode);
+    }
+}
+
+void
+CSCLUI::set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data)
+{
+    if (m_impl) {
+        m_impl->set_graphics_backend_callback(callback, data);
+    }
+}
+
+void
+CSCLUI::set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data)
+{
+    if (m_impl) {
+        m_impl->set_window_backend_callback(callback, data);
+    }
+}
+
+/**
+ * Sets the current input mode to the given mode
+ * @Usage
+ * gCore->set_input_mode("INPUT_MODE_SYMBOL");
+ */
+sclboolean
+CSCLUI::set_input_mode(const sclchar *input_mode)
+{
+    sclboolean ret = FALSE;
+
+    if (m_impl) {
+        ret = m_impl->set_input_mode(input_mode);
+    }
+
+    return ret;
+}
+
+/**
+ * Returns the current input mode
+ */
+const sclchar*
+CSCLUI::get_input_mode()
+{
+    const sclchar *ret = NULL;
+
+    if (m_impl) {
+        ret = m_impl->get_input_mode();
+    }
+
+    return ret;
+}
+
+/**
+ * Sets the given popup window's input mode to the given mode
+ * @Usage
+ * gCore->set_input_mode("INPUT_MODE_SYMBOL");
+ */
+sclboolean
+CSCLUI::set_popup_input_mode(sclwindow window, const sclchar *input_mode)
+{
+    sclboolean ret = FALSE;
+
+    if (m_impl) {
+        ret = m_impl->set_popup_input_mode(window, input_mode);
+    }
+
+    return ret;
+}
+
+/**
+ * Returns the given popup window's input mode
+ */
+const sclchar*
+CSCLUI::get_popup_input_mode(sclwindow window)
+{
+    const sclchar *ret = NULL;
+
+    if (m_impl) {
+        ret = m_impl->get_popup_input_mode(window);
+    }
+
+    return ret;
+}
+
+
+/**
+ * Sets the current rotation
+ */
+sclboolean
+CSCLUI::set_rotation(SCLRotation rotation)
+{
+    sclboolean ret = FALSE;
+
+    if (m_impl) {
+        ret = m_impl->set_rotation(rotation);
+    }
+
+    return ret;
+}
+
+/**
+ * Gets the current rotation
+ */
+SCLRotation
+CSCLUI::get_rotation()
+{
+    SCLRotation ret = ROTATION_0;
+
+    if (m_impl) {
+        ret = m_impl->get_rotation();
+    }
+
+    return ret;
+}
+
+/**
+ * Returns the current display mode
+ */
+SCLDisplayMode
+CSCLUI::get_display_mode()
+{
+    SCLDisplayMode ret = DISPLAYMODE_PORTRAIT;
+
+    if (m_impl) {
+        ret = m_impl->get_display_mode();
+    }
+
+    return ret;
+}
+
+/**
+ * Sets a private key to the current context
+ * The other properties except given parameters will keep to the orginal value.
+ * @Usage
+ * gCore->set_private_key(INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0, "private", 999, TRUE);
+ *
+ * @param fRedraw If true, it will redraw the current key
+ */
+sclint
+CSCLUI::set_private_key(const sclchar* custom_id, sclchar* label, sclchar* imagelabel[SCL_BUTTON_STATE_MAX], sclchar* imagebg[SCL_BUTTON_STATE_MAX], sclulong key_event, sclchar *key_value, sclboolean redraw)
+{
+    sclint ret = NOT_USED;
+
+    if (m_impl) {
+        ret = m_impl->set_private_key(custom_id, label, imagelabel, imagebg, key_event, key_value, redraw);
+    }
+
+    return ret;
+}
+
+
+/**
+* Unsets a private key to the current context
+*/
+void
+CSCLUI::unset_private_key(const sclchar* custom_id)
+{
+    if (m_impl) {
+        m_impl->unset_private_key(custom_id);
+    }
+}
+
+/**
+* Sets the current theme
+*/
+/* FIXME : If setting themename is not allowed before initializing,
+           the default theme has to be loaded regardless of current theme name
+           and the appropriate current theme has to be loaded afterwards, which is very inefficient */
+sclboolean
+CSCLUI::set_cur_themename(const sclchar *themename)
+{
+    sclboolean ret = FALSE;
+
+    if (m_impl) {
+        ret = m_impl->set_cur_themename(themename);
+    }
+
+    return ret;
+}
+
+SCLShiftState
+CSCLUI::get_shift_state()
+{
+    SCLShiftState ret = SCL_SHIFT_STATE_OFF;
+    if (m_impl) {
+        ret = m_impl->get_shift_state();
+    }
+    return ret;
+}
+
+void
+CSCLUI::set_shift_state(SCLShiftState state)
+{
+    if (m_impl) {
+        m_impl->set_shift_state(state);
+    }
+}
+
+sclboolean
+CSCLUI::get_caps_lock_mode()
+{
+    sclboolean ret = FALSE;
+    if (m_impl) {
+        ret = m_impl->get_caps_lock_mode();
+    }
+    return ret;
+}
+
+void
+CSCLUI::set_caps_lock_mode(sclboolean state)
+{
+    if (m_impl) {
+        m_impl->set_caps_lock_mode(state);
+    }
+}
+
+
+/**
+ * This function will be called by the user which uses SCL when the context of the focus application is changed
+ * ISE user should explicitly call this function when the context of application is changed.
+ * For instance, focus-changed, application-changed,, and so on.
+ * This function will call CSCLController to init the related variables.
+ */
+void
+CSCLUI::notify_app_focus_changed()
+{
+    if (m_impl) {
+        m_impl->notify_app_focus_changed();
+    }
+}
+
+void
+CSCLUI::reset_popup_timeout()
+{
+    if (m_impl) {
+        m_impl->notify_app_focus_changed();
+    }
+}
+
+void
+CSCLUI::close_all_popups()
+{
+    if (m_impl) {
+        m_impl->close_all_popups();
+    }
+}
+
+/**
+ * Returns a scale rate (see default screen resolution in sclconfig.h file)
+ */
+sclfloat
+CSCLUI::get_scale_rate()
+{
+    sclfloat ret = 0.0f;
+    if (m_impl) {
+        ret = m_impl->get_scale_rate();
+    }
+    return ret;
+}
+
+/**
+ * Returns a calculated x value according to the current screen resolution
+ */
+scl16
+CSCLUI::get_scaled_x(scl16 x)
+{
+    scl16 ret = 0;
+    if (m_impl) {
+        ret = m_impl->get_scaled_x(x);
+    }
+    return ret;
+}
+
+/**
+ * Returns a calculated y value according to the current screen resolution
+ */
+scl16
+CSCLUI::get_scaled_y(scl16 y)
+{
+    scl16 ret = 0;
+    if (m_impl) {
+        ret = m_impl->get_scaled_y(y);
+    }
+    return ret;
+}
+
+/**
+ * Returns the current rate x value for resizing the keyboard's content
+ */
+sclfloat
+CSCLUI::get_custom_scale_rate_x()
+{
+    sclfloat ret = 1.0f;
+    if (m_impl) {
+        ret = m_impl->get_custom_scale_rate_x();
+    }
+    return ret;
+}
+
+/**
+ * Returns the current rate y value for resizing the keyboard's content
+ */
+sclfloat
+CSCLUI::get_custom_scale_rate_y()
+{
+    sclfloat ret = 1.0f;
+    if (m_impl) {
+        ret = m_impl->get_custom_scale_rate_y();
+    }
+    return ret;
+}
+
+/**
+ * Sets the custom rate value for resizing the keyboard's content
+ */
+void
+CSCLUI::set_custom_scale_rate(sclfloat x, sclfloat y)
+{
+    if (m_impl) {
+        m_impl->set_custom_scale_rate(x, y);
+    }
+}
+
+/**
+ * Sets the custom starting coordinates for drawing the keyboard's content
+ */
+void
+CSCLUI::set_custom_starting_coordinates(sclint x, sclint y)
+{
+    if (m_impl) {
+        m_impl->set_custom_starting_coordinates(x, y);
+    }
+}
+
+/**
+ * Sets the custom starting coordinates option for drawing the keyboard's content
+ */
+void
+CSCLUI::set_custom_starting_coordinates_option(SCLStartingCoordinatesOption option)
+{
+    if (m_impl) {
+        m_impl->set_custom_starting_coordinates_option(option);
+    }
+}
+
+/**
+ * Returns the scl main window size
+ */
+SclRectangle
+CSCLUI::get_main_window_rect()
+{
+    SclRectangle ret = {0, 0, 0, 0};
+
+    if (m_impl) {
+        ret = m_impl->get_main_window_rect();
+    }
+
+    return ret;
+}
+
+/**
+ * Returns the size of given input mode
+ */
+SclSize
+CSCLUI::get_input_mode_size(const sclchar *input_mode, SCLDisplayMode display_mode)
+{
+    SclSize ret = {0, 0};
+
+    if (m_impl) {
+        ret = m_impl->get_input_mode_size(input_mode, display_mode);
+    }
+
+    return ret;
+}
+
+/**
+* Returns the screen resolution
+*/
+void
+CSCLUI::get_screen_resolution(sclint *width, sclint *height)
+{
+    if (m_impl) {
+        m_impl->get_screen_resolution(width, height);
+    }
+}
+
+
+
+void
+CSCLUI::set_debug_mode(SCLDebugMode mode)
+{
+    if (m_impl) {
+        m_impl->set_debug_mode(mode);
+    }
+}
+
+SCLDebugMode
+CSCLUI::get_debug_mode()
+{
+    SCLDebugMode ret = DEBUGMODE_DISABLED;
+    if (m_impl) {
+        ret = m_impl->get_debug_mode();
+    }
+    return ret;
+}
+
+void
+CSCLUI::set_update_pending(sclboolean pend)
+{
+    if (m_impl) {
+        m_impl->set_update_pending(pend);
+    }
+}
+
+void
+CSCLUI::enable_button(const sclchar* custom_id, sclboolean enabled)
+{
+    if (m_impl) {
+        m_impl->enable_button(custom_id, enabled);
+    }
+}
+
+sclint
+CSCLUI::get_multi_touch_context_num()
+{
+    sclint ret = 0;
+    if (m_impl) {
+        ret = m_impl->get_multi_touch_context_num();
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUI::get_multi_touch_event(sclint seqorder, SclUIEventDesc *desc)
+{
+    sclboolean ret = FALSE;
+    if (m_impl) {
+        ret = m_impl->get_multi_touch_event(seqorder, desc);
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUI::set_longkey_duration(scllong msc)
+{
+    sclboolean ret = FALSE;
+    if (m_impl) {
+        ret = m_impl->set_longkey_duration(msc);
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUI::set_longkey_cancel_dist(sclshort dist)
+{
+    sclboolean ret = FALSE;
+    if (m_impl) {
+        ret = m_impl->set_longkey_cancel_dist(dist);
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUI::set_repeatkey_duration(scllong msc)
+{
+    sclboolean ret = FALSE;
+    if (m_impl) {
+        ret = m_impl->set_repeatkey_duration(msc);
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUI::set_autopopup_key_duration(scllong msc)
+{
+    sclboolean ret = FALSE;
+    if (m_impl) {
+        ret = m_impl->set_autopopup_key_duration(msc);
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUI::set_button_delay_duration(scllong msc)
+{
+    sclboolean ret = FALSE;
+    if (m_impl) {
+        ret = m_impl->set_button_delay_duration(msc);
+    }
+    return ret;
+}
+
+void
+CSCLUI::enable_magnifier(sclboolean enabled)
+{
+    if (m_impl) {
+        m_impl->enable_magnifier(enabled);
+    }
+}
+
+void
+CSCLUI::enable_sound(sclboolean enabled)
+{
+    if (m_impl) {
+        m_impl->enable_sound(enabled);
+    }
+}
+
+void
+CSCLUI::enable_vibration(sclboolean enabled)
+{
+    if (m_impl) {
+        m_impl->enable_vibration(enabled);
+    }
+}
+
+void
+CSCLUI::enable_tts(sclboolean enabled)
+{
+    if (m_impl) {
+        m_impl->enable_tts(enabled);
+    }
+}
+
+void
+CSCLUI::enable_shift_multi_touch(sclboolean enabled)
+{
+    if (m_impl) {
+        m_impl->enable_shift_multi_touch(enabled);
+    }
+}
+
+void
+CSCLUI::enable_highlight_ui(sclboolean enabled)
+{
+    if (m_impl) {
+        m_impl->enable_highlight_ui(enabled);
+    }
+}
+
+void
+CSCLUI::enable_highlight_ui_animation(sclboolean enabled)
+{
+    if (m_impl) {
+        m_impl->enable_highlight_ui_animation(enabled);
+    }
+}
+
+void
+CSCLUI::enable_touch_offset(sclboolean enabled)
+{
+    if (m_impl) {
+        m_impl->enable_touch_offset(enabled);
+    }
+}
+
+void
+CSCLUI::disable_input_events(sclboolean disabled)
+{
+    if (m_impl) {
+        m_impl->disable_input_events(disabled);
+    }
+}
+
+sclboolean
+CSCLUI::set_cur_sublayout(const sclchar *sub_layout_name)
+{
+    sclboolean ret = FALSE;
+    if (m_impl) {
+        ret = m_impl->set_cur_sublayout(sub_layout_name);
+    }
+    return ret;
+}
+
+const sclchar*
+CSCLUI::get_cur_sublayout()
+{
+    const sclchar* ret = NULL;
+    if (m_impl) {
+        ret = m_impl->get_cur_sublayout();
+    }
+    return ret;
+}
+
+void
+CSCLUI::set_custom_magnifier_label(scltouchdevice touch_id, sclint index, const sclchar* label)
+{
+    if (m_impl) {
+        m_impl->set_custom_magnifier_label(touch_id, index, label);
+    }
+}
+
+void
+CSCLUI::set_string_substitution(const sclchar *original, const sclchar *substitute)
+{
+    if (m_impl) {
+        m_impl->set_string_substitution(original, substitute);
+    }
+}
+
+void
+CSCLUI::unset_string_substitution(const sclchar *original)
+{
+    if (m_impl) {
+        m_impl->unset_string_substitution(original);
+    }
+}
+
+void
+CSCLUI::set_autocapital_shift_state(sclboolean flag) {
+    if (m_impl) {
+        m_impl->set_autocapital_shift_state(flag);
+    }
+}
+
+sclint
+CSCLUI::get_autocapital_shift_state() {
+    sclint flag = 0;
+
+    if (m_impl) {
+        flag = m_impl->get_autocapital_shift_state();
+    }
+
+    return flag;
+}
+
+sclboolean
+CSCLUI::process_key_event(const char *key)
+{
+    if (m_impl) {
+        return m_impl->process_key_event(key);
+    }
+    return FALSE;
+}
+
+sclboolean
+CSCLUI::get_button_geometry(const sclchar* custom_id, SclRectangle *rectangle)
+{
+    if (m_impl) {
+        return m_impl->get_button_geometry(custom_id, rectangle);
+    }
+    return FALSE;
+}
diff --git a/scl/sclui.h b/scl/sclui.h
new file mode 100644 (file)
index 0000000..484dab0
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_UI_H__
+#define __SCL_UI_H__
+
+#include "scltypes.h"
+#include "sclconfig.h"
+#include "sclstructs.h"
+#include "scleventcallback.h"
+#include "sclgraphicsbackendcallback.h"
+#include "sclwindowbackendcallback.h"
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+
+/* To use pimpl idiom */
+class CSCLUIImpl;
+
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class EXAPI CSCLUI
+{
+public:
+    CSCLUI();
+    virtual ~CSCLUI();
+
+    /*
+     * @brief This API initializes SCL library
+     * @param[in] main_window a pointer to main window object
+     * @param[in] parser_type decides which parser should be selected for parsing SCL UI resource file
+     * @param[in] entry_filepath a file path to SCL's UI resource entry file
+     * @return non-zero value is returned when successful
+     */
+    sclboolean init(sclwindow main_window, SCLParserType parser_type, const sclchar *entry_filepath);
+
+    /*
+     * @brief This API deinitializes SCL library
+     */
+    void fini();
+
+    /**
+     * @brief This API requests SCL library to show the S/W keyboard on the screen
+     * @param[in] auto_relocate Indicates whether the SCL library should relocate the keyboard window automatically
+     *            When set to FALSE, the developer should move the window to its expected position.
+     */
+    //void show(sclboolean auto_relocate = TRUE);
+    void show();
+
+    /**
+     * @brief This API requests SCL library to hide the S/W keyboard from the screen
+     */
+    void hide();
+
+
+    /**
+     * @brief This API registers a callback interface, to handle the events generated by SCL library
+     * @param[in] callback a pointer to ISCLEventCallback interface implementation class
+     * @param[in] input_mode when given not NULL, this callback processes event on that input_mode only.
+     */
+    void set_ui_event_callback(ISCLUIEventCallback *callback, const sclchar *input_mode = NULL);
+
+    /**
+     * @brief This API requests SCL library to rotate the window to given degree
+     * @param[in] degree an SCLRotation value for rotating the keyboard
+     * @return non-zero value is returned when successful
+     */
+    sclboolean set_rotation(SCLRotation degree);
+
+    /**
+     * @brief This API returns the current rotation degree
+     * @return current rotation value
+     */
+    SCLRotation get_rotation();
+
+    /**
+     * @brief This API checks if the current display mode is portrait or landscape
+     * @return current display mode
+     */
+    SCLDisplayMode get_display_mode();
+
+    /**
+     * @brief This API request SCL library to change to given input mode
+     * @param[in] input_mode the name of the desired input mode
+     * @return non-zero value is returned when successful
+     */
+    sclboolean set_input_mode(const sclchar *input_mode);
+
+    /**
+     * @brief This API retrieves the current input mode
+     * @return a string pointer that indicates the name of current input mode
+     */
+    const sclchar* get_input_mode();
+
+    /**
+     * @brief This API request SCL library to change the given popup window's input mode
+     * @param[in] window the handle for the popup window that we want to change the input mode
+     * @param[in] input_mode the name of the desired input mode
+     * @return non-zero value is returned when successful
+     */
+    sclboolean set_popup_input_mode(sclwindow window, const sclchar *input_mode);
+
+    /**
+     * @brief This API retrieves the current input mode
+     * @param[in] window the handle for the popup window that we want to retrieve the input mode
+     * @return a string pointer that indicates the name of current input mode
+     */
+    const sclchar* get_popup_input_mode(sclwindow window);
+
+    /**
+     * @brief This API request SCL library to suspend screen updates
+     * @param[in] pend whether to suspend screen updates
+     */
+    void set_update_pending(sclboolean pend);
+
+    /**
+     * @brief This API request SCL library to change a specific key with user customized values, with different parameters
+     * @param[in] custom_id the name of the key to be reset
+     * @param[in] label the string to be displayed on the button
+     * @param[in] label the file path to button's label image
+     * @param[in] imagebg the file path to button's background image
+     * @param[in] key_event a numeric value to be emitted when this button is clicked
+     * @param[in] key_value a string value to be emitted when this button is clicked
+     * @param[in] redraw whether to redraw the key right after updating detailed information
+     * @return internal private key index
+     */
+    sclint set_private_key(const sclchar* custom_id, sclchar* label, sclchar* imagelabel[SCL_BUTTON_STATE_MAX], sclchar* imagebg[SCL_BUTTON_STATE_MAX], sclulong key_event, sclchar *key_value, sclboolean redraw);
+
+    /**
+     * @brief This API request SCL library to reset a key to its original configuration
+     * @param[in] custom_id the name of the key to be reset
+     */
+    void unset_private_key(const sclchar* custom_id);
+
+    /**
+     * @brief This API request SCL library to enable a button with given ID
+     * @param[in] custom_id the name of the key to be enabled
+     * @param[in] enabled whether this button should be enabled or not
+     */
+    void enable_button(const sclchar* custom_id, sclboolean enabled);
+
+    /**
+     * @brief This API sets the name of the current theme to change the look and feel of S/W keyboard
+     * @param[in] themename the name of the theme to be applied
+     * @return non-zero value is returned when successful
+     */
+    sclboolean set_cur_themename(const sclchar *themename);
+
+    /**
+     * @brief This API sets the name of the desired predefined sub-layout, which changes only some part of current layout
+     * @param[in] themename the name of the theme to be applied
+     * @return non-zero value is returned when successful
+     */
+    sclboolean set_cur_sublayout(const sclchar *sub_layout_name);
+
+    /**
+     * @brief This API retrieves the name of current selected sub-layout
+     * @return the string pointer that indicates the name of current sub-layout
+     */
+    const sclchar* get_cur_sublayout();
+
+    /**
+     * @brief This API sets the current shift state
+     * @param[in] state the SCLShiftState value for desired shift state
+     */
+    void set_shift_state(SCLShiftState state);
+
+    /**
+     * @brief This API retrieves the current shift state
+     * @return current shift state
+     */
+    SCLShiftState get_shift_state();
+
+    /**
+     * @brief This API sets the current caps lock mode, which reverses the effect of shift mode
+     * @param[in] mode whether the cap lock mode is enabled or not
+     */
+    void set_caps_lock_mode(sclboolean mode);
+
+    /**
+     * @brief This API retrieves the current caps lock mode
+     * @return current caps lock mode
+     */
+    sclboolean get_caps_lock_mode();
+
+    /**
+     * @brief This API notifies the SCL library that the application's focus was moved to another input context
+     */
+    void notify_app_focus_changed();
+
+    /**
+     * @brief This API request SCL library to reset the timer, which closes all popup windows when expired
+     */
+    void reset_popup_timeout();
+
+    /**
+     * @brief This API request SCL library to close all opened popup windows
+     */
+    void close_all_popups();
+
+    /*
+     * @brief This API acquires the size of main window
+     * @param[out] rect the geometry information of main window
+     */
+    SclRectangle get_main_window_rect();
+
+    /**
+     * @brief This API retrieves the current input mode
+     * @param[in] input_mode the name of the desired input mode
+     * @param[in] display_mode desired display mode value
+     * @return a size struct contains the input_mode's size in given display_mode
+     */
+    SclSize get_input_mode_size(const sclchar *input_mode, SCLDisplayMode display_mode);
+
+    /**
+     * @brief This API acquires the screen size of current device
+     * @param[out] width the x-axis size of screen
+     * @param[out] height the y-axis size of screen
+     */
+    void get_screen_resolution(sclint *width, sclint *height);
+
+    /**
+     * @brief This API request SCL library to scale the input value,
+              by calculating the rate of target screen size and current screen size
+     * @param[in] x the value that needs to be scaled
+     * @return scaled value
+     */
+    scl16 get_scaled_x(scl16 x);
+
+    /**
+     * @brief This API request SCL library to scale the input value,
+              by calculating the rate of target screen size and current screen size
+     * @param[in] y the value that needs to be scaled
+     * @return scaled value
+     */
+    scl16 get_scaled_y(scl16 y);
+
+    /**
+     * @brief This API returns the smaller scale rate, between x and y
+     * @return scale rate
+     */
+    sclfloat get_scale_rate();
+
+    /**
+     * @brief This API retrieves the current custom scale rate x, for resizing the keyboard's content
+     * @return current custom x scale value
+     */
+    sclfloat get_custom_scale_rate_x();
+
+    /**
+     * @brief This API retrieves the current custom scale rate y, for resizing the keyboard's content
+     * @return current custom y scale value
+     */
+    sclfloat get_custom_scale_rate_y();
+
+    /**
+     * @brief This API sets the current custom scale rate values, for resizing the keyboard's content
+     * @param[in] x the scale rate value
+     */
+    void set_custom_scale_rate(sclfloat x, sclfloat y);
+
+    /**
+     * @brief This API sets the starting coordinates for drawing keyboard's contents
+     * @param[in] x the starting coordinate x
+     * @param[in] y the starting coordinate y
+     */
+    void set_custom_starting_coordinates(sclint x, sclint y);
+
+    /**
+     * @brief This API sets the option for the starting coordinates feature
+     * @param[in] option the starting coordinate option
+     */
+    void set_custom_starting_coordinates_option(SCLStartingCoordinatesOption option);
+
+    /**
+     * @brief This API returns the number of current multi touch contexts,
+     *        which means how many fingers are currently pressing the touch device
+     * @return number of touch contexts
+     */
+    sclint get_multi_touch_context_num();
+
+    /**
+     * @brief This API retrieves the descriptor for the nth multi touch context, for processing multi touch events
+     * @param[in] seqorder the sequence order of currently requesting multi touch context
+     * @param[out] desc a pointer to SclKeyEventDesc struct, to be filled with given multi touch context's detailed information
+     * @return non-zero value is returned when successful
+     */
+    sclboolean get_multi_touch_event(sclint seqorder, SclUIEventDesc *desc);
+
+    /**
+     * @brief This API requests SCL library to start working in debug mode
+     */
+    void set_debug_mode(SCLDebugMode mode);
+
+    /**
+     * @brief This API retrieves the current debug mode of SCL library
+     */
+    SCLDebugMode get_debug_mode();
+
+    /**
+     * @brief This API sets the timeout value for recognizing long press event
+     * @param[in] msc the time before the system waits until it determines the press event is long press event
+     * @return non-zero value is returned when successful
+     */
+    sclboolean set_longkey_duration(scllong msc);
+
+    /**
+     * @brief This API sets the threshold value for recognizing long press event
+     * @param[in] dist maximum distance, in pixels.
+                  the move event should not go beyond this distance from its initial pressed point
+     * @return non-zero value is returned when successful
+     */
+    sclboolean set_longkey_cancel_dist(sclshort dist);
+
+    /**
+     * @brief This API sets the timeout value for emitting repeat key event
+     * @param[in] msc the time that SCL library has to wait before emitting next repeat key even
+     * @return non-zero value is returned when successful
+     */
+    sclboolean set_repeatkey_duration(scllong msc);
+
+    /**
+     * @brief This API sets the timeout value for recognizing long press event, if current button supports hidden text popup
+     * @param[in] msc the time before the system waits until it determines the press event is long press event
+     * @return non-zero value is returned when successful
+     */
+    sclboolean set_autopopup_key_duration(scllong msc);
+
+    /**
+     * @brief This API sets the timeout value before it reverts the ui feedback of button press event
+     * @param[in] msc the time before the system waits until it resets the pressed key to its normal state
+     * @return non-zero value is returned when successful
+     */
+    sclboolean set_button_delay_duration(scllong msc);
+
+    /**
+     * @brief This API requests SCL library to enable/disable magnifier window
+     * @param[in] enabled indicates whether mangifier window should be displayed or not
+     */
+    void enable_magnifier(sclboolean enabled);
+
+    /**
+     * @brief This API requests SCL library to enable/disable sound feedback
+     * @param[in] enabled indicates whether sound feedback should be played or not, when a key is pressed
+     */
+    void enable_sound(sclboolean enabled);
+
+    /**
+     * @brief This API requests SCL library to enable/disable vibration feedback
+     * @param[in] enabled indicates whether vibration feedback should be played or not, when a key is pressed
+     */
+    void enable_vibration(sclboolean enabled);
+
+    /**
+     * @brief This API requests SCL library to enable/disable tts feedback
+     * @param[in] enabled indicates whether tts feedback should be played or not, when a key is pressed
+     */
+    void enable_tts(sclboolean enabled);
+
+    /**
+     * @brief This API requests SCL library to enable/disable shift multi touch action
+     * @param[in] enabled indicates whether shift button should provide multi touch action
+     */
+    void enable_shift_multi_touch(sclboolean enabled);
+
+    /**
+     * @brief This API requests SCL library to enable/disable highlight ui
+     * @param[in] enabled indicates whether to show highlight ui
+     */
+    void enable_highlight_ui(sclboolean enabled);
+
+    /**
+     * @brief This API requests SCL library to enable/disable animation effect for highlight ui
+     * @param[in] enabled indicates whether to display animation effect when moving highlight ui
+     */
+    void enable_highlight_ui_animation(sclboolean enabled);
+
+    /**
+     * @brief This API requests SCL library to apply the touch offset adjustment
+     * @param[in] enabled indicates whether the touch offset adjustment should applied or not
+     */
+    void enable_touch_offset(sclboolean enabled);
+
+    /**
+     * @brief This API requests SCL library to ignore any events raised from the keyboard window
+     * @param[in] enabled indicates whether the keyboard window should ignore any touch events it receives
+     */
+    void disable_input_events(sclboolean disabled);
+
+    /**
+     * @brief This API requests SCL library to change the content of magnifier window that will be displayed
+     * @param[in] touch_id indicates which multi touch context this customization should be applied to
+     * @param[in] index indicates the index of magnifier window's label
+     * @param[in] label the string to be displayed on the magnifier window
+     */
+    void set_custom_magnifier_label(scltouchdevice touch_id, sclint index, const sclchar* label);
+
+    /**
+     * @brief This API requests SCL library to substitute a string with given one when displaying it
+     * @param[in] original indicates the string that should be substituted from
+     * @param[in] substitute indicates the string that should be substituted to
+     */
+    void set_string_substitution(const sclchar *original, const sclchar *substitute);
+
+    /**
+     * @brief This API requests SCL library to reset substitution for the given string
+     * @param[in] original indicates the string that was registered to be substituted from
+     */
+    void unset_string_substitution(const sclchar *original);
+
+    /**
+     * @brief This API sets the autocapital shift state flag
+     * @param[in] flag: TRUE indicates the libscl-ui will auto handle the shift state
+     *                  FALSE not, then the users will handle this outside the libscl-ui
+     * default is TRUE
+     */
+    void set_autocapital_shift_state(sclboolean flag);
+
+    /**
+     * @brief This API gets the autocapital shift state flag
+     */
+    sclint get_autocapital_shift_state();
+
+    /**
+     * @brief This API process the key event received from ISF
+     */
+    sclboolean process_key_event(const char *key);
+
+    /**
+     * @brief This API request SCL library to return the geometry information of a button with given ID
+     * @param[in] custom_id the name of the key to be queried
+     * @return non-zero value is returned when successful
+     */
+    sclboolean get_button_geometry(const sclchar* custom_id, SclRectangle *rectangle);
+
+    void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data);
+
+    void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data);
+private:
+    CSCLUIImpl *m_impl;
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_UI_H__
diff --git a/scl/scluibuilder.cpp b/scl/scluibuilder.cpp
new file mode 100644 (file)
index 0000000..a71528b
--- /dev/null
@@ -0,0 +1,1333 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "scluibuilder.h"
+#include "scldebug.h"
+#include "sclresourcecache.h"
+#include "sclcontext.h"
+#include "sclimageproxy.h"
+#include "sclactionstate.h"
+#include "sclkeyfocushandler.h"
+#include "sclanimator.h"
+
+//#include "sclresource.h"
+#include <assert.h>
+#include "sclres_manager.h"
+
+using namespace scl;
+
+//extern sclboolean g_key_spacing_off;
+
+CSCLUIBuilder::CSCLUIBuilder()
+{
+    SCL_DEBUG();
+
+    m_gwes = NULL;
+    m_utils = NULL;
+}
+
+CSCLUIBuilder::~CSCLUIBuilder()
+{
+    SCL_DEBUG();
+    m_gwes = NULL;
+    m_utils = NULL;
+}
+
+CSCLUIBuilder*
+CSCLUIBuilder::get_instance()
+{
+    static CSCLUIBuilder instance;
+    return &instance;
+}
+
+void
+CSCLUIBuilder::init(sclwindow parent)
+{
+    SCL_DEBUG();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    m_gwes = CSCLGwes::get_instance();
+    m_utils = CSCLUtils::get_instance();
+    /* It will create the base window */
+
+    scl8 mode = NOT_USED;
+    sclint layout = NOT_USED;
+    SCLDisplayMode display_mode = DISPLAYMODE_PORTRAIT;
+
+    PSclDefaultConfigure default_configure = NULL;
+    PSclMagnifierWndConfigure magnifier_configure = NULL;
+    if (m_gwes && m_utils && sclres_manager) {
+        PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+        PSclLayout sclres_layout = sclres_manager->get_layout_table();
+
+        assert(sclres_input_mode_configure != NULL);
+        assert(sclres_layout != NULL);
+
+        default_configure = sclres_manager->get_default_configure();
+        magnifier_configure = sclres_manager->get_magnifier_configure();
+        if (default_configure) {
+            display_mode = default_configure->display_mode;
+            mode = sclres_manager->get_inputmode_id(default_configure->input_mode);
+        }
+        /* Make sure these variables does not exceed the size of our array */
+        if (!scl_check_arrindex(mode, MAX_SCL_INPUT_MODE) ||
+            !scl_check_arrindex(mode, sclres_manager->get_inputmode_size())) {
+            mode = 0;
+        }
+        if (!scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+            display_mode = DISPLAYMODE_PORTRAIT;
+        }
+
+        layout = sclres_manager->get_layout_id(sclres_input_mode_configure[mode].layouts[display_mode]);
+        if (layout < 0 || !scl_check_arrindex_unsigned(layout, MAX_SCL_LAYOUT) ||
+            !scl_check_arrindex_unsigned(layout, sclres_manager->get_layout_size())) {
+            layout = 0;
+        }
+
+        if (m_utils) {
+            m_gwes->init(parent,
+                        m_utils->get_scaled_x(sclres_layout[layout].width),
+                        m_utils->get_scaled_y(sclres_layout[layout].height));
+        }
+
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            context->set_display_mode(display_mode);
+            context->set_input_mode(mode);
+            context->set_base_layout(sclres_manager->get_layout_id(sclres_input_mode_configure[mode].layouts[display_mode]));
+        }
+
+        sclwindow window = SCLWINDOW_INVALID;
+        if (m_gwes->m_windows)
+            window = m_gwes->m_windows->get_base_window();
+
+        /* Creates the magnifier window */
+        if (default_configure && magnifier_configure) {
+            if (default_configure->use_magnifier_window) {
+                if (m_gwes->m_windows && m_gwes->m_events) {
+                    sclwindow magnifier_window = m_gwes->m_windows->create_magnifier_window(parent, 0, 0,
+                        magnifier_configure->width, magnifier_configure->height);
+                    m_gwes->m_events->connect_window_events(magnifier_window, SCL_EVENT_EXPOSE | SCL_EVENT_MOUSE);
+                }
+            }
+        }
+
+        /* Creates the dim window */
+        /* FIXME */
+        //if (scl_check_arrindex(defaultLayoutIdx, MAX_LAYOUT)) {
+        if (m_gwes->m_windows)
+            m_gwes->m_windows->create_dim_window(window, NULL, sclres_layout[layout].width, sclres_layout[layout].height);
+
+        /* m_gwes->m_events->set_touch_event_offset(scl_default_configure.touch_offset);*/
+        /*Moved to Show Layout*/
+
+        /* For testing pre-image load */
+        /*CSCLImageProxy *proxy = CSCLImageProxy::get_instance();
+        sclchar composed_path[_POSIX_PATH_MAX] = {0,};
+        for (sclint loop = 0; loop < MAX_PRELOAD_IMG_CNT; loop++) {
+            memset(composed_path, 0x00, sizeof(sclchar)*_POSIX_PATH_MAX);
+            m_utils->get_composed_path(composed_path, scl_preload_image[loop]);
+            proxy->get_image(composed_path);
+        }*/
+    }
+}
+
+/**
+ * Shows the current layout and contexts
+ * This function will be called by expose event and invalidate rect
+ */
+sclboolean
+CSCLUIBuilder::show_layout(const sclwindow window, const scl16 x, const scl16 y, const scl16 width, const scl16 height)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLGraphics *graphics = CSCLGraphics::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    PSclDefaultConfigure default_configure = NULL;
+    if (sclres_manager) {
+        default_configure = sclres_manager->get_default_configure();
+    }
+    if (events && windows && graphics && cache && context && focus_handler && default_configure) {
+    /* FIXME : The draw_ctx should be acquired from the base window also, if the target window is virtual
+       However, for ease of development, leave the drawctx to be acquired from the target window for now
+       Should modify the EFLObject list management routine after fixing the issue described above
+    */
+        scldrawctx draw_ctx = graphics->begin_paint(window);
+        SCLDisplayMode display_mode =  context->get_display_mode();
+        events->set_touch_event_offset(default_configure->touch_offset[display_mode]);
+
+        if (window == windows->get_magnifier_window()) {
+            /* For the magnifier window */
+            ret = show_magnifier(window, draw_ctx);
+        } else if (window == windows->get_dim_window()) {
+            SclWindowContext *dim_window_context = windows->get_window_context(window);
+            if (dim_window_context) {
+                SclSize size;
+                SclColor color;
+                size.width = dim_window_context->geometry.width;
+                size.height = dim_window_context->geometry.height;
+                color = default_configure->dim_color;
+                draw_window_bg_by_sw(window, draw_ctx, size, 0.0, color, color);
+                /*sclchar composed_path[_POSIX_PATH_MAX] = {0,};
+                const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
+                m_utils->get_composed_path(composed_path, layout->image_path[BUTTON_STATE_NORMAL]);
+                graphics->draw_image(window, draw_ctx, composed_path, 0, 0, layout->width, layout->height);*/
+            }
+        } else {
+            /* For the base and popup window */
+            const SclLayout* layout = cache->get_cur_layout(window);
+            // FIXME implement later
+            // SclLayoutInfoCache *info_cache = cache->get_cur_layout_info_cache(window);
+            if (layout) {
+                //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+                SclWindowContext *window_context = windows->get_window_context(window);
+                scl_assert_return_false(layout);
+
+                if (layout->use_sw_background) {
+                    if (window_context) {
+                        SclSize size;
+                        size.width = window_context->geometry.width;
+                        size.height = window_context->geometry.height;
+                        draw_window_bg_by_sw(window, draw_ctx, size, layout->bg_line_width, layout->bg_line_color, layout->bg_color);
+                    }
+                } else if (layout->image_path[BUTTON_STATE_NORMAL]) {
+                    sclint targetx = 0;
+                    sclint targety = 0;
+                    /* If the target window is virtual window, let's draw it on the base window */
+                    sclwindow targetwin = window;
+                    if (window_context) {
+                        if (window_context->is_virtual) {
+                            /*SclWindowContext *base_window_context =
+                                windows->get_window_context(windows->get_base_window(), FALSE);*/
+                            SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                            if (base_window_context) {
+                                targetwin = windows->get_base_window();
+                                targetx = window_context->geometry.x - base_window_context->geometry.x;
+                                targety = window_context->geometry.y - base_window_context->geometry.y;
+                            }
+                        }
+                        /* Apply custom starting coordinates only to the base window, and if the option is ALL */
+                        if (windows->is_base_window(window) &&
+                            cache->get_custom_starting_coordinates_option() == SCL_STARTING_COORDINATES_OPTION_ALL) {
+                            targetx += cache->get_custom_starting_coordinates().x;
+                            targety += cache->get_custom_starting_coordinates().y;
+                        }
+                        if (strlen(layout->image_path[BUTTON_STATE_NORMAL]) > 0) {
+                            /*SclImageCachedInfo cached_info = {0, };
+                            cached_info.nine_patch_left = info_cache->bg_image_path[BUTTON_STATE_NORMAL].left;
+                            cached_info.nine_patch_right = info_cache->bg_image_path[BUTTON_STATE_NORMAL].right;
+                            cached_info.nine_patch_top = info_cache->bg_image_path[BUTTON_STATE_NORMAL].top;
+                            cached_info.nine_patch_bottom = info_cache->bg_image_path[BUTTON_STATE_NORMAL].bottom;*/
+
+                            sclchar composed_path[_POSIX_PATH_MAX] = {0, };
+                            m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, layout->image_path[BUTTON_STATE_NORMAL]);
+                            // Temporary testing for EFL backend.. Otherwise the background image covers other buttons
+                            if (window_context && (x + y + width + height == 0)) {
+                                //graphics->draw_image(targetwin, draw_ctx, composed_path, &cached_info, targetx, targety, layout->width, layout->height, window_context->layout_image_offset.x, winctx->layout_image_offset.y, -1, -1, layout->extract_background);
+                                graphics->draw_image(targetwin, draw_ctx, composed_path, NULL,
+                                    targetx, targety, layout->width, layout->height,
+                                    window_context->layout_image_offset.x, window_context->layout_image_offset.y,
+                                    -1, -1, layout->extract_background);
+                            }
+                        }
+                    }
+                }
+                draw_button_all(window, draw_ctx, x, y, width, height);
+
+                //if (highlight_ui_enabled)
+                if (focus_handler->get_current_focus_window() == window) {
+                    sclint startx = 0;
+                    sclint starty = 0;
+
+                    SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                    if (window_context && base_window_context) {
+                        if (window_context->is_virtual) {
+                            startx += (window_context->geometry.x - base_window_context->geometry.x);
+                            starty += (window_context->geometry.y - base_window_context->geometry.y);
+                        }
+                    }
+
+                    sclboolean draw_highlight_ui = TRUE;
+                    SclAnimationState *state = NULL;
+                    CSCLAnimator *animator = CSCLAnimator::get_instance();
+                    if (animator) {
+                        sclint id = animator->find_animator_by_type(ANIMATION_TYPE_HIGHLIGHT_UI);
+                        state = animator->get_animation_state(id);
+                    }
+                    if (state) {
+                        // If currently the highlight UI is being animated, don't draw it here
+                        if (state->active) {
+                            draw_highlight_ui = FALSE;
+                        }
+                    }
+
+                    if (draw_highlight_ui && context->get_highlight_ui_enabled()) {
+                        sclchar composed_path[_POSIX_PATH_MAX] = {0, };
+                        const SclLayoutKeyCoordinate *coordinate = NULL;
+                        scl8 current_key_index = focus_handler->get_current_focus_key();
+                        coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
+                        /* FIXME : Need to use highlight image */
+                        m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, SCL_HIGHLIGHT_UI_IMAGE);
+                        if (coordinate) {
+                            // Draw highlight
+                            graphics->draw_image(window, draw_ctx, composed_path, NULL,
+                                startx + coordinate->x, starty + coordinate->y, coordinate->width, coordinate->height);
+                        }
+                    }
+                }
+            }
+        }
+        graphics->end_paint(window, draw_ctx);
+    }
+
+    return ret;
+}
+
+/**
+ * Draws all of buttons
+ */
+sclboolean
+CSCLUIBuilder::draw_button_all(const sclwindow window, const scldrawctx draw_ctx, const scl16 x /* = 0 */, const scl16 y /* = 0 */, const scl16 width /* = 0 */, const scl16 height /* = 0 */)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(window);
+
+    sclboolean drawall = FALSE;
+    SclRectangle updatearea = {x, y, width, height};
+    if (x + y + width + height == 0) {
+        drawall = TRUE;
+    }
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    SclLayoutKeyCoordinate* coordinate = NULL;
+    SclButtonContext* button_context = NULL;
+
+    if (context && cache && utils) {
+        for (sclint idx = 0; idx < MAX_KEY; idx++) {
+            coordinate = cache->get_cur_layout_key_coordinate(window, idx);
+            button_context = cache->get_cur_button_context(window, idx);
+            if (coordinate && button_context) {
+                /* First check if this button is enabled in current active sublayout */
+                sclboolean subLayoutMatch = TRUE;
+                if (coordinate->sub_layout && context->get_cur_sublayout()) {
+                    if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+                        subLayoutMatch = FALSE;
+                    }
+                }
+                if (coordinate->valid && subLayoutMatch) {
+                    SclRectangle itemrect = {coordinate->x, coordinate->y, coordinate->width, coordinate->height};
+                    if (drawall || utils->is_rect_overlap(itemrect, updatearea)) {
+                        SCLButtonState state = button_context->state;
+                        if (button_context->toggled) {
+                            state = BUTTON_STATE_TOGGLED;
+                        }
+                        if (!draw_button(window, draw_ctx, idx, state)) {
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return TRUE;
+}
+
+/**
+ * Returns text that should be read if accessibility support is enabled
+ */
+const sclchar*
+CSCLUIBuilder::get_button_text_to_read(const sclwindow window, const scl16 key_index, SCLShiftState shift_index)
+{
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    if (!cache)
+        return NULL;
+
+    const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+    SclButtonContext * button_context = cache->get_cur_button_context(window, key_index);
+
+    if (coordinate && button_context && coordinate->key_type != KEY_TYPE_NONE) {
+        const sclchar *targetstr = coordinate->hint_string[shift_index][button_context->multitap_index];
+        if (targetstr == NULL) {
+            targetstr = coordinate->label[shift_index][0];
+        }
+        if (targetstr == NULL) {
+            targetstr = coordinate->key_value[shift_index][button_context->multitap_index];
+        }
+
+        return cache->find_substituted_string(targetstr);
+    }
+    return NULL;
+}
+
+
+/**
+ * Draws the button of the given key index by type of the button
+ * @remark draw_button_all
+ */
+sclboolean
+CSCLUIBuilder::draw_button(const sclwindow window, scldrawctx draw_ctx, const scl16 key_index, const SCLButtonState state, const sclboolean force_draw_bg /* = FALSE */)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(window);
+    scl_assert_return_false(key_index > NOT_USED && key_index < MAX_KEY);
+    scl_assert_return_false(state >= BUTTON_STATE_NORMAL && state < SCL_BUTTON_STATE_MAX);
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLGraphics *graphics = CSCLGraphics::get_instance();
+
+    if (cache && context && graphics) {
+        SclButtonContext* button_context = cache->get_cur_button_context(window, key_index);
+
+        if (button_context) {
+            if (!button_context->used) {
+                return FALSE;
+            }
+
+            /* creates a cairo surface if the value of the given draw_ctx is NULL */
+            sclboolean need_endpaint = FALSE;
+            if (draw_ctx == NULL) {
+                draw_ctx = graphics->begin_paint(window);
+                need_endpaint = TRUE;
+            }
+
+            /* FIXME : There is a case that begin_pain fails. Inspection on the root cause is needed */
+            if (draw_ctx) {
+                SCLShiftState shift_index = context->get_shift_state();
+                if (shift_index >= SCL_SHIFT_STATE_MAX) shift_index = SCL_SHIFT_STATE_OFF;
+
+                const SclLayout* layout = cache->get_cur_layout(window);
+                const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+
+                /* 1. drawing the background of the button */
+                /* check it according to the following check-list */
+                /* check it whether uses SW style button */
+                if (layout && coordinate) {
+                    scldrawing background = NULL;
+                    if (layout->use_sw_button) {
+                        /* case 1 (uses Software button) */
+                        background = draw_button_bg_by_sw(window, draw_ctx, key_index, state);
+                    } else {
+                        /* check it whether uses an individual images */
+                        if (coordinate->bg_image_path[shift_index][state]) {
+                            if (strcmp(coordinate->bg_image_path[shift_index][state], SCL_BACKGROUND_IMAGE_STRING) != 0) {
+                                /* case 2 (uses an individual image) */
+                                background = draw_button_bg_by_img(window, draw_ctx, key_index, state, shift_index);
+                            } else {
+                                /* case 3 (uses the layout background image) */
+                                background = draw_button_bg_by_layoutimg(window, draw_ctx, key_index, state, shift_index);
+                            }
+                        } else if (force_draw_bg) {
+                            background = draw_button_bg_by_layoutimg(window, draw_ctx, key_index, state, shift_index);
+                        }
+                        /* case 4 (don't draw anything for button's background if image_path is NULL) */
+                    }
+
+                    /* 2. displaying the label of the button */
+                    draw_button_label(window, draw_ctx, key_index, state, shift_index);
+                    /* 3. register button as atspi object */
+                    const sclchar * text = get_button_text_to_read(window, key_index, shift_index);
+                    graphics->register_atspi_object(window, background, text);
+                }
+            }
+
+            /* destroys the cairo surface if the value of the given(parameter) draw_ctx is NULL */
+            if (need_endpaint) {
+                graphics->end_paint(window, draw_ctx);
+            }
+        } else {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+/**
+ * Draws labels for the target button
+ * @remark draw_button
+ */
+sclboolean
+CSCLUIBuilder::draw_button_label(const sclwindow window, const scldrawctx draw_ctx, const scl16 key_index, SCLButtonState state, SCLShiftState shift)
+{
+    SCL_DEBUG();
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLGraphics *graphics = CSCLGraphics::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    const SclLayoutKeyCoordinate* coordinate = NULL;
+
+    if (!utils || !windows || !graphics || !cache) return FALSE;
+
+    coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+    if (coordinate) {
+        scl_assert_return_false(window);
+        scl_assert_return_false(draw_ctx);
+        scl_assert_return_false(coordinate);
+
+        /* If the target window is virtual window, let's draw it on the base window */
+        sclint targetaddx = 0;
+        sclint targetaddy = 0;
+        sclwindow targetwin = window;
+        //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+        SclWindowContext *window_context = windows->get_window_context(window);
+        if (window_context) {
+            if (window_context->is_virtual) {
+                //SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window(), FALSE);
+                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                if (base_window_context) {
+                    targetwin = windows->get_base_window();
+                    targetaddx = window_context->geometry.x - base_window_context->geometry.x;
+                    targetaddy = window_context->geometry.y - base_window_context->geometry.y;
+                }
+            }
+        }
+
+        /* for image label  */
+        if (coordinate->image_label_path[shift][state]) {
+            if (strlen(coordinate->image_label_path[shift][state]) > 0) {
+                sclchar composed_path[_POSIX_PATH_MAX] = {0, };
+                m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, coordinate->image_label_path[shift][state]);
+
+                SclSize imgSize = m_gwes->m_graphics->get_image_size(composed_path);
+                if (imgSize.width == 0 && imgSize.height == 0) {
+                    imgSize.width = coordinate->width;
+                    imgSize.height = coordinate->height;
+                }
+                imgSize.width *= m_utils->get_smallest_scale_rate() * m_utils->get_smallest_custom_scale_rate();
+                imgSize.height *= m_utils->get_smallest_scale_rate() * m_utils->get_smallest_custom_scale_rate();
+
+                /* Make sure the image label is not bigger than the given coordinate */
+                if (imgSize.width > coordinate->width) {
+                    imgSize.width = coordinate->width;
+                }
+                if (imgSize.height > coordinate->height) {
+                    imgSize.height = coordinate->height;
+                }
+
+                SclPoint pos = {0, 0};
+                const SclLabelProperties *labelproperties = cache->get_label_properties(coordinate->image_label_type, 0);
+                if (labelproperties) {
+                    SCLLabelAlignment align = labelproperties->alignment;
+                    sclshort padding_x = labelproperties->padding_x * utils->get_custom_scale_rate_x();
+                    sclshort padding_y = labelproperties->padding_y * utils->get_custom_scale_rate_y();
+                    if (align == LABEL_ALIGN_LEFT_MIDDLE ||
+                        align == LABEL_ALIGN_CENTER_MIDDLE ||
+                        align == LABEL_ALIGN_RIGHT_MIDDLE) {
+                            pos.y = coordinate->y + ((coordinate->height - imgSize.height) / 2) + padding_y;
+                    } else if (align == LABEL_ALIGN_LEFT_BOTTOM ||
+                        align == LABEL_ALIGN_CENTER_BOTTOM ||
+                        align == LABEL_ALIGN_RIGHT_BOTTOM) {
+                            pos.y = coordinate->y + (coordinate->height - imgSize.height) - padding_y;
+                    } else {
+                        pos.y = coordinate->y + padding_y;
+                    }
+                    if (align == LABEL_ALIGN_CENTER_TOP ||
+                        align == LABEL_ALIGN_CENTER_MIDDLE ||
+                        align == LABEL_ALIGN_CENTER_BOTTOM) {
+                            pos.x = coordinate->x + ((coordinate->width - imgSize.width) / 2) + padding_x;
+                    } else if (align == LABEL_ALIGN_RIGHT_TOP ||
+                        align == LABEL_ALIGN_RIGHT_MIDDLE ||
+                        align == LABEL_ALIGN_RIGHT_BOTTOM) {
+                            pos.x = coordinate->x + (coordinate->width - imgSize.width) - padding_x;
+                    } else {
+                        pos.x = coordinate->x + padding_x;
+                    }
+                } else {
+                    pos.x = coordinate->x + ((coordinate->width - imgSize.width) / 2);
+                    pos.y = coordinate->y + ((coordinate->height - imgSize.height) / 2);
+                }
+
+                /*
+                graphics->draw_image(
+                    targetwin,
+                    draw_ctx,
+                    composed_path,
+                    pos.x + targetaddx,
+                    pos.y + targetaddy,
+                    imgSize.width,
+                    imgSize.height
+                );*/
+                graphics->draw_image(
+                    targetwin,
+                    draw_ctx,
+                    composed_path,
+                    NULL,
+                    pos.x + targetaddx,
+                    pos.y + targetaddy,
+                    imgSize.width,
+                    imgSize.height);
+            }
+        }
+
+        /* for text */
+        for (int idx = 0; idx < coordinate->label_count; idx++) {
+            SclFontInfo info;
+            const SclLabelProperties *labelproperties = cache->get_label_properties(coordinate->label_type, idx);
+            if (labelproperties) {
+                const sclchar *label = coordinate->label[shift][idx];
+                label = cache->find_substituted_string(label);
+
+                /* If the button type is BUTTON_TYPE_ROTATION, display current keyvalue */
+                if (idx == 0) {
+                    if (coordinate->button_type == BUTTON_TYPE_ROTATION) {
+                        SclButtonContext* button_context = cache->get_cur_button_context(window, key_index);
+                        if (button_context) {
+                            if (button_context->multitap_index < MAX_SIZE_OF_MULTITAP_CHAR) {
+                                label = coordinate->key_value[shift][button_context->multitap_index];
+                            }
+                        }
+                    }
+                }
+                if (labelproperties->font_name) {
+                    strncpy(info.font_name, labelproperties->font_name, MAX_FONT_NAME_LEN - 1);
+                    info.font_name[MAX_FONT_NAME_LEN - 1] = '\0';
+                    info.font_size = labelproperties->font_size * utils->get_smallest_custom_scale_rate();
+                    info.is_bold = info.is_italic = true;
+
+                    CSCLContext *context = CSCLContext::get_instance();
+                    SCLShiftState shiftstate = SCL_SHIFT_STATE_OFF;
+                    if (context)
+                        shiftstate = context->get_shift_state();
+                    if (labelproperties->shadow_distance > 0 && labelproperties->shadow_color[shiftstate][state].a != 0) {
+                        sclint deltax = 0;
+                        sclint deltay = 0;
+
+                        if (labelproperties->shadow_direction == SHADOW_DIRECTION_LEFT_TOP ||
+                                labelproperties->shadow_direction == SHADOW_DIRECTION_LEFT_MIDDLE ||
+                                labelproperties->shadow_direction == SHADOW_DIRECTION_LEFT_BOTTOM) {
+                            deltax -= labelproperties->shadow_distance * utils->get_smallest_custom_scale_rate();
+                        } else if (labelproperties->shadow_direction == SHADOW_DIRECTION_RIGHT_TOP ||
+                                   labelproperties->shadow_direction == SHADOW_DIRECTION_RIGHT_MIDDLE ||
+                                   labelproperties->shadow_direction == SHADOW_DIRECTION_RIGHT_BOTTOM) {
+                            deltax += labelproperties->shadow_distance * utils->get_smallest_custom_scale_rate();
+                        }
+
+                        if (labelproperties->shadow_direction == SHADOW_DIRECTION_LEFT_TOP ||
+                                labelproperties->shadow_direction == SHADOW_DIRECTION_CENTER_TOP ||
+                                labelproperties->shadow_direction == SHADOW_DIRECTION_RIGHT_TOP) {
+                            deltay -= labelproperties->shadow_distance * utils->get_smallest_custom_scale_rate();
+                        } else if (labelproperties->shadow_direction == SHADOW_DIRECTION_LEFT_BOTTOM ||
+                                   labelproperties->shadow_direction == SHADOW_DIRECTION_CENTER_BOTTOM ||
+                                   labelproperties->shadow_direction == SHADOW_DIRECTION_RIGHT_BOTTOM) {
+                            deltay += labelproperties->shadow_distance * utils->get_smallest_custom_scale_rate();
+                        }
+
+                        graphics->draw_text(
+                            targetwin,
+                            draw_ctx,
+                            info,
+                            labelproperties->shadow_color[shiftstate][state],
+                            label,
+                            NULL,
+                            (sclint)coordinate->x + deltax + targetaddx,
+                            (sclint)coordinate->y + deltax + targetaddy,
+                            (sclint)coordinate->width,
+                            (sclint)coordinate->height,
+                            labelproperties->alignment,
+                            labelproperties->padding_x * utils->get_custom_scale_rate_x(),
+                            labelproperties->padding_y * utils->get_custom_scale_rate_y(),
+                            labelproperties->inner_width * utils->get_custom_scale_rate_x(),
+                            labelproperties->inner_height * utils->get_custom_scale_rate_y());
+                    }
+                    graphics->draw_text(
+                        targetwin,
+                        draw_ctx,
+                        info,
+                        labelproperties->font_color[shiftstate][state],
+                        label,
+                        NULL,
+                        (sclint)coordinate->x + targetaddx,
+                        (sclint)coordinate->y + targetaddy,
+                        (sclint)coordinate->width,
+                        (sclint)coordinate->height,
+                        labelproperties->alignment,
+                        labelproperties->padding_x * utils->get_custom_scale_rate_x(),
+                        labelproperties->padding_y * utils->get_custom_scale_rate_y(),
+                        labelproperties->inner_width * utils->get_custom_scale_rate_x(),
+                        labelproperties->inner_height * utils->get_custom_scale_rate_y());
+                }
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+* Draws window's background using software
+* @remark
+*/
+sclboolean
+CSCLUIBuilder::draw_window_bg_by_sw(const sclwindow window, const scldrawctx draw_ctx, const SclSize size,
+                                    const scldouble line_width, const SclColor line_color, const SclColor fill_color)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(window);
+    scl_assert_return_false(draw_ctx);
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLGraphics *graphics = CSCLGraphics::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    if (graphics && windows && cache) {
+        /* If the target window is virtual window, let's draw it on the base window */
+        sclwindow targetwin = window;
+        //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+        SclWindowContext *window_context = windows->get_window_context(window);
+        if (window_context) {
+            if (window_context->is_virtual) {
+                targetwin = windows->get_base_window();
+            }
+        }
+
+        graphics->draw_rectangle(targetwin, draw_ctx,
+            cache->get_custom_starting_coordinates().x, cache->get_custom_starting_coordinates().y,
+            size.width, size.height, line_width, line_color, TRUE, fill_color);
+    }
+
+    return TRUE;
+}
+
+/**
+ * Draws a button using software
+ * @remark draw_button
+ */
+scldrawing
+CSCLUIBuilder::draw_button_bg_by_sw(const sclwindow window, const scldrawctx draw_ctx, const scl16 key_index, const SCLButtonState state)
+{
+    //SCL_DEBUG();
+
+    //CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    //const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(window, key_index);
+
+    //scl_assert_return_false(window);
+    //scl_assert_return_false(draw_ctx);
+    //scl_assert_return_false(coords);
+
+    //scl_assert_return_false(state >= BUTTON_STATE_NORMAL && state < SCL_BUTTON_STATE_MAX);
+
+    //scldouble line_width = scl_swbutton_style[scl_default_configure.sw_button_style].line_width[state];
+    //SclColor &line_color = scl_swbutton_style[scl_default_configure.sw_button_style].line_color[state];
+    //SclColor &bg_color = scl_swbutton_style[scl_default_configure.sw_button_style].bg_color[state];
+    //scldouble line_curve = scl_swbutton_style[scl_default_configure.sw_button_style].line_curve;
+    //sclfloat bg_alpha = scl_swbutton_style[scl_default_configure.sw_button_style].bg_alpha;
+
+    ///*if (g_key_spacing_off) {
+    //    m_gwes->m_graphics->draw_rectangle(window,
+    //        draw_ctx,
+    //        (sclint)coords->x - (sclint)coords->add_hit_left,
+    //        (sclint)coords->y - (sclint)coords->add_hit_top,
+    //        (sclint)coords->width + (sclint)coords->add_hit_left + (sclint)coords->add_hit_right,
+    //        (sclint)coords->height + (sclint)coords->add_hit_top + (sclint)coords->add_hit_bottom,
+    //        line_width,
+    //        line_color,
+    //        TRUE,
+    //        bg_color,
+    //        line_curve,
+    //        bg_alpha);
+    //} else {*/
+    //    m_gwes->m_graphics->draw_rectangle(window,
+    //                                 draw_ctx,
+    //                                 coords->x,
+    //                                 coords->y,
+    //                                 coords->width,
+    //                                 coords->height,
+    //                                 line_width,
+    //                                 line_color,
+    //                                 TRUE,
+    //                                 bg_color,
+    //                                 line_curve,
+    //                                 bg_alpha);
+    ////}
+    return NULL;
+}
+
+/**
+ * Draws a button using the set image
+ * @remark draw_button
+ */
+scldrawing
+CSCLUIBuilder::draw_button_bg_by_img(const sclwindow window, const scldrawctx draw_ctx, scl16 key_index, SCLButtonState state, SCLShiftState shift)
+{
+    SCL_DEBUG();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLGraphics *graphics = CSCLGraphics::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    const SclLayoutKeyCoordinate* coordinate = NULL;
+
+    if (!context || !windows || !graphics || !cache || !sclres_manager) return NULL;
+
+    coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+
+    PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
+    assert(sclres_modifier_decoration != NULL);
+    scl_assert_return_null(window);
+    scl_assert_return_null(draw_ctx);
+
+    scl_assert_return_null(state >= BUTTON_STATE_NORMAL && state < SCL_BUTTON_STATE_MAX);
+
+    sclchar composed_path[_POSIX_PATH_MAX] = {0, };
+
+    if (context && windows && graphics && cache && coordinate) {
+        sclboolean path_composed = FALSE;
+        /* Check if we need to decorate the button's drag state */
+        //if (context->get_cur_drag_state(context->get_last_touch_device_id()) != SCL_DRAG_STATE_NONE &&
+        if (context->get_cur_key_modifier(context->get_last_touch_device_id()) != KEY_MODIFIER_NONE &&
+            context->get_cur_pressed_window(context->get_last_touch_device_id()) == window &&
+            context->get_cur_pressed_key(context->get_last_touch_device_id()) == key_index &&
+            coordinate->modifier_decorator) {
+                sclchar *decoration_bg_img = NULL;
+                const SclModifierDecoration *decoration = NULL;
+                /* FIXME */
+                /*if (scl_check_arrindex(coordinate->modifier_decorator,
+                    sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
+                scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
+                if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
+                    if (sclres_modifier_decoration[decoration_id].valid) {
+                        decoration = &(sclres_modifier_decoration[decoration_id]);
+                    }
+                }
+                if (decoration) {
+                    sclshort display = context->get_display_mode();
+                    if (!scl_check_arrindex(display, DISPLAYMODE_MAX)) display = 0;
+                    SCLKeyModifier modifier = context->get_cur_key_modifier(context->get_last_touch_device_id());
+                    if (!scl_check_arrindex(modifier, KEY_MODIFIER_MAX)) modifier = KEY_MODIFIER_NONE;
+                    decoration_bg_img = decoration->bg_image_path[display][modifier];
+                    /*sclshort dragstate = context->get_cur_drag_state(context->get_last_touch_device_id());
+                    if (!scl_check_arrindex(dragstate, SCL_DRAG_STATE_MAX)) dragstate = 0;
+                    decoration_bg_img = decoration->bg_image_path[display][dragstate];*/
+                }
+                if (decoration_bg_img) {
+                    if (strlen(decoration_bg_img) > 0) {
+                        m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, decoration_bg_img);
+                        path_composed = TRUE;
+                    }
+                }
+        }
+        if (!path_composed) {
+            m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, coordinate->bg_image_path[shift][state]);
+        }
+
+        /* If the target window is virtual window, let's draw it on the base window */
+        sclint targetx = coordinate->x;
+        sclint targety = coordinate->y;
+        sclwindow targetwin = window;
+        //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+        SclWindowContext *window_context = windows->get_window_context(window);
+        if (window_context) {
+            if (window_context->is_virtual) {
+                //SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window(), FALSE);
+                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                if (base_window_context) {
+                    targetwin = windows->get_base_window();
+                    targetx += window_context->geometry.x - base_window_context->geometry.x;
+                    targety += window_context->geometry.y - base_window_context->geometry.y;
+                }
+            }
+        }
+
+        /*if (g_key_spacing_off) {
+            m_gwes->m_graphics->draw_image(
+                window,
+                draw_ctx,
+                composed_path,
+                (sclint)coordinate->x - (sclint)coordinate->add_hit_left,
+                (sclint)coordinate->y - (sclint)coordinate->add_hit_top,
+                (sclint)coordinate->width + (sclint)coordinate->add_hit_left + (sclint)coordinate->add_hit_right,
+                (sclint)coordinate->height + (sclint)coordinate->add_hit_top + (sclint)coordinate->add_hit_bottom
+                );
+        } else {*/
+            return graphics->draw_image(
+                targetwin,
+                draw_ctx,
+                composed_path,
+                NULL,
+                (sclint)targetx,
+                (sclint)targety,
+                (sclint)coordinate->width,
+                (sclint)coordinate->height);
+        //}
+    }
+
+    return NULL;
+}
+
+/**
+ * Draws a button using the set layout image
+ * @remark draw_button
+ */
+scldrawing
+CSCLUIBuilder::draw_button_bg_by_layoutimg(const sclwindow window, const scldrawctx draw_ctx, const scl16 key_index, const SCLButtonState state, const sclboolean shift)
+{
+    SCL_DEBUG();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!context || !windows || !cache || !sclres_manager) return NULL;
+
+    const SclLayout* layout = cache->get_cur_layout(window);
+    const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+    PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
+    assert(sclres_modifier_decoration != NULL);
+
+    scl_assert_return_null(window);
+    scl_assert_return_null(draw_ctx);
+
+    scl_assert_return_null(state >= BUTTON_STATE_NORMAL && state < SCL_BUTTON_STATE_MAX);
+
+    //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+    SclWindowContext *window_context = windows->get_window_context(window);
+
+    sclchar composed_path[_POSIX_PATH_MAX] = {0, };
+    if (context && cache && coordinate && window_context) {
+        sclboolean path_composed = FALSE;
+        /* Check if we need to decorate the button's drag state */
+        //if (context->get_cur_drag_state(context->get_last_touch_device_id()) != SCL_DRAG_STATE_NONE &&
+        if (context->get_cur_key_modifier(context->get_last_touch_device_id()) != KEY_MODIFIER_NONE &&
+            context->get_cur_pressed_window(context->get_last_touch_device_id()) == window &&
+            context->get_cur_pressed_key(context->get_last_touch_device_id()) == key_index &&
+            coordinate->modifier_decorator) {
+                sclchar *decoration_bg_img = NULL;
+                const SclModifierDecoration *decoration = NULL;
+                /* FIXME */
+                /*if (scl_check_arrindex(coordinate->modifier_decorator,
+                    sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
+                scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
+                if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
+                    if (sclres_modifier_decoration[decoration_id].valid) {
+                        decoration = &(sclres_modifier_decoration[decoration_id]);
+                    }
+                }
+                if (decoration) {
+                    sclshort display = context->get_display_mode();
+                    if (!scl_check_arrindex(display, DISPLAYMODE_MAX)) display = 0;
+                    SCLKeyModifier modifier = context->get_cur_key_modifier(context->get_last_touch_device_id());
+                    if (!scl_check_arrindex(modifier, KEY_MODIFIER_MAX)) modifier = KEY_MODIFIER_NONE;
+                    decoration_bg_img = decoration->bg_image_path[display][modifier];
+                    /*sclshort dragstate = context->get_cur_drag_state(context->get_last_touch_device_id());
+                    if (!scl_check_arrindex(dragstate, SCL_DRAG_STATE_MAX)) dragstate = 0;
+                    decoration_bg_img = decoration->bg_image_path[display][dragstate];*/
+                }
+                if (decoration_bg_img) {
+                    if (strlen(decoration_bg_img) > 0) {
+                        m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, decoration_bg_img);
+                        path_composed = TRUE;
+                    }
+                }
+        }
+        if (!path_composed && layout) {
+            m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, layout->image_path[state]);
+        }
+        /*if (g_key_spacing_off) {
+            m_gwes->m_graphics->draw_image(
+                window,
+                draw_ctx,
+                composed_path,
+                (sclint)coordinate->x - (sclint)coordinate->add_hit_left,
+                (sclint)coordinate->y - (sclint)coordinate->add_hit_top,
+                (sclint)coordinate->width + (sclint)coordinate->add_hit_left + (sclint)coordinate->add_hit_right,
+                (sclint)coordinate->height + (sclint)coordinate->add_hit_top + (sclint)coordinate->add_hit_bottom,
+                window_context->imgOffsetx + (sclint)coordinate->x - (sclint)coordinate->add_hit_left,
+                window_context->imgOffsety + (sclint)coordinate->y - (sclint)coordinate->add_hit_top,
+                (sclint)coordinate->width + (sclint)coordinate->add_hit_left + (sclint)coordinate->add_hit_right,
+                (sclint)coordinate->height + (sclint)coordinate->add_hit_top + (sclint)coordinate->add_hit_bottom,
+                TRUE
+                );
+        } else {*/
+            sclint dest_x = coordinate->x;
+            sclint dest_y = coordinate->y;
+            if (window_context->is_virtual) {
+                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                if (base_window_context) {
+                    dest_x += (window_context->geometry.x - base_window_context->geometry.x);
+                    dest_y += (window_context->geometry.y - base_window_context->geometry.y);
+                }
+            }
+
+            return m_gwes->m_graphics->draw_image(
+                window,
+                draw_ctx,
+                composed_path,
+                NULL,
+                dest_x,
+                dest_y,
+                (sclint)coordinate->width,
+                (sclint)coordinate->height,
+                window_context->layout_image_offset.x + (sclint)coordinate->x,
+                window_context->layout_image_offset.y + (sclint)coordinate->y,
+                (sclint)coordinate->width,
+                (sclint)coordinate->height,
+                TRUE);
+        //}
+    }
+    return NULL;
+}
+
+/**
+ * Shows the magnifier window
+ */
+sclboolean
+CSCLUIBuilder::show_magnifier(const sclwindow window, scldrawctx draw_ctx)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(window);
+
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+
+    if (!utils || !context || !cache || !state || !windows) return FALSE;
+
+    utils->log("show_magnifier");
+    sclwindow pressed_window = context->get_cur_pressed_window(context->get_last_touch_device_id());
+    scl8 pressed_key = context->get_cur_pressed_key(context->get_last_touch_device_id());
+
+    /* Due to the explicit delay on hiding magnifier window, there is a case pressed key has been already reset */
+    if (pressed_key == NOT_USED) {
+        pressed_window = context->get_prev_pressed_window(context->get_last_touch_device_id());
+        pressed_key = context->get_prev_pressed_key(context->get_last_touch_device_id());
+    }
+
+    if (pressed_key == NOT_USED || pressed_key >= MAX_KEY) {
+        //utils->log("show_magnifier pressed_key == NOT_USED || pressed_key >= MAX_KEY \n");
+        return TRUE;
+    }
+
+    const SclLayout *layout = cache->get_cur_layout(windows->get_base_window());
+    SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+    SclButtonContext* button_context = cache->get_cur_button_context(pressed_window, pressed_key);
+    SCLShiftState shift_index = context->get_shift_state();
+    if (shift_index >= SCL_SHIFT_STATE_MAX) shift_index = SCL_SHIFT_STATE_OFF;
+    if (context->get_caps_lock_mode()) {
+        shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+    }
+
+    /* Do not show if current layout does not allow magnifier */
+    if (layout) {
+        if (!(layout->use_magnifier_window)) {
+            if (utils) {
+                utils->log("!(layout->use_magnifier_window \n");
+            }
+            return FALSE;
+        }
+    }
+    if (coordinate) {
+        /* Some key types do not use the magnifier window */
+        if ((coordinate->key_type == KEY_TYPE_CONTROL &&
+            coordinate->key_event[0][0] != MVK_space  &&
+            coordinate->key_event[0][0] != MVK_BackSpace) ||
+                (coordinate->key_type == KEY_TYPE_MODECHANGE ||
+                coordinate->key_type == KEY_TYPE_NONE ||
+                coordinate->button_type == BUTTON_TYPE_ROTATION)) {
+            return FALSE;
+        }
+        /* FIXME : workaround for not showing magnifier for recent symbols */
+        /* Do not show if there's nothing to show */
+        //const char *targetstr = coordinate->key_value[shift_index][button_context->multikeyIdx];
+        const char *targetstr = coordinate->label[shift_index][0];
+        if (state) {
+            if (state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
+                targetstr = coordinate->long_key_value;
+            }
+        }
+        const sclchar* customstr = NULL;
+        for (sclint label_index = 0;label_index < MAX_SIZE_OF_LABEL_FOR_ONE && !customstr;label_index++) {
+            const sclchar *tempstr = context->get_custom_magnifier_label(context->get_last_touch_device_id(), label_index);
+            if (tempstr) {
+                customstr = tempstr;
+            }
+        }
+        if (customstr) {
+            targetstr = customstr;
+        }
+        if (targetstr == NULL) {
+            if (utils) {
+                utils->log("coordinate->key_value[shift][button_context->multikeyIdx] == NULL \n");
+            }
+            return FALSE;
+        } else if (strlen(targetstr) == 0) {
+            if (utils) {
+                utils->log("coordinate->key_value[shift][button_context->multikeyIdx]) == 0 \n");
+            }
+            return FALSE;
+        }
+    }
+
+#if 0
+    SclPoint pos = {0, 0};
+    /* calculates x position to be set */
+    pos.x = (coordinate->x + (coordinate->width / 2)) - (utils->get_scale_x(scl_magnifier_configure.width) / 2);
+
+    /* calculates y position to be set */
+    sclint scnWidth, scnHeight;
+    utils->get_screen_resolution(&scnWidth, &scnHeight);
+    pos.y = (scnHeight - layout->height) + coordinate->y - utils->get_scale_y(scl_magnifier_configure.height);
+    windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
+#endif
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    PSclMagnifierWndConfigure magnifier_configure = NULL;
+    if (sclres_manager) {
+        magnifier_configure = sclres_manager->get_magnifier_configure();
+    }
+    if (coordinate && magnifier_configure && utils && state) {
+        sclchar composed_path[_POSIX_PATH_MAX] = {0, };
+        if (state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY) {
+            m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, magnifier_configure->bg_long_key_image_path);
+            m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, 0, 0,
+                magnifier_configure->width * utils->get_custom_scale_rate_x(),
+                magnifier_configure->height * utils->get_custom_scale_rate_y());
+        } else {
+            if (shift_index == SCL_SHIFT_STATE_LOCK) {
+                m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, magnifier_configure->bg_shift_lock_image_path);
+                m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, 0, 0,
+                    magnifier_configure->width * utils->get_custom_scale_rate_x(),
+                    magnifier_configure->height * utils->get_custom_scale_rate_y());
+            } else if (shift_index == SCL_SHIFT_STATE_ON) {
+                m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, magnifier_configure->bg_shift_image_path);
+                m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, 0, 0,
+                    magnifier_configure->width * utils->get_custom_scale_rate_x(),
+                    magnifier_configure->height * utils->get_custom_scale_rate_y());
+            } else {
+                m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, magnifier_configure->bg_image_path);
+                m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, 0, 0,
+                    magnifier_configure->width * utils->get_custom_scale_rate_x(),
+                    magnifier_configure->height * utils->get_custom_scale_rate_y());
+            }
+        }
+
+        for (int loop = 0;loop < MAX_WND_DECORATOR;loop++) {
+            if (magnifier_configure->decoration_image_path[loop] &&
+                strlen(magnifier_configure->decoration_image_path[loop]) > 0) {
+                m_utils->get_composed_path(composed_path, IMG_PATH_PREFIX, magnifier_configure->decoration_image_path[loop]);
+                int decoration_size = magnifier_configure->decoration_size * utils->get_smallest_custom_scale_rate();
+                switch (loop) {
+                case WND_DECORATOR_TOP_LEFT:
+                    m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
+                        0, 0, decoration_size, decoration_size);
+                    break;
+                case WND_DECORATOR_TOP_CENTER:
+                    m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, decoration_size, 0,
+                        magnifier_configure->width * utils->get_custom_scale_rate_x()- (2 * decoration_size), decoration_size);
+                    break;
+                case WND_DECORATOR_TOP_RIGHT:
+                    m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
+                        magnifier_configure->width * utils->get_custom_scale_rate_x() - decoration_size, 0, decoration_size, decoration_size);
+                    break;
+                case WND_DECORATOR_MIDDLE_LEFT:
+                    m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, 0,
+                        decoration_size, decoration_size, magnifier_configure->height * utils->get_custom_scale_rate_y() - (2 * decoration_size));
+                    break;
+                case WND_DECORATOR_MIDDLE_CENTER:
+                    m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, 0, 0,
+                        magnifier_configure->width * utils->get_custom_scale_rate_x(), magnifier_configure->height * utils->get_custom_scale_rate_y());
+                    break;
+                case WND_DECORATOR_MIDDLE_RIGHT:
+                    m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
+                        magnifier_configure->width * utils->get_custom_scale_rate_x() - decoration_size, decoration_size,
+                        decoration_size, magnifier_configure->height * utils->get_custom_scale_rate_y() - (2 * decoration_size));
+                    break;
+                case WND_DECORATOR_BOTTOM_LEFT:
+                    m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, 0,
+                        magnifier_configure->height * utils->get_custom_scale_rate_y() - decoration_size, decoration_size, decoration_size);
+                    break;
+                case WND_DECORATOR_BOTTOM_CENTER:
+                    m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL,
+                        decoration_size, magnifier_configure->height * utils->get_custom_scale_rate_y() - decoration_size,
+                        magnifier_configure->width * utils->get_custom_scale_rate_x() - (2 * decoration_size), decoration_size);
+                    break;
+                case WND_DECORATOR_BOTTOM_RIGHT:
+                    m_gwes->m_graphics->draw_image(window, draw_ctx, composed_path, NULL, magnifier_configure->width * utils->get_custom_scale_rate_x()
+                        - decoration_size, magnifier_configure->height * utils->get_custom_scale_rate_y() - decoration_size, decoration_size, decoration_size);
+                    break;
+                }
+            }
+        }
+
+        sclboolean ended = FALSE;
+        for (int loop = 0;loop < MAX_SIZE_OF_LABEL_FOR_ONE && !ended;loop++) {
+            const SclLabelProperties *labelproperties = cache->get_label_properties(magnifier_configure->label_type, loop);
+            if (labelproperties) {
+                if (labelproperties->valid) {
+                    if (magnifier_configure->show_shift_label) {
+                        shift_index = SCL_SHIFT_STATE_ON;
+                    }
+                    if ((coordinate->use_long_key_magnifier && state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY) ||
+                        state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
+                            const sclchar* targetstr = coordinate->long_key_value;
+                            const sclchar* customstr = context->get_custom_magnifier_label(context->get_last_touch_device_id(), loop);
+                            if (customstr) {
+                                if (coordinate->long_key_value == NULL) {
+                                    targetstr = customstr;
+                                } else if (strlen(coordinate->long_key_value) == 0) {
+                                    targetstr = customstr;
+                                } else if (strcmp(coordinate->long_key_value, " ") == 0) {
+                                    targetstr = customstr;
+                                }
+                                draw_magnifier_label(window, draw_ctx, loop, targetstr);
+                            } else if (loop == 0) {
+                                targetstr = cache->find_substituted_string(targetstr);
+                                draw_magnifier_label(window, draw_ctx, 0, targetstr);
+                            }
+                    } else {
+                        const sclchar* targetstr = NULL;
+                        const sclchar* customstr = context->get_custom_magnifier_label(context->get_last_touch_device_id(), loop);
+                        if (customstr) {
+                            targetstr = customstr;
+                        } else if (coordinate->magnifier_label[shift_index][loop]) {
+                            targetstr = coordinate->magnifier_label[shift_index][loop];
+                            targetstr = cache->find_substituted_string(targetstr);
+                        } else if (loop == 0) {
+                            /* Don't display sublabels of each buttons in magnifier window - this policy can be changed, but for now */
+                            if (button_context) {
+                                targetstr = coordinate->label[shift_index][button_context->multitap_index];
+                                targetstr = cache->find_substituted_string(targetstr);
+                            }
+                        }
+                        if (targetstr) {
+                            draw_magnifier_label(window, draw_ctx, loop, targetstr);
+                        }
+                    }
+                } else {
+                    ended = TRUE;
+                }
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+
+/**
+ * Draws labels on the rectangle of the magnifier window
+ * @remark show_magnifier
+ */
+sclboolean
+CSCLUIBuilder::draw_magnifier_label(const sclwindow window, const scldrawctx draw_ctx, const scl16 label_index, const sclchar* label)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(window);
+    scl_assert_return_false(draw_ctx);
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLGraphics *graphics = CSCLGraphics::get_instance();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    PSclMagnifierWndConfigure magnifier_configure = NULL;
+    if (sclres_manager) {
+        magnifier_configure = sclres_manager->get_magnifier_configure();
+    }
+
+    if (utils && windows && cache && context && graphics && magnifier_configure) {
+        const SclLabelProperties *labelproperties = NULL;
+        if (scl_check_arrindex(label_index, MAX_SIZE_OF_LABEL_FOR_ONE)) {
+            labelproperties = cache->get_label_properties(magnifier_configure->label_type, label_index);
+        }
+        if (labelproperties) {
+            SclFontInfo info;
+            if (labelproperties->font_name) {
+                strncpy(info.font_name, labelproperties->font_name, MAX_FONT_NAME_LEN - 1);
+            }
+            info.font_name[MAX_FONT_NAME_LEN - 1] = '\0';
+            info.font_size = labelproperties->font_size * utils->get_smallest_custom_scale_rate();
+            info.is_bold = info.is_italic = true;
+
+            SCLShiftState shiftstate = context->get_shift_state();
+            if (scl_check_arrindex(shiftstate, SCL_SHIFT_STATE_MAX)) {
+                if (context->get_caps_lock_mode()) {
+                    shiftstate = (shiftstate == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+                }
+                graphics->draw_text(
+                    window,
+                    draw_ctx,
+                    info,
+                    labelproperties->font_color[shiftstate][BUTTON_STATE_NORMAL],
+                    label,
+                    NULL,
+                    magnifier_configure->label_area_rect.left * utils->get_custom_scale_rate_x(),
+                    magnifier_configure->label_area_rect.top * utils->get_custom_scale_rate_y(),
+                    magnifier_configure->label_area_rect.right * utils->get_custom_scale_rate_x(),
+                    magnifier_configure->label_area_rect.bottom * utils->get_custom_scale_rate_y(),
+                    labelproperties->alignment,
+                    labelproperties->padding_x * utils->get_custom_scale_rate_x(),
+                    labelproperties->padding_y * utils->get_custom_scale_rate_y(),
+                    labelproperties->inner_width * utils->get_custom_scale_rate_x(),
+                    labelproperties->inner_height * utils->get_custom_scale_rate_y());
+            }
+        }
+    }
+    return TRUE;
+}
+
+void
+CSCLUIBuilder::set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data)
+{
+    CSCLGraphics *graphics = CSCLGraphics::get_instance();
+
+    if (graphics)
+        graphics->set_graphics_backend_callback(callback, data);
+}
+
+void
+CSCLUIBuilder::set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data)
+{
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    if (m_gwes) {
+        if (m_gwes->m_windows)
+            m_gwes->m_windows->set_window_backend_callback(callback, data);
+        else {
+            if (utils)
+                utils->log("No window");
+        }
+    }
+    else {
+        if (utils)
+            utils->log("No GWES");
+    }
+}
diff --git a/scl/scluibuilder.h b/scl/scluibuilder.h
new file mode 100644 (file)
index 0000000..67f4370
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012 - 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 <map>
+#include <string>
+#include "sclgwes.h"
+#include "sclutils.h"
+#include "sclgraphicsbackendcallback.h"
+#include "sclwindowbackendcallback.h"
+
+#ifndef __SCL_UIBUILDER_H__
+#define __SCL_UIBUILDER_H__
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLUIBuilder
+{
+    friend class CSCLFontProxy;
+
+private:
+    CSCLUIBuilder();
+public:
+    virtual ~CSCLUIBuilder();
+
+    static CSCLUIBuilder* get_instance();
+
+    void init(sclwindow parent);
+    sclboolean show_layout(const sclwindow window, const scl16 x = 0, const scl16 y = 0, const scl16 width = 0, const scl16 height = 0);
+    sclboolean draw_button(const sclwindow window, scldrawctx draw_ctx, const scl16 key_index, const SCLButtonState state, const sclboolean force_draw_bg = FALSE);
+    sclboolean show_magnifier(const sclwindow window, scldrawctx draw_ctx);
+    sclboolean show_autopopup(const sclwindow parent, scldrawctx draw_ctx, const scl16 key_index);
+
+    void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data);
+    void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data);
+
+private:
+    sclboolean draw_button_all(const sclwindow window, const scldrawctx draw_ctx, const scl16 x, const scl16 y, const scl16 width, const scl16 height);
+    scldrawing draw_button_bg_by_sw(const sclwindow window, const scldrawctx draw_ctx, const scl16 key_index, const SCLButtonState state);
+    sclboolean draw_window_bg_by_sw(const sclwindow window, const scldrawctx draw_ctx, const SclSize size,
+        const scldouble line_width, const SclColor line_color, const SclColor fill_color);
+    scldrawing draw_button_bg_by_img(const sclwindow window, const scldrawctx draw_ctx, const scl16 key_index,
+        SCLButtonState state, SCLShiftState shift);
+    scldrawing draw_button_bg_by_layoutimg(const sclwindow window, const scldrawctx draw_ctx, const scl16 key_index,
+        const SCLButtonState state, const sclboolean shift);
+    sclboolean draw_button_label(const sclwindow window, const scldrawctx draw_ctx, const scl16 key_index,
+                                 SCLButtonState state, SCLShiftState shift);
+
+    sclboolean draw_magnifier_label(const sclwindow window, const scldrawctx draw_ctx, const scl16 label_index, const sclchar* label);
+
+    const sclchar* get_button_text_to_read(const sclwindow window, const scl16 key_index, SCLShiftState shift_index);
+
+protected:
+    /* Backend Primitive */
+    CSCLGwes *m_gwes;
+    CSCLUtils *m_utils;
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_UIBUILDER_H__
diff --git a/scl/scluiimpl.cpp b/scl/scluiimpl.cpp
new file mode 100644 (file)
index 0000000..344cdb0
--- /dev/null
@@ -0,0 +1,1237 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+
+#include "scluiimpl.h"
+#include "scldebug.h"
+#include "scluibuilder.h"
+#include "sclcontroller.h"
+#include "sclresourcecache.h"
+#include "sclerroradjustment.h"
+#include "sclres_manager.h"
+#include "scleventhandler.h"
+#include "sclkeyfocushandler.h"
+#include "sclanimator.h"
+
+using namespace scl;
+
+CSCLUIImpl::CSCLUIImpl()
+{
+    SCL_DEBUG();
+
+    /*CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+    CSCLController *controller = CSCLController::get_instance();
+    if (builder && controller) {
+        builder->init(SCLWINDOW_INVALID);
+        controller->init();
+    }*/
+    m_initialized = FALSE;
+    /* FIXME whether need the libscl-ui autocapital the shift state */
+    /* if set to FALSE, the libscl-ui will not auto handle the shift state */
+    /* the client will handle outside the libscl-ui, default is TRUE */
+    m_autocapital_shift_state = TRUE;
+}
+
+CSCLUIImpl::~CSCLUIImpl()
+{
+    SCL_DEBUG();
+}
+
+CSCLUIImpl*
+CSCLUIImpl::get_instance()
+{
+    static CSCLUIImpl instance;
+    return &instance;
+}
+
+sclboolean CSCLUIImpl::init(sclwindow parent, const SCLParserType parser_type, const char *entry_filepath)
+{
+    SCL_DEBUG();
+
+    SCL_DEBUG_ELAPSED_TIME_START();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    if (sclres_manager && builder && cache && utils) {
+        sclres_manager->init(parser_type, entry_filepath);
+
+        utils->init();
+        cache->init();
+        builder->init(parent);
+
+        m_initialized = TRUE;
+    }
+
+    SCL_DEBUG_ELAPSED_TIME_END();
+
+    return TRUE;
+}
+
+void
+CSCLUIImpl::fini()
+{
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    if (utils) {
+        utils->fini();
+    }
+
+    CSCLGwes *gwes = CSCLGwes::get_instance();
+    if (gwes) {
+        gwes->fini();
+    }
+}
+
+/**
+ * Shows the SCL main window
+ * For displaying the SCL UI, you should explicitly call this function after CSCLUIImpl class is created
+ */
+void
+//CSCLUIImpl::show(sclboolean auto_relocate /* = TRUE */ )
+CSCLUIImpl::show()
+{
+    SCL_DEBUG();
+
+    if (m_initialized) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        CSCLContext *context = CSCLContext::get_instance();
+        CSCLController *controller = CSCLController::get_instance();
+        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+        if (utils && windows && controller && context && sclres_manager) {
+            if (utils->update_screen_resolution()) {
+                utils->log("Screen resolution updated, now reloading resource files");
+                /* If the screen resolution has been changed, reload all the xml files and recompute layout */
+                sclres_manager->reload();
+
+                CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+                if (cache) {
+                    cache->resize_resource_elements_by_resolution();
+                    cache->recompute_layout(windows->get_base_window());
+                }
+            } else {
+                utils->log("Screen resolution not changed, continuing");
+            }
+            //if (auto_relocate) {
+            if (TRUE) {
+                /* Let's relocate our base window - bottomed center aligned */
+                SclRectangle rect = get_main_window_rect();
+
+                sclint scrx, scry;
+                utils->get_screen_resolution(&scrx, &scry);
+
+                sclint pos_x = (scrx - rect.width) / 2;
+                sclint pos_y = (scry - rect.height);
+
+                windows->move_window(windows->get_base_window(), pos_x, pos_y);
+            }
+
+            sclwindow window = windows->get_base_window();
+            controller->handle_engine_signal(SCL_SIG_SHOW);
+            windows->show_window(window);
+        }
+    }
+}
+
+/**
+ * Hides the SCL main window
+ * The real hide action does not work about base window because that is child of the active window
+ */
+void
+CSCLUIImpl::hide()
+{
+    SCL_DEBUG();
+
+    if (m_initialized) {
+        CSCLController *controller = CSCLController::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        if (controller && windows) {
+            controller->handle_engine_signal(SCL_SIG_HIDE);
+            windows->hide_window(windows->get_base_window());
+        }
+    }
+}
+
+
+/**
+ * Registers an event callback function
+ * so that the user which uses SCL can receives all events occuring in running
+ */
+void
+CSCLUIImpl::set_ui_event_callback(ISCLUIEventCallback *callback, const sclchar *input_mode)
+{
+    SCL_DEBUG();
+
+    if (m_initialized) {
+        CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+        if (handler) {
+            handler->set_event_callback(callback, input_mode);
+        }
+    }
+}
+
+void
+CSCLUIImpl::set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data)
+{
+    SCL_DEBUG();
+
+    if (m_initialized) {
+        CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+        if (builder) {
+            builder->set_graphics_backend_callback(callback, data);
+        }
+    }
+}
+
+void
+CSCLUIImpl::set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data)
+{
+    SCL_DEBUG();
+
+    if (m_initialized) {
+        CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+        if (builder) {
+            builder->set_window_backend_callback(callback, data);
+        }
+    }
+}
+
+/**
+ * Sets the current input mode to the given mode
+ * @Usage
+ * gCore->set_input_mode("INPUT_MODE_SYMBOL");
+ */
+sclboolean
+CSCLUIImpl::set_input_mode(const sclchar *input_mode)
+{
+    SCL_DEBUG();
+    SCL_DEBUG_ELAPSED_TIME_START();
+
+    sclboolean ret = FALSE;
+
+    if (m_initialized) {
+        CSCLController *controller = CSCLController::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+        CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+
+        scl8 mode = NOT_USED;
+
+        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+        if (sclres_manager) {
+            mode = sclres_manager->get_inputmode_id(input_mode);
+        }
+
+        if (controller && windows && handler && focus_handler && mode != NOT_USED) {
+            if (handler->set_input_mode(input_mode)) {
+                ret = controller->process_input_mode_change(mode);
+                windows->update_window(windows->get_base_window());
+                focus_handler->init_key_index();
+            }
+        }
+    }
+
+    SCL_DEBUG_ELAPSED_TIME_END();
+    return ret;
+}
+
+/**
+ * Returns the current input mode
+ */
+const sclchar*
+CSCLUIImpl::get_input_mode()
+{
+    SCL_DEBUG();
+
+    const sclchar *ret = NULL;
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+        if (context && sclres_manager) {
+            scl8 inputmode_id = context->get_input_mode();
+            ret = sclres_manager->get_inputmode_name(inputmode_id);
+        }
+    }
+    return ret;
+}
+
+
+/**
+ * Sets the given popup window's input mode to the given mode
+ * @Usage
+ * gCore->set_input_mode("INPUT_MODE_SYMBOL");
+ */
+sclboolean
+CSCLUIImpl::set_popup_input_mode(sclwindow window, const sclchar *input_mode)
+{
+    SCL_DEBUG();
+    SCL_DEBUG_ELAPSED_TIME_START();
+
+    sclboolean ret = FALSE;
+
+    if (m_initialized) {
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        CSCLContext *context = CSCLContext::get_instance();
+
+        scl8 mode = NOT_USED;
+        sclshort layout = NOT_USED;
+        SclWindowContext *window_context = NULL;
+
+        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+        if (sclres_manager && windows && context) {
+            SCLDisplayMode display_mode = context->get_display_mode();
+            PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+            mode = sclres_manager->get_inputmode_id(input_mode);
+            window_context = windows->get_window_context(window);
+            if (sclres_input_mode_configure &&
+                scl_check_arrindex(mode, MAX_SCL_INPUT_MODE) &&
+                scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+                    layout = sclres_manager->get_layout_id(sclres_input_mode_configure[mode].layouts[display_mode]);
+            }
+        }
+
+        if (cache && windows && window_context) {
+            if (mode != NOT_USED && mode != window_context->inputmode && layout != NOT_USED) {
+                window_context->inputmode = mode;
+                window_context->layout = layout;
+                cache->recompute_layout(window);
+                windows->update_window(window);
+                ret = TRUE;
+            }
+        }
+    }
+
+    SCL_DEBUG_ELAPSED_TIME_END();
+    return ret;
+}
+
+/**
+ * Returns the given window's input mode
+ */
+const sclchar*
+CSCLUIImpl::get_popup_input_mode(sclwindow window)
+{
+    SCL_DEBUG();
+
+    const sclchar *ret = NULL;
+
+    if (m_initialized) {
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+        if (windows && sclres_manager) {
+            SclWindowContext *window_context = windows->get_window_context(window);
+            if (window_context) {
+                if (scl_check_arrindex(window_context->inputmode, MAX_SCL_INPUT_MODE)) {
+                    ret = sclres_manager->get_inputmode_name(window_context->inputmode);
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+/**
+ * Sets the current rotation
+ */
+sclboolean
+CSCLUIImpl::set_rotation(SCLRotation rotation)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+
+    if (m_initialized) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        CSCLController *controller = CSCLController::get_instance();
+
+        if (utils && windows && controller) {
+            ret = controller->process_rotation_change(rotation);
+
+            //if (auto_relocate) {
+            if (TRUE) {
+                /* Let's relocate our base window - bottomed center aligned */
+                SclRectangle rect = get_main_window_rect();
+
+                sclint scrx, scry;
+                utils->get_screen_resolution(&scrx, &scry);
+
+                sclint pos_x = (scrx - rect.width) / 2;
+                sclint pos_y = (scry - rect.height);
+
+                windows->move_window(windows->get_base_window(), pos_x, pos_y);
+            }
+        }
+    }
+
+    return ret;
+}
+
+/**
+ * Returns the current rotation
+ */
+SCLRotation
+CSCLUIImpl::get_rotation()
+{
+    SCL_DEBUG();
+
+    SCLRotation ret = ROTATION_0;
+
+    CSCLContext *context = CSCLContext::get_instance();
+    if (context) {
+        ret = context->get_rotation();
+    }
+
+    return ret;
+}
+
+/**
+ * Returns the current display mode
+ */
+SCLDisplayMode
+CSCLUIImpl::get_display_mode()
+{
+    SCL_DEBUG();
+
+    SCLDisplayMode ret = DISPLAYMODE_MAX;
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            ret = context->get_display_mode();
+        }
+    }
+    return ret;
+}
+
+/**
+ * Sets a private key to the current context
+ * The other properties except given parameters will keep to the original value.
+ * @Usage
+ * gCore->set_private_key(INPUT_MODE_NUMBER, LYT_PORTRAIT_NOW_3x4, 0, "private", 999, TRUE);
+ *
+ * @param fRedraw If true, it will redraw the current key
+ */
+sclint
+CSCLUIImpl::set_private_key(const sclchar* custom_id, sclchar* label, sclchar* imagelabel[SCL_BUTTON_STATE_MAX], sclchar* imagebg[SCL_BUTTON_STATE_MAX], sclulong key_event, sclchar *key_value, sclboolean fRedraw)
+{
+    SCL_DEBUG();
+    sclint ret = NOT_USED;
+    if (m_initialized) {
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        if (windows && cache) {
+            ret = cache->set_private_key(custom_id, label, imagelabel, imagebg,
+                key_event, key_value, fRedraw, windows->get_update_pending());
+        }
+    }
+    return ret;
+}
+
+
+/**
+* Unsets a private key to the current context
+*/
+void
+CSCLUIImpl::unset_private_key(const sclchar* custom_id)
+{
+    SCL_DEBUG();
+    if (m_initialized) {
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        if (cache) {
+            cache->unset_private_key(custom_id);
+        }
+    }
+}
+
+/**
+* Sets the current theme
+*/
+/* FIXME : If setting themename is not allowed before initializing,
+           the default theme has to be loaded regardless of current theme name
+           and the appropriate current theme has to be loaded afterwards, which is very inefficient */
+sclboolean
+CSCLUIImpl::set_cur_themename(const sclchar *themename)
+{
+    sclboolean ret = FALSE;
+
+    if (m_initialized) {
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        if (cache && windows) {
+            cache->set_cur_themename(themename);
+            windows->update_window(windows->get_base_window());
+            int loop = 0;
+            sclwindow window;
+            do {
+                window = windows->get_nth_popup_window(loop);
+                if (window) {
+                    windows->update_window(window);
+                }
+                loop++;
+            } while (window);
+        }
+        ret = TRUE;
+    }
+
+    return ret;
+}
+
+SCLShiftState
+CSCLUIImpl::get_shift_state()
+{
+    SCLShiftState ret = SCL_SHIFT_STATE_OFF;
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            ret = context->get_shift_state();
+        }
+    }
+    return ret;
+}
+
+void
+CSCLUIImpl::set_shift_state(SCLShiftState state)
+{
+    if (m_initialized) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        CSCLContext *context = CSCLContext::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+
+        /*inform the client that the shift state changed */
+        CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+        if (handler) {
+            SclNotiShiftStateChangeDesc desc;
+            desc.ui_event_desc = NULL;
+            desc.shift_state = state;
+
+            SCLEventReturnType ret = handler->on_event_notification(SCL_UINOTITYPE_SHIFT_STATE_CHANGE, &desc);
+            if (ret == SCL_EVENT_DONE) {
+                return;
+            }
+        }
+
+        if (context && windows && utils) {
+            SCLShiftState current_state = context->get_shift_state();
+            context->set_shift_state(state);
+            if (state != current_state) {
+                windows->update_window(windows->get_base_window());
+                if (context->get_tts_enabled()) {
+                    if (state == SCL_SHIFT_STATE_ON) {
+                        utils->play_tts(SCL_SHIFT_STATE_ON_HINT_STRING);
+                    } else if (state == SCL_SHIFT_STATE_LOCK) {
+                        utils->play_tts(SCL_SHIFT_STATE_LOCK_HINT_STRING);
+                    } else {
+                        utils->play_tts(SCL_SHIFT_STATE_OFF_HINT_STRING);
+                    }
+                }
+            }
+        }
+    }
+}
+
+sclboolean
+CSCLUIImpl::get_caps_lock_mode()
+{
+    sclboolean ret = FALSE;
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            ret = context->get_caps_lock_mode();
+        }
+    }
+    return ret;
+}
+
+void
+CSCLUIImpl::set_caps_lock_mode(sclboolean mode)
+{
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+
+        if (context && windows) {
+            sclboolean current_mode = context->get_caps_lock_mode();
+            if (mode != current_mode) {
+                context->set_caps_lock_mode(mode);
+                windows->update_window(windows->get_base_window());
+            }
+        }
+    }
+}
+
+/**
+ * This function will be called by the user which uses SCL when the context of the focus application is changed
+ * ISE user should explicitly call this function when the context of application is changed.
+ * For instance, focus-changed, application-changed,, and so on.
+ * This function will call CSCLController to init the related variables.
+ */
+void
+CSCLUIImpl::notify_app_focus_changed()
+{
+    SCL_DEBUG();
+    if (m_initialized) {
+        CSCLController *controller = CSCLController::get_instance();
+        if (controller) {
+            controller->handle_engine_signal(SCL_SIG_FOCUS_CHANGE);
+        }
+    }
+}
+
+void
+CSCLUIImpl::reset_popup_timeout()
+{
+    SCL_DEBUG();
+    if (m_initialized) {
+        CSCLEvents *events = CSCLEvents::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+
+        if (events && windows) {
+            events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+
+            sclbyte index = 0;
+            sclboolean timerset = FALSE;
+            sclwindow window = SCLWINDOW_INVALID;
+            SclWindowContext *window_context = NULL;
+            do {
+                window = windows->get_nth_window_in_Z_order_list(index);
+                //window_context = windows->get_window_context(window, FALSE);
+                window_context = windows->get_window_context(window);
+                if (window_context) {
+                    if (window_context->timeout != 0) {
+                        events->create_timer(SCL_TIMER_POPUP_TIMEOUT, window_context->timeout, 0, TRUE);
+                        timerset = TRUE;
+                    }
+                    index++;
+                }
+            } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !timerset);
+        }
+    }
+}
+
+void
+CSCLUIImpl::close_all_popups()
+{
+    SCL_DEBUG();
+    if (m_initialized) {
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        if (windows) {
+            windows->close_all_popups();
+        }
+    }
+}
+
+/**
+ * Returns a scale rate (see default screen resolution in sclconfig.h file)
+ */
+sclfloat
+CSCLUIImpl::get_scale_rate()
+{
+    sclfloat ret = 0.0f;
+    if (m_initialized) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        if (utils) {
+            ret = utils->get_smallest_scale_rate();
+        }
+    }
+    return ret;
+}
+
+/**
+ * Returns a calculated x value according to the current screen resolution
+ */
+scl16
+CSCLUIImpl::get_scaled_x(scl16 x)
+{
+    scl16 ret = 0;
+    if (m_initialized) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        if (utils) {
+            ret = utils->get_scaled_x(x);
+        }
+    }
+    return ret;
+}
+
+/**
+ * Returns a calculated y value according to the current screen resolution
+ */
+scl16
+CSCLUIImpl::get_scaled_y(scl16 y)
+{
+    scl16 ret = 0;
+    if (m_initialized) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        if (utils) {
+            ret = utils->get_scaled_y(y);
+        }
+    }
+    return ret;
+}
+
+/**
+ * Returns the current rate x value for resizing the keyboard's content
+ */
+sclfloat
+CSCLUIImpl::get_custom_scale_rate_x()
+{
+    sclfloat ret = 1.0f;
+    if (m_initialized) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        if (utils) {
+            ret = utils->get_custom_scale_rate_x();
+        }
+    }
+    return ret;
+}
+
+/**
+ * Returns the current rate y value for resizing the keyboard's content
+ */
+sclfloat
+CSCLUIImpl::get_custom_scale_rate_y()
+{
+    sclfloat ret = 1.0f;
+    if (m_initialized) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        if (utils) {
+            ret = utils->get_custom_scale_rate_y();
+        }
+    }
+    return ret;
+}
+
+/**
+ * Sets the custom rate value for resizing the keyboard's content
+ */
+void
+CSCLUIImpl::set_custom_scale_rate(sclfloat x, sclfloat y)
+{
+    if (m_initialized) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        if (utils && cache && windows) {
+            utils->set_custom_scale_rate_x(x);
+            utils->set_custom_scale_rate_y(y);
+
+            cache->recompute_layout(windows->get_base_window());
+        }
+    }
+}
+
+/**
+ * Sets the custom starting coordinates for drawing the keyboard's content
+ */
+void
+CSCLUIImpl::set_custom_starting_coordinates(sclint x, sclint y)
+{
+    if (m_initialized) {
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        if (cache) {
+            SclPoint coords = cache->get_custom_starting_coordinates();
+            /* Do not proceed if the new coordinates are same with the values that we currently have */
+            if (x != coords.x || y != coords.y) {
+                cache->set_custom_starting_coordinates(x, y);
+                if (windows) {
+                    cache->recompute_layout(windows->get_base_window());
+                }
+            }
+        }
+    }
+}
+
+/**
+ * Sets the custom starting coordinates option for drawing the keyboard's content
+ */
+void
+CSCLUIImpl::set_custom_starting_coordinates_option(SCLStartingCoordinatesOption option)
+{
+    if (m_initialized) {
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        if (cache) {
+            cache->set_custom_starting_coordinates_option(option);
+        }
+    }
+}
+
+/**
+ * Returns the scl base window size
+ */
+SclRectangle
+CSCLUIImpl::get_main_window_rect()
+{
+    SclRectangle ret = {0, 0, 0, 0};
+
+    if (m_initialized) {
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        if (cache && windows) {
+            //const SclLayout *layout  = cache->get_cur_layout(windows->get_base_window());
+            SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());
+            if (window_context) {
+                ret.x = window_context->geometry.x;
+                ret.y = window_context->geometry.y;
+                ret.width = window_context->geometry.width;
+                ret.height = window_context->geometry.height;
+            }
+        }
+    }
+
+    return ret;
+}
+
+/**
+ * Returns the scl base window size
+ */
+SclSize
+CSCLUIImpl::get_input_mode_size(const sclchar *input_mode, SCLDisplayMode display_mode)
+{
+    SclSize ret = {0, 0};
+
+    if (m_initialized) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+        if (utils && sclres_manager) {
+            const PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+            const PSclLayout sclres_layout = sclres_manager->get_layout_table();
+            sclint inputmode = sclres_manager->get_inputmode_id(input_mode);
+            if (sclres_input_mode_configure && sclres_layout) {
+                sclint layout = sclres_manager->get_layout_id(
+                        sclres_input_mode_configure[inputmode].layouts[display_mode]);
+
+                if (layout >= 0) {
+                    ret.width = sclres_layout[layout].width;
+                    ret.height = sclres_layout[layout].height;
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+/**
+* Returns the screen resolution
+*/
+void
+CSCLUIImpl::get_screen_resolution(sclint *width, sclint *height)
+{
+    if (m_initialized) {
+        CSCLUtils *utils = CSCLUtils::get_instance();
+        if (utils && width && height) {
+            utils->get_screen_resolution(width, height);
+        }
+    }
+}
+
+void
+CSCLUIImpl::set_debug_mode(SCLDebugMode mode)
+{
+    if (m_initialized) {
+        CSCLController *controller = CSCLController::get_instance();
+        if (controller) {
+            controller->set_debug_mode(mode);
+        }
+    }
+}
+
+SCLDebugMode
+CSCLUIImpl::get_debug_mode()
+{
+    SCLDebugMode ret = DEBUGMODE_DISABLED;
+    if (m_initialized) {
+        CSCLController *controller = CSCLController::get_instance();
+        if (controller) {
+            ret = controller->get_debug_mode();
+        }
+    }
+    return ret;
+}
+
+void
+CSCLUIImpl::set_update_pending(sclboolean pend)
+{
+    if (m_initialized) {
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        if (windows) {
+            windows->set_update_pending(pend);
+        }
+    }
+}
+
+void
+CSCLUIImpl::enable_button(const sclchar* custom_id, sclboolean enabled)
+{
+    if (m_initialized) {
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        if (cache) {
+            cache->enable_button(custom_id, enabled);
+        }
+    }
+}
+
+sclint
+CSCLUIImpl::get_multi_touch_context_num()
+{
+    sclint ret = 0;
+
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            ret = context->get_multi_touch_context_num();
+        }
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUIImpl::get_multi_touch_event(sclint seqorder, SclUIEventDesc *desc)
+{
+    sclboolean ret = FALSE;
+
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            ret = context->get_multi_touch_event(seqorder, desc);
+        }
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUIImpl::set_longkey_duration(scllong msc)
+{
+    sclboolean ret = FALSE;
+
+    if (m_initialized) {
+        CSCLController *controller = CSCLController::get_instance();
+        if (controller) {
+            ret = controller->set_longkey_duration(msc);
+        }
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUIImpl::set_longkey_cancel_dist(sclshort dist)
+{
+    sclboolean ret = FALSE;
+
+    if (m_initialized) {
+        CSCLController *controller = CSCLController::get_instance();
+        if (controller) {
+            ret = controller->set_longkey_cancel_dist(dist);
+        }
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUIImpl::set_repeatkey_duration(scllong msc)
+{
+    sclboolean ret = FALSE;
+
+    if (m_initialized) {
+        CSCLController *controller = CSCLController::get_instance();
+        if (controller) {
+            ret = controller->set_repeatkey_duration(msc);
+        }
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUIImpl::set_autopopup_key_duration(scllong msc)
+{
+    sclboolean ret = FALSE;
+
+    if (m_initialized) {
+        CSCLController *controller = CSCLController::get_instance();
+        if (controller) {
+            ret = controller->set_autopopup_key_duration(msc);
+        }
+    }
+    return ret;
+}
+
+sclboolean
+CSCLUIImpl::set_button_delay_duration(scllong msc)
+{
+    sclboolean ret = FALSE;
+
+    if (m_initialized) {
+        CSCLController *controller = CSCLController::get_instance();
+        if (controller) {
+            ret = controller->set_button_delay_duration(msc);
+        }
+    }
+    return ret;
+}
+
+void
+CSCLUIImpl::enable_magnifier(sclboolean enabled)
+{
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            context->set_magnifier_enabled(enabled);
+        }
+    }
+}
+
+void
+CSCLUIImpl::enable_sound(sclboolean enabled)
+{
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            context->set_sound_enabled(enabled);
+        }
+    }
+}
+
+void
+CSCLUIImpl::enable_vibration(sclboolean enabled)
+{
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            context->set_vibration_enabled(enabled);
+        }
+    }
+}
+
+void
+CSCLUIImpl::enable_tts(sclboolean enabled)
+{
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            context->set_tts_enabled(enabled);
+        }
+    }
+}
+
+void
+CSCLUIImpl::enable_shift_multi_touch(sclboolean enabled)
+{
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            context->set_shift_multi_touch_enabled(enabled);
+        }
+    }
+}
+
+void
+CSCLUIImpl::enable_highlight_ui(sclboolean enabled)
+{
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        if (context && windows) {
+            context->set_highlight_ui_enabled(enabled);
+
+            sclwindow window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+            windows->update_window(window);
+            if (!(windows->is_base_window(window))) {
+                windows->update_window(windows->get_base_window());
+            }
+        }
+        if (enabled) {
+            CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+            const SclLayoutKeyCoordinate *coordinate = NULL;
+            scl8 key_index;
+            sclwindow focus_window ;
+            CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+            if (!windows || !focus_handler || !cache) return;
+
+            focus_window = focus_handler->get_current_focus_window();
+            key_index = focus_handler->get_current_focus_key();
+            if (cache) {
+                coordinate = cache->get_cur_layout_key_coordinate(focus_window, key_index);
+            }
+            if (coordinate) {
+                windows->update_window(focus_window,
+                                coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+            }
+        }
+    }
+}
+
+void
+CSCLUIImpl::enable_highlight_ui_animation(sclboolean enabled)
+{
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        CSCLAnimator *animator = CSCLAnimator::get_instance();
+        if (context && animator) {
+            context->set_highlight_ui_animation_enabled(enabled);
+
+            if (!enabled) {
+                sclint id = animator->find_animator_by_type(ANIMATION_TYPE_HIGHLIGHT_UI);
+                if (id != NOT_USED) {
+                    animator->destroy_animator(id);
+                }
+            }
+        }
+    }
+}
+
+void
+CSCLUIImpl::enable_touch_offset(sclboolean enabled)
+{
+    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+    if (adjustment) {
+        adjustment->enable_touch_offset(enabled);
+    }
+}
+
+void
+CSCLUIImpl::disable_input_events(sclboolean disabled)
+{
+    if (m_initialized) {
+        CSCLController *controller = CSCLController::get_instance();
+        if (controller) {
+            controller->disable_input_events(disabled);
+        }
+    }
+}
+
+sclboolean
+CSCLUIImpl::set_cur_sublayout(const sclchar *sub_layout_name)
+{
+    sclboolean ret = FALSE;
+
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        if (context && windows) {
+            ret = context->set_cur_sublayout(sub_layout_name);
+            SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());
+            if (window_context) {
+                if (!(window_context->hidden)) {
+                    /* Update main window only when it is in visible state */
+                    windows->update_window(windows->get_base_window());
+                }
+            }
+        }
+    }
+    return ret;
+}
+
+const sclchar*
+CSCLUIImpl::get_cur_sublayout()
+{
+    sclchar* ret = NULL;
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            ret = context->get_cur_sublayout();
+        }
+    }
+    return ret;
+}
+
+void
+CSCLUIImpl::set_custom_magnifier_label(scltouchdevice touch_id, sclint index, const sclchar* label)
+{
+    if (m_initialized) {
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context) {
+            context->set_custom_magnifier_label(touch_id, index, label);
+        }
+    }
+}
+
+void
+CSCLUIImpl::set_string_substitution(const sclchar *original, const sclchar *substitute)
+{
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    if (!cache || !windows) return;
+
+    if (m_initialized) {
+        if (cache->set_string_substitution(original, substitute)) {
+            SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());
+            if (window_context) {
+                if (!(window_context->hidden)) {
+                    /* Update main window only when it is in visible state */
+                    windows->update_window(windows->get_base_window());
+                }
+            }
+        }
+    }
+}
+
+void
+CSCLUIImpl::unset_string_substitution(const sclchar *original)
+{
+    if (m_initialized) {
+        CSCLWindows *windows = CSCLWindows::get_instance();
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        if (cache && windows) {
+            cache->unset_string_substitution(original);
+            SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());
+            if (window_context) {
+                if (!(window_context->hidden)) {
+                    /* Update main window only when it is in visible state */
+                    windows->update_window(windows->get_base_window());
+                }
+            }
+        }
+    }
+}
+
+void
+CSCLUIImpl::set_autocapital_shift_state(sclboolean flag) {
+    m_autocapital_shift_state = flag;
+}
+
+sclboolean
+CSCLUIImpl::get_autocapital_shift_state() {
+    return m_autocapital_shift_state;
+}
+
+sclboolean
+CSCLUIImpl::process_key_event(const char *key)
+{
+    if (m_initialized) {
+        CSCLEvents *events = CSCLEvents::get_instance();
+        return events->process_key_event(key);
+    }
+    return FALSE;
+}
+
+sclboolean
+CSCLUIImpl::get_button_geometry(const sclchar* custom_id, SclRectangle *rectangle)
+{
+    if (m_initialized) {
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        if (cache)
+            return cache->get_button_geometry(custom_id, rectangle);
+    }
+    return FALSE;
+}
diff --git a/scl/scluiimpl.h b/scl/scluiimpl.h
new file mode 100644 (file)
index 0000000..847b236
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_UIIMPL_H__
+#define __SCL_UIIMPL_H__
+
+#include "scltypes.h"
+#include "sclstructs.h"
+#include "scleventcallback.h"
+#include "sclgraphicsbackendcallback.h"
+#include "sclwindowbackendcallback.h"
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLUIImpl
+{
+private:
+    CSCLUIImpl();
+
+public:
+    virtual ~CSCLUIImpl();
+    static CSCLUIImpl* get_instance();
+
+    sclboolean init(sclwindow parent, SCLParserType parser_type, const char *entry_filepath);
+    void fini();
+
+    void show();
+    void hide();
+
+    void set_ui_event_callback(ISCLUIEventCallback *callback, const sclchar *input_mode);
+    void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data);
+    void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data);
+
+    sclboolean set_rotation(SCLRotation degree);
+    SCLRotation get_rotation();
+
+    SCLDisplayMode get_display_mode();
+
+    sclboolean set_input_mode(const sclchar *input_mode);
+    const sclchar* get_input_mode();
+    sclboolean set_popup_input_mode(sclwindow window, const sclchar *input_mode);
+    const sclchar* get_popup_input_mode(sclwindow window);
+
+    void set_update_pending(sclboolean pend);
+
+    sclint set_private_key(const sclchar* custom_id, sclchar* label, sclchar* imagelabel[SCL_BUTTON_STATE_MAX], sclchar* imagebg[SCL_BUTTON_STATE_MAX], sclulong key_event, sclchar *key_value, sclboolean redraw);
+    void unset_private_key(const sclchar* custom_id);
+
+    void enable_button(const sclchar* custom_id, sclboolean enabled);
+
+    sclboolean set_cur_themename(const sclchar *themename);
+
+    sclboolean set_cur_sublayout(const sclchar *sub_layout_name);
+    const sclchar* get_cur_sublayout();
+
+    void set_shift_state(SCLShiftState state);
+    SCLShiftState get_shift_state();
+
+    void set_caps_lock_mode(sclboolean mode);
+    sclboolean get_caps_lock_mode();
+
+    void notify_app_focus_changed();
+    void reset_popup_timeout();
+    void close_all_popups();
+
+    SclRectangle get_main_window_rect();
+    SclSize get_input_mode_size(const sclchar *input_mode, SCLDisplayMode display_mode);
+    void get_screen_resolution(sclint *width, sclint *height);
+
+    scl16 get_scaled_x(scl16 x);
+    scl16 get_scaled_y(scl16 y);
+    sclfloat get_scale_rate();
+
+    sclfloat get_custom_scale_rate_x();
+    sclfloat get_custom_scale_rate_y();
+    void set_custom_scale_rate(sclfloat x, sclfloat y);
+
+    void set_custom_starting_coordinates(sclint x, sclint y);
+    void set_custom_starting_coordinates_option(SCLStartingCoordinatesOption option);
+
+    sclint get_multi_touch_context_num();
+    sclboolean get_multi_touch_event(sclint seqorder, SclUIEventDesc *desc);
+
+    void set_debug_mode(SCLDebugMode mode);
+    SCLDebugMode get_debug_mode();
+
+    sclboolean set_longkey_duration(scllong msc);
+    sclboolean set_longkey_cancel_dist(sclshort dist);
+    sclboolean set_repeatkey_duration(scllong msc);
+    sclboolean set_autopopup_key_duration(scllong msc);
+    sclboolean set_button_delay_duration(scllong msc);
+
+    void enable_magnifier(sclboolean enabled);
+    void enable_sound(sclboolean enabled);
+    void enable_vibration(sclboolean enabled);
+    void enable_tts(sclboolean enabled);
+    void enable_shift_multi_touch(sclboolean enabled);
+    void enable_highlight_ui(sclboolean enabled);
+    void enable_highlight_ui_animation(sclboolean enabled);
+
+    void enable_touch_offset(sclboolean enabled);
+    void disable_input_events(sclboolean disabled);
+
+    void set_custom_magnifier_label(scltouchdevice touch_id, sclint index, const sclchar* label);
+
+    void set_string_substitution(const sclchar *original, const sclchar *substitute);
+    void unset_string_substitution(const sclchar *original);
+    sclboolean get_autocapital_shift_state();
+    void set_autocapital_shift_state(sclboolean flag);
+
+    sclboolean process_key_event(const char *key);
+    sclboolean get_button_geometry(const sclchar* custom_id, SclRectangle *rectangle);
+
+private:
+    sclboolean m_initialized;
+    sclboolean m_autocapital_shift_state;
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_UIIMPL_H__
diff --git a/scl/sclutils-linux.cpp b/scl/sclutils-linux.cpp
new file mode 100644 (file)
index 0000000..526a141
--- /dev/null
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2012 - 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 "sclutils.h"
+#include "scldebug.h"
+#include "sclcontext.h"
+
+#include <stdarg.h>
+
+#include <Elementary.h>
+#ifdef WAYLAND
+#define EFL_BETA_API_SUPPORT
+#include <Ecore_Wl2.h>
+#else
+#include <Ecore_X.h>
+#endif
+#include <feedback.h>
+#include <tts.h>
+#include <vconf.h>
+
+#include <dlog.h>
+
+using namespace scl;
+
+static tts_h tts = NULL;
+#ifndef WAYLAND
+static Eina_Bool _get_default_zone_geometry_info(Ecore_X_Window root, scluint *x, scluint *y, scluint *w, scluint *h)
+{
+    Ecore_X_Atom zone_geometry_atom;
+    Ecore_X_Window* zone_lists;
+    sclint num_zone_lists;
+    sclint num_ret;
+    Eina_Bool ret;
+
+    zone_geometry_atom = ecore_x_atom_get("_E_ILLUME_ZONE_GEOMETRY");
+    if (!zone_geometry_atom) {
+        /* Error... */
+        return EINA_FALSE;
+    }
+
+    scluint geom[4];
+    num_zone_lists = ecore_x_window_prop_window_list_get(root, ECORE_X_ATOM_E_ILLUME_ZONE_LIST, &zone_lists);
+    if (num_zone_lists > 0) {
+        num_ret = ecore_x_window_prop_card32_get(zone_lists[0], zone_geometry_atom, geom, 4);
+        if (num_ret == 4) {
+            if (x) *x = geom[0];
+            if (y) *y = geom[1];
+            if (w) *w = geom[2];
+            if (h) *h = geom[3];
+            ret = EINA_TRUE;
+        } else {
+            ret = EINA_FALSE;
+        }
+    } else {
+        /* if there is no zone available */
+        ret = EINA_FALSE;
+    }
+
+    if (zone_lists) {
+        /* We must free zone_lists */
+        free(zone_lists);
+    }
+
+    return ret;
+}
+#endif
+static void accessibility_changed_cb(keynode_t *key, void* data)
+{
+    int r;
+    int enabled = 0;
+    if (vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &enabled) == 0) {
+        LOGD("VCONFKEY_SETAPPL_ACCESSIBILITY_TTS : %d, (%p)", enabled, tts);
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context)
+            context->set_tts_enabled(enabled);
+
+        if (enabled) {
+            if (tts == NULL) {
+                LOGD("Initializing TTS\n");
+
+                r = tts_create(&tts);
+                if (TTS_ERROR_NONE != r) {
+                    LOGD("tts_create FAILED : result(%d)", r);
+                } else {
+                    r = tts_set_mode(tts, TTS_MODE_SCREEN_READER);
+                }
+                if (TTS_ERROR_NONE != r) {
+                    LOGD("tts_set_mode FAILED : result(%d)", r);
+                }
+
+                tts_state_e current_state;
+                r = tts_get_state(tts, &current_state);
+                if (TTS_ERROR_NONE != r) {
+                    LOGD("tts_get_state FAILED : result(%d)", r);
+                }
+
+                if (TTS_STATE_CREATED == current_state)  {
+                    r = tts_prepare(tts);
+                }
+                if (TTS_ERROR_NONE != r) {
+                    LOGD("tts_prepare FAILED : ret(%d)\n", r);
+                }
+            }
+        } else {
+            if (tts != NULL) {
+                LOGD("Deinitializing TTS\n");
+
+                r = tts_unprepare(tts);
+                if (TTS_ERROR_NONE != r) {
+                    LOGD("tts_unprepare FAILED : result(%d)", r);
+                }
+
+                r = tts_destroy(tts);
+                if (TTS_ERROR_NONE != r) {
+                    LOGD("tts_destroy FAILED : result(%d)", r);
+                }
+
+                tts = NULL;
+            }
+        }
+    }
+}
+
+void
+CSCLUtilsImplLinux::init() {
+    SCL_DEBUG();
+    ecore_wl2_init();
+
+    open_devices();
+
+    vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, accessibility_changed_cb, NULL);
+    accessibility_changed_cb(NULL, NULL);
+}
+
+void
+CSCLUtilsImplLinux::fini() {
+    SCL_DEBUG();
+
+    vconf_ignore_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, accessibility_changed_cb);
+
+    close_devices();
+
+    ecore_wl2_shutdown();
+}
+
+/* FIXME : Currently the screen resolution is locally cached, should be updated when it gets changed */
+sclboolean
+CSCLUtilsImplLinux::get_screen_resolution(sclint *x, sclint *y) {
+    SCL_DEBUG();
+    CSCLContext *context = CSCLContext::get_instance();
+
+    sclint scr_w = m_scr_size.width;
+    sclint scr_h = m_scr_size.height;
+    if (m_scr_size.width == 0 || m_scr_size.height == 0) {
+#ifdef WAYLAND
+        ecore_wl2_sync();
+        Ecore_Wl2_Display *ewd;
+        if (!(ewd = ecore_wl2_connected_display_get(NULL)))
+            return FALSE;
+        ecore_wl2_display_screen_size_get(ewd, &scr_w, &scr_h);
+#else
+        scluint w, h;
+        w = h = 0;
+        if (_get_default_zone_geometry_info(ecore_x_window_root_first_get(), NULL, NULL, &w, &h)) {
+            scr_w = w;
+            scr_h = h;
+        } else {
+            ecore_x_window_size_get(ecore_x_window_root_first_get(), &scr_w, &scr_h);
+        }
+#endif
+        m_scr_size.width = scr_w;
+        m_scr_size.height = scr_h;
+    }
+    if (context && x && y) {
+        if (context->get_display_mode() == DISPLAYMODE_LANDSCAPE) {
+            *x = scr_h;
+            *y = scr_w;
+        } else {
+            *x = scr_w;
+            *y = scr_h;
+        }
+    }
+    return TRUE;
+}
+
+sclboolean
+CSCLUtilsImplLinux::update_screen_resolution() {
+    sclboolean ret = FALSE;
+    SclSize prev_size = m_scr_size;
+
+    /* Reset screen size cache value for acquiring new resolution */
+    m_scr_size.width = 0;
+    m_scr_size.height = 0;
+    get_screen_resolution(NULL, NULL);
+
+    LOGD("Previous resolution : %d %d, Current resolution : %d %d",
+        prev_size.width, prev_size.height, m_scr_size.width, m_scr_size.height);
+
+    /* Check if the screen size value has been changed */
+    if (m_scr_size.width != prev_size.width || m_scr_size.height != prev_size.height) {
+        ret = TRUE;
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLUtilsImplLinux::play_tts(const sclchar* str) {
+    SCL_DEBUG();
+
+    if (str) {
+        int r;
+        int utt_id = 0;
+        tts_state_e current_state;
+
+        r = tts_get_state(tts, &current_state);
+        if (TTS_ERROR_NONE != r) {
+            LOGD("Fail to get state from TTS : ret(%d)\n", r);
+        }
+
+        if (TTS_STATE_PLAYING == current_state)  {
+            r = tts_stop(tts);
+            if (TTS_ERROR_NONE != r) {
+                LOGD("Fail to stop TTS : ret(%d)\n", r);
+            }
+        }
+        r = tts_add_text(tts, str, NULL, TTS_VOICE_TYPE_AUTO, TTS_SPEED_AUTO, &utt_id);
+        if (TTS_ERROR_NONE == r) {
+            r = tts_play(tts);
+            if (TTS_ERROR_NONE != r) {
+                LOGD("Fail to play TTS : ret(%d)\n", r);
+            }
+        } else {
+            LOGD("Fail to add text : ret(%d)\n", r);
+        }
+    }
+
+    return TRUE;
+}
+
+sclboolean
+CSCLUtilsImplLinux::play_sound(const sclchar* snd_style) {
+    SCL_DEBUG();
+
+    typedef struct {
+        const char *name;
+        feedback_pattern_e type_value;
+    } SOUND_TYPES;
+
+    static const SOUND_TYPES internal_types[] = {
+        {"Backspace", FEEDBACK_PATTERN_SIP},
+    };
+    static const sclint SOUND_TYPES_NUM = (sizeof(internal_types) / sizeof(SOUND_TYPES));
+
+    sclboolean ret = FALSE;
+    int r = FEEDBACK_ERROR_NONE;
+
+    sclboolean found = FALSE;
+    sclint loop = 0;
+    for (loop = 0; loop < SOUND_TYPES_NUM;loop++) {
+        if (strncmp(snd_style, internal_types[loop].name, strlen(internal_types[loop].name)) == 0) {
+            found = TRUE;
+            r = feedback_play_type(FEEDBACK_TYPE_SOUND, internal_types[loop].type_value);
+        }
+    }
+    if (!found) {
+        r = feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_SIP);
+    }
+
+    if (r != FEEDBACK_ERROR_NONE) {
+        LOGD("Cannot play sound : %d\n", r);
+    } else {
+        ret = TRUE;
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLUtilsImplLinux::play_vibration(const sclchar* vibe_style, const scllong duration) {
+    SCL_DEBUG();
+
+    typedef struct {
+        const char *name;
+        feedback_pattern_e type_value;
+    } VIBRATION_TYPES;
+
+    static const VIBRATION_TYPES internal_types[] = {
+        {"Backspace", FEEDBACK_PATTERN_SIP},
+    };
+    static const sclint VIBRATION_TYPES_NUM = (sizeof(internal_types) / sizeof(VIBRATION_TYPES));
+
+    sclboolean ret = FALSE;
+    int r = FEEDBACK_ERROR_NONE;
+
+    sclboolean found = FALSE;
+    sclint loop = 0;
+    for (loop = 0; loop < VIBRATION_TYPES_NUM;loop++) {
+        if (strncmp(vibe_style, internal_types[loop].name, strlen(internal_types[loop].name)) == 0) {
+            found = TRUE;
+            r = feedback_play_type(FEEDBACK_TYPE_VIBRATION, internal_types[loop].type_value);
+        }
+    }
+    if (!found) {
+        r = feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_SIP);
+    }
+
+    if (r != FEEDBACK_ERROR_NONE) {
+        LOGD("Cannot play vibration : %d\n", r);
+    } else {
+        ret = TRUE;
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLUtilsImplLinux::open_devices() {
+    SCL_DEBUG();
+
+    int r = feedback_initialize(); // Initialize feedback
+
+    if (r != FEEDBACK_ERROR_NONE) {
+        LOGD("FEEDBACK INITIALIZATION FAILED : %d\n", r);
+    } else {
+        LOGD("FEEDBACK INITIALIZATION SUCCESSFUL : %d\n", r);
+    }
+
+    return TRUE;
+}
+
+sclboolean
+CSCLUtilsImplLinux::close_devices() {
+    SCL_DEBUG();
+
+    int r = feedback_deinitialize(); // Deinitialize feedback
+
+    if (r != FEEDBACK_ERROR_NONE) {
+        LOGD("FEEDBACK DEINITIALIZATION FAILED : %d\n", r);
+    } else {
+        LOGD("FEEDBACK DEINITIALIZATION SUCCESSFUL : %d\n", r);
+    }
+
+    return TRUE;
+}
+
+sclint CSCLUtilsImplLinux::log(const sclchar *msg)
+{
+    SCL_DEBUG();
+    sclint ret = 0;
+
+    LOGD("%s", msg);
+
+    return ret;
+}
+
+/*
+sclboolean
+CSCLUtilsImplLinux::find_first_file(FILEFINDINFO &sFileFindInfo, const sclchar *szSuffix, const sclchar *szDirPath)
+{
+    sclboolean bSuccess = false;
+
+    sFileFindInfo.Uninitialize();
+
+    sFileFindInfo.pDirInfo = opendir(szDirPath);
+    if (sFileFindInfo.pDirInfo) {
+        sclboolean bEnd = false;
+        while (!bEnd) {
+            struct dirent *pDirEnt = readdir(sFileFindInfo.pDirInfo);
+            if (NULL == pDirEnt) {
+                bEnd = true;
+            } else {
+                if (szSuffix) {
+                    if (strlen(szSuffix) <= strlen(pDirEnt->d_name)) {
+                        if (strcmp(pDirEnt->d_name + strlen(pDirEnt->d_name) - strlen(szSuffix), szSuffix) == 0) {
+                            bSuccess = true;
+                            sFileFindInfo.pDirEnt = pDirEnt;
+                            bEnd = true;
+                        }
+                    }
+                } else {
+                    bSuccess = true;
+                    sFileFindInfo.pDirEnt = pDirEnt;
+                    bEnd = true;
+                }
+            }
+        }
+    }
+
+    return bSuccess;
+}
+
+sclboolean
+CSCLUtilsImplLinux::find_next_file(FILEFINDINFO &sFileFindInfo, const sclchar *szSuffix)
+{
+    sclboolean bSuccess = false;
+
+    if (sFileFindInfo.pDirInfo) {
+        sclboolean bEnd = false;
+        while (!bEnd) {
+            struct dirent *pDirEnt = readdir(sFileFindInfo.pDirInfo);
+            if (NULL == pDirEnt) {
+                bEnd = true;
+            } else {
+                if (szSuffix) {
+                    if (strlen(szSuffix) <= strlen(pDirEnt->d_name)) {
+                        if (strcmp(pDirEnt->d_name + strlen(pDirEnt->d_name) - strlen(szSuffix), szSuffix) == 0) {
+                            bSuccess = true;
+                            sFileFindInfo.pDirEnt = pDirEnt;
+                            bEnd = true;
+                        }
+                    }
+                } else {
+                    bSuccess = true;
+                    sFileFindInfo.pDirEnt = pDirEnt;
+                    bEnd = true;
+                }
+            }
+        }
+    }
+
+    return bSuccess;
+}
+*/
diff --git a/scl/sclutils.cpp b/scl/sclutils.cpp
new file mode 100644 (file)
index 0000000..fb8fefb
--- /dev/null
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 2012 - 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 <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <math.h>
+#include <stdarg.h>
+
+#include "sclutils.h"
+#include "sclconfig.h"
+#include "scldebug.h"
+#include "sclcontext.h"
+#include "sclresource.h"
+#include "sclresourcecache.h"
+#include "sclres_manager.h"
+
+using namespace scl;
+
+#define SCL_MAX_UNIQUE_ID 1000
+
+CSCLUtils::CSCLUtils()
+{
+    SCL_DEBUG();
+    m_scn_rate_x = 1.0f;
+    m_scn_rate_y = 1.0f;
+    m_custom_scale_rate_x = 1.0f;
+    m_custom_scale_rate_y = 1.0f;
+    m_scn_resolution_x = 0;
+    m_scn_resolution_y = 0;
+}
+
+CSCLUtils::~CSCLUtils()
+{
+    SCL_DEBUG();
+}
+
+CSCLUtils* CSCLUtils::get_instance()
+{
+    static CSCLUtils instance;
+    return &instance;
+}
+
+void
+CSCLUtils::init()
+{
+    SCL_DEBUG();
+
+    CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+    if (impl) {
+        impl->init();
+    }
+
+    update_scale_rate_values();
+
+    m_nine_patch_info_map.clear();
+}
+
+void CSCLUtils::fini()
+{
+    SCL_DEBUG();
+
+    CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+    if (impl) {
+        impl->fini();
+    }
+}
+
+/**
+ * Returns a scale rate (see default screen resolution in sclconfig.h file)
+ */
+sclfloat
+CSCLUtils::get_smallest_scale_rate()
+{
+    /* Try to return smaller scale rate, to avoid UI crash */
+    return (m_scn_rate_x < m_scn_rate_y ) ? m_scn_rate_x : m_scn_rate_y ;
+}
+
+/**
+* Returns a scale rate X (see default screen resolution in sclconfig.h file)
+*/
+sclfloat
+CSCLUtils::get_scale_rate_x()
+{
+    /* Try to return smaller scale rate, to avoid UI crash */
+    return m_scn_rate_x;
+}
+
+/**
+* Returns a scale rate Y (see default screen resolution in sclconfig.h file)
+*/
+sclfloat
+CSCLUtils::get_scale_rate_y()
+{
+    /* Try to return smaller scale rate, to avoid UI crash */
+    return m_scn_rate_y;
+}
+
+/**
+ * Recalculates x value according to the current screen resolution
+ */
+void
+CSCLUtils::scale_x(scl16 *x)
+{
+    if (x) (*x) *= m_scn_rate_x;
+}
+
+/**
+* Recalculates y value according to the current screen resolution
+ */
+void
+CSCLUtils::scale_y(scl16 *y)
+{
+    if (y) (*y) *= m_scn_rate_y;
+}
+
+/**
+ * Returns a calculated x value according to the current screen resolution
+ */
+scl16
+CSCLUtils::get_scaled_x(scl16 x)
+{
+    return static_cast<scl16>(x * m_scn_rate_x);
+}
+
+/**
+ * Returns a calculated y value according to the current screen resolution
+ */
+scl16
+CSCLUtils::get_scaled_y(scl16 y)
+{
+    return static_cast<scl16>(y * m_scn_rate_y);
+}
+
+/**
+ * Returns the smallest custom scale rate
+ */
+sclfloat
+CSCLUtils::get_smallest_custom_scale_rate()
+{
+    /* Try to return smaller scale rate, to avoid UI crash */
+    return (m_custom_scale_rate_x < m_custom_scale_rate_y) ? m_custom_scale_rate_x : m_custom_scale_rate_y;
+}
+
+/**
+* Returns the current custom scale rate X
+*/
+sclfloat
+CSCLUtils::get_custom_scale_rate_x()
+{
+    return m_custom_scale_rate_x;
+}
+
+/**
+* Returns the current custom scale rate Y
+*/
+sclfloat
+CSCLUtils::get_custom_scale_rate_y()
+{
+    return m_custom_scale_rate_y;
+}
+
+void
+CSCLUtils::set_custom_scale_rate_x(sclfloat x)
+{
+    if (x > 0.0f) {
+        m_custom_scale_rate_x = x;
+    }
+}
+
+void
+CSCLUtils::set_custom_scale_rate_y(sclfloat y)
+{
+    if (y > 0.0f) {
+        m_custom_scale_rate_y = y;
+    }
+}
+
+/**
+ * portable sleep function
+ */
+sclboolean
+CSCLUtils::sleep(sclulong msc)
+{
+    SCL_DEBUG();
+    fd_set dummy;
+    struct timeval interval;
+    FD_ZERO(&dummy);
+    interval.tv_sec = msc / 1000;
+    interval.tv_usec = (msc % 1000) * 1000;
+    select(0, &dummy, NULL, NULL, &interval);
+    return TRUE;
+}
+
+/* FIXME : let's just look for appropriate directory once and cache it
+           and one more thing, let's find a closest resolution when caching the appropriate directory
+*/
+/**
+ * returns the composed path
+ */
+sclchar*
+CSCLUtils::get_composed_path(sclchar* buf, const sclchar* prefix, const sclchar* path)
+{
+    SCL_DEBUG();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (buf && path && sclres_manager) {
+        const sclchar *base_path = "";
+        PSclDefaultConfigure default_configure = sclres_manager->get_default_configure();
+        if (default_configure) {
+            if (default_configure->image_file_base_path) {
+                base_path = default_configure->image_file_base_path;
+            }
+        }
+
+        if (path[0] == '/')
+            snprintf(buf, _POSIX_PATH_MAX, "%s", path);
+        else
+            snprintf(buf, _POSIX_PATH_MAX, "%s/%s/%s/%s",
+                sclres_manager->get_resource_directory(), base_path, IMG_PATH_PREFIX, path);
+    }
+
+    return buf;
+}
+
+/**
+ * returns the decomposed path
+ */
+sclchar*
+CSCLUtils::get_decomposed_path(sclchar* buf, const sclchar* prefix, const sclchar* path)
+{
+    SCL_DEBUG();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (buf && path && sclres_manager) {
+        sclchar comparand[_POSIX_PATH_MAX];
+
+        snprintf(comparand, _POSIX_PATH_MAX, "%s/%s/",
+            sclres_manager->get_resource_directory(), IMG_PATH_PREFIX);
+        if (strncmp(path, comparand, strlen(comparand)) == 0) {
+            snprintf(buf, _POSIX_PATH_MAX, "%s", path + strlen(comparand));
+        } else {
+            snprintf(buf, _POSIX_PATH_MAX, "%s", path);
+        }
+    }
+
+    return buf;
+}
+
+sclboolean
+CSCLUtils::get_autopopup_window_variables(sclchar * const autopopup_keys[MAX_SIZE_OF_AUTOPOPUP_STRING], sclbyte *num_keys, sclbyte *num_columns, sclbyte *num_rows, sclint *width, sclint *height)
+{
+    SCL_DEBUG();
+    scl_assert_return_false(autopopup_keys);
+    scl_assert_return_false(num_keys && num_columns && num_rows && width && height);
+
+    int loop;
+    sclboolean ret = FALSE;
+    sclint scrx, scry;
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    PSclAutoPopupConfigure autopopup_configure = NULL;
+    if (sclres_manager) {
+        autopopup_configure = sclres_manager->get_autopopup_configure();
+    }
+    if (autopopup_configure && autopopup_keys && num_keys && num_columns && num_rows && width && height) {
+        *num_keys = 0;
+        for (loop = 0;loop < MAX_SIZE_OF_AUTOPOPUP_STRING;loop++) {
+            if (autopopup_keys[loop]) {
+                if (strlen(autopopup_keys[loop]) > 0) {
+                    (*num_keys)++;
+                }
+            }
+        }
+        if (*num_keys > 0) {
+            ret = TRUE;
+        }
+
+        this->get_screen_resolution(&scrx, &scry);
+
+        CSCLContext *context = CSCLContext::get_instance();
+        if (context && context->get_display_mode() == DISPLAYMODE_LANDSCAPE) {
+            int  swap = scrx;
+            scrx = scry;
+            scry = swap;
+        }
+
+        *num_columns = (scrx - (2 * autopopup_configure->bg_padding * get_smallest_custom_scale_rate())) /
+                      (autopopup_configure->button_width * get_smallest_custom_scale_rate() +
+                      autopopup_configure->button_spacing * get_smallest_custom_scale_rate());
+        if (*num_columns > autopopup_configure->max_column && autopopup_configure->max_column > 0)
+            *num_columns = autopopup_configure->max_column;
+        *num_rows = ((*num_keys - 1) / *num_columns) + 1;
+        if (*num_columns > *num_keys) *num_columns = *num_keys;
+
+        /* Try to spread evenly on each lines */
+        *num_columns = (*num_keys) / (*num_rows);
+        if ((*num_keys) % *num_rows != 0) (*num_columns)++;
+
+        *width =
+            (*num_columns * autopopup_configure->button_width * get_custom_scale_rate_x()) +
+            (2 * autopopup_configure->bg_padding * get_smallest_custom_scale_rate()) +
+            ((*num_columns - 1) * autopopup_configure->button_spacing * get_smallest_custom_scale_rate());
+        *height =
+            (*num_rows * autopopup_configure->button_height * get_custom_scale_rate_y()) +
+            (2 * autopopup_configure->bg_padding * get_smallest_custom_scale_rate()) +
+            ((*num_rows - 1) * autopopup_configure->button_spacing * get_smallest_custom_scale_rate());
+
+        *width += (2 * autopopup_configure->decoration_size * get_smallest_custom_scale_rate());
+        *height += (2 * autopopup_configure->decoration_size * get_smallest_custom_scale_rate());
+    }
+
+    return ret;
+}
+
+/**
+ * Returns a duplicated string pointer by given str
+ */
+sclchar*
+CSCLUtils::get_str_dup(const sclchar* str)
+{
+    SCL_DEBUG();
+    sclchar *new_str;
+    sclint length;
+
+    if (str) {
+        length = strlen(str) + 1;
+        new_str = (sclchar*)malloc(length);
+        if (new_str) {
+            memcpy(new_str, str, length);
+            new_str[length - 1] = '\0';
+        }
+    } else {
+        new_str = NULL;
+    }
+
+    return new_str;
+}
+
+/**
+ * Returns an unique ID
+ */
+scl16
+CSCLUtils::get_unique_id()
+{
+    SCL_DEBUG();
+    static scl16 uniId = 0;
+    if (uniId < SCL_MAX_UNIQUE_ID) {
+        uniId++;
+    } else {
+        uniId = 0;
+    }
+    return uniId;
+}
+
+sclboolean
+CSCLUtils::is_rect_overlap(SclRectangle rect1, SclRectangle rect2)
+{
+    if (rect1.x < rect2.x + rect2.width && rect1.x + rect1.width > rect2.x &&
+            rect1.y < rect2.y + rect2.height && rect1.y + rect1.height > rect2.y) {
+        /*if (rect1.x == rect2.x && rect1.width == rect2.width &&
+                rect1.y == rect2.y && rect1.height == rect2.height) {*/
+        return true;
+    }
+    return false;
+}
+
+sclfloat
+CSCLUtils::get_distance(sclint x1, sclint y1, sclint x2, sclint y2)
+{
+    sclint dx = x1 - x2;
+    sclint dy = y1 - y2;
+    return sqrt((dx * dx) + (dy * dy));
+}
+
+sclfloat
+CSCLUtils::get_distance(SclPoint pt1, SclPoint pt2)
+{
+    return get_distance(pt1.x, pt1.y, pt2.x, pt2.y);
+}
+
+sclfloat
+CSCLUtils::get_approximate_distance(sclint x1, sclint y1, sclint x2, sclint y2)
+{
+    sclint dx = abs(x1 - x2);
+    sclint dy = abs(y1 - y2);
+    return dx + dy;
+}
+
+sclfloat
+CSCLUtils::get_approximate_distance(SclPoint pt1, SclPoint pt2)
+{
+    return get_approximate_distance(pt1.x, pt1.y, pt2.x, pt2.y);
+}
+
+const SclNinePatchInfo*
+CSCLUtils::get_nine_patch_info(const sclchar *image_path)
+{
+    SCL_DEBUG();
+
+    /* FIXME - Let's fix this function not to use static */
+    static SclNinePatchInfo ret;
+    if (!image_path) return NULL;
+
+    sclchar buf[_POSIX_PATH_MAX] = {0};
+    sclboolean finished = FALSE;
+    //get_decomposed_path(buf, IMG_PATH_PREFIX, image_path);
+    for (sclint loop = strlen(image_path);!finished && loop > 0;loop--) {
+        if (image_path[loop] == '\\' || image_path[loop] == '/') {
+            strncpy(buf, image_path + loop + 1, _POSIX_PATH_MAX - 1);
+            finished = TRUE;
+        }
+    }
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (sclres_manager) {
+        if (sclres_manager->get_nine_patch_info(buf, &ret)) {
+            return &ret;
+        }
+    }
+
+    return NULL;
+}
+
+sclint CSCLUtils::log(const sclchar *fmt, ...)
+{
+    SCL_DEBUG();
+    va_list argptr;
+    sclint ret = 0;
+
+    va_start(argptr, fmt);
+    CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+    if (impl) {
+        char buf[_POSIX_PATH_MAX] = {0};
+        vsnprintf(buf, _POSIX_PATH_MAX - 1, fmt, argptr);
+        ret = impl->log(buf);
+    }
+    va_end(argptr);
+
+    return ret;
+}
+
+void CSCLUtils::update_scale_rate_values()
+{
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    PSclDefaultConfigure default_configure = NULL;
+    if (sclres_manager) {
+        default_configure = sclres_manager->get_default_configure();
+    }
+
+    if (default_configure) {
+        scl_assert(default_configure->target_screen_width);
+        scl_assert(default_configure->target_screen_height);
+        if (default_configure->target_screen_width != 0 && default_configure->target_screen_height != 0) {
+            CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+            if (impl)
+                impl->get_screen_resolution(&m_scn_resolution_x, &m_scn_resolution_y);
+
+            m_scn_rate_x = m_scn_resolution_x / (float)default_configure->target_screen_width;
+            m_scn_rate_y = m_scn_resolution_y / (float)default_configure->target_screen_height;
+
+            if (default_configure->auto_detect_landscape) {
+                /* If the width of screen is bigger than the height, switch portrait mode and landscape mode */
+                if (m_scn_resolution_x > m_scn_resolution_y) {
+                    m_scn_rate_x = m_scn_resolution_x / (float)default_configure->target_screen_height;
+                    m_scn_rate_y = m_scn_resolution_y / (float)default_configure->target_screen_width;
+                }
+            }
+        }
+    }
+}
+
+sclboolean CSCLUtils::update_screen_resolution()
+{
+    sclboolean ret = FALSE;
+    CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+    if (impl) {
+        ret = impl->update_screen_resolution();
+    }
+    if (ret) {
+        update_scale_rate_values();
+    }
+    return ret;
+}
+
+_CSCLUtils::_CSCLUtils()
+{
+    m_impl = 0;
+}
+
+void _CSCLUtils::init()
+{
+    CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+    if (impl) {
+        impl->init();
+    }
+}
+
+void _CSCLUtils::fini()
+{
+    CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+    if (impl) {
+        impl->fini();
+    }
+}
+
+sclboolean _CSCLUtils::get_screen_resolution(sclint *x, sclint *y)
+{
+    sclboolean ret = FALSE;
+    CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+    if (impl) {
+        ret = impl->get_screen_resolution(x, y);
+    }
+    return ret;
+}
+
+sclboolean _CSCLUtils::update_screen_resolution()
+{
+    sclboolean ret = FALSE;
+    CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+    if (impl) {
+        ret = impl->update_screen_resolution();
+    }
+    return ret;
+}
+
+sclboolean _CSCLUtils::play_tts(const sclchar *str)
+{
+    sclboolean ret = FALSE;
+    CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+    if (impl) {
+        ret = impl->play_tts(str);
+    }
+    return ret;
+}
+
+sclboolean _CSCLUtils::play_sound(const sclchar* snd_style)
+{
+    sclboolean ret = FALSE;
+    CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+    if (impl) {
+        ret = impl->play_sound(snd_style);
+    }
+    return ret;
+}
+
+sclboolean _CSCLUtils::play_vibration(const sclchar* vibe_style, const scllong duration)
+{
+    sclboolean ret = FALSE;
+    CSCLUtilsImpl *impl = GetCSCLUtilsImpl();
+    if (impl) {
+        ret = impl->play_vibration(vibe_style, duration);
+    }
+    return ret;
+}
+
+CSCLUtilsImpl* _CSCLUtils::GetCSCLUtilsImpl()
+{
+    if (m_impl == 0) {
+#ifdef  __WIN32__
+        m_impl = new CSCLUtilsImplWin32;
+#else
+        m_impl = new CSCLUtilsImplLinux;
+#endif
+    }
+    return m_impl;
+}
diff --git a/scl/sclutils.h b/scl/sclutils.h
new file mode 100644 (file)
index 0000000..2f7aa1c
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <map>
+
+#include "scltypes.h"
+#include "sclconfig.h"
+#include "sclstructs.h"
+
+#ifndef __SCL_UTILS_H__
+#define __SCL_UTILS_H__
+
+#ifdef __cplusplus
+//SCL_BEGIN_DECLS
+#endif
+
+#ifndef _POSIX_PATH_MAX
+#define _POSIX_PATH_MAX 255
+#endif
+
+namespace scl
+{
+
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLUtilsImpl
+{
+public :
+    CSCLUtilsImpl() { m_scr_size.width = 0;m_scr_size.height = 0; }
+
+    virtual void init() = 0;
+    virtual void fini() = 0;
+
+    virtual sclboolean get_screen_resolution(sclint *x, sclint *y) = 0;
+    virtual sclboolean update_screen_resolution() = 0;
+    virtual sclboolean play_tts(const sclchar *str) = 0;
+    virtual sclboolean play_sound(const sclchar* snd_style) = 0;
+    virtual sclboolean play_vibration(const sclchar* vibe_style, const scllong duration) = 0;
+
+    virtual sclboolean open_devices() = 0;
+    virtual sclboolean close_devices() = 0;
+
+    virtual sclint log(const sclchar *msg) = 0;
+
+protected:
+    SclSize m_scr_size;
+};
+
+class CSCLUtilsImplLinux : public CSCLUtilsImpl
+{
+public :
+    void init();
+    void fini();
+
+    sclboolean get_screen_resolution(sclint *x, sclint *y);
+    sclboolean update_screen_resolution();
+    sclboolean play_tts(const sclchar *str);
+    sclboolean play_sound(const sclchar* snd_style);
+    sclboolean play_vibration(const sclchar* vibe_style, const scllong duration);
+
+    sclboolean open_devices();
+    sclboolean close_devices();
+
+    sclint log(const sclchar *msg);
+};
+
+class CSCLUtilsImplWin32 : public CSCLUtilsImpl
+{
+public :
+    void init();
+    void fini();
+
+    sclboolean get_screen_resolution(sclint *x, sclint *y);
+    sclboolean update_screen_resolution();
+    sclboolean play_tts(const sclchar *str);
+    sclboolean play_sound(const sclchar* snd_style);
+    sclboolean play_vibration(const sclchar* vibe_style, const scllong duration);
+
+    sclboolean open_devices();
+    sclboolean close_devices();
+
+    sclint log(const sclchar *msg);
+};
+
+class _CSCLUtils
+{
+public :
+    _CSCLUtils();
+
+    virtual void init();
+    virtual void fini();
+    virtual sclboolean get_screen_resolution(sclint *x, sclint *y);
+    virtual sclboolean update_screen_resolution();
+    virtual sclboolean play_tts(const sclchar *str);
+    virtual sclboolean play_sound(const sclchar* snd_style);
+    virtual sclboolean play_vibration(const sclchar* vibe_style, const scllong duration);
+protected :
+    CSCLUtilsImpl* GetCSCLUtilsImpl();
+
+private :
+    CSCLUtilsImpl* m_impl;
+};
+
+class EXAPI CSCLUtils : public _CSCLUtils
+{
+private:
+    CSCLUtils();
+public :
+    virtual ~CSCLUtils();
+
+    static CSCLUtils* get_instance();
+
+    void init();
+    void fini();
+
+    void scale_x(scl16 *x);
+    void scale_y(scl16 *y);
+    scl16 get_scaled_x(scl16 x);
+    scl16 get_scaled_y(scl16 y);
+    sclfloat get_smallest_scale_rate();
+    sclfloat get_scale_rate_x();
+    sclfloat get_scale_rate_y();
+    sclfloat get_smallest_custom_scale_rate();
+    sclfloat get_custom_scale_rate_x();
+    sclfloat get_custom_scale_rate_y();
+
+    void set_custom_scale_rate_x(sclfloat x);
+    void set_custom_scale_rate_y(sclfloat y);
+
+    sclchar* get_str_dup(const sclchar* str);
+
+    sclboolean sleep(sclulong msc);
+
+    sclchar* get_composed_path(sclchar* buf, const sclchar* prefix, const sclchar* path);
+    sclchar* get_decomposed_path(sclchar* buf, const sclchar* prefix, const sclchar* path);
+    const SclNinePatchInfo* get_nine_patch_info(const sclchar *image_path);
+
+    sclboolean get_autopopup_window_variables(sclchar * const autopopup_keys[MAX_SIZE_OF_AUTOPOPUP_STRING], sclbyte *num_keys,
+        sclbyte *num_columns, sclbyte *num_rows, sclint *width, sclint *height);
+
+    scl16 get_unique_id();
+
+    sclboolean is_rect_overlap(SclRectangle rect1, SclRectangle rect2);
+    sclfloat get_distance(sclint x1, sclint y1, sclint x2, sclint y2);
+    sclfloat get_distance(SclPoint pt1, SclPoint pt2);
+
+    sclfloat get_approximate_distance(sclint x1, sclint y1, sclint x2, sclint y2);
+    sclfloat get_approximate_distance(SclPoint pt1, SclPoint pt2);
+
+    sclint log(const sclchar *fmt, ...);
+
+    void update_scale_rate_values();
+    sclboolean update_screen_resolution();
+private :
+    sclfloat m_scn_rate_x;
+    sclfloat m_scn_rate_y;
+
+    sclfloat m_custom_scale_rate_x;
+    sclfloat m_custom_scale_rate_y;
+
+    sclint m_scn_resolution_x;
+    sclint m_scn_resolution_y;
+
+    std::map<sclchar*, SclNinePatchInfo> m_nine_patch_info_map;
+};
+
+
+} /* End of scl namespace */
+
+#ifdef __cplusplus
+//SCL_END_DECLS
+#endif
+
+#endif //__SCL_UTILS_H__
diff --git a/scl/sclversion.h b/scl/sclversion.h
new file mode 100644 (file)
index 0000000..a879b22
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 - 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 __SCL_VERSION_H__
+#define __SCL_VERSION_H__
+
+#define SCL_VERSION "0.5.0-1"
+
+#endif //__SCL_VERSION_H
+
+/*
+Version History
+    0.1.1-1
+        - Started recording version information of SCL library
+    0.1.2-1
+        - Modified the autopopup layout generation code for fulfilling UX requirement
+    0.1.3-1
+        - Modified the private key to be set only by custom id and skip default values
+    0.1.4-1
+        - Modified to send key events in autopopup layout when possible
+    0.1.5-1
+        - Modified type for the variable inner_width from sclbyte to sclint
+    0.1.6-1
+        - Fixed the bug that longkey behaves incorrectly with multi-touch events
+    0.1.7-1
+        - Minor changes for tizen 2.0 open
+    0.1.8-1
+        - Modified the EFL backend to call elm_win_raise() for popup windows as well
+       0.2.2-1
+               - Implemented synchronization feature with window manager
+*/
diff --git a/scl/sclwindowbackendcallback.h b/scl/sclwindowbackendcallback.h
new file mode 100644 (file)
index 0000000..a7b7d10
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021 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 __SCL_WINDOW_BACKENDCALLBACK_H__
+#define __SCL_WINDOW_BACKENDCALLBACK_H__
+
+using namespace scl;
+
+//SCL_BEGIN_DECLS
+/* FIXME : Need to check the dependency cause by the next include statement */
+
+struct ISCLUIWindowBackendCallback {
+    virtual void update_window(int x, int w, int width, int height, void* user_data) { }
+
+};
+
+#endif //__SCL_WINDOW_BACKENDCALLBACK_H__
diff --git a/scl/sclwindows-nui.cpp b/scl/sclwindows-nui.cpp
new file mode 100644 (file)
index 0000000..0ebe443
--- /dev/null
@@ -0,0 +1,1127 @@
+/*
+ * Copyright (c) 2012 - 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 "sclwindows-nui.h"
+#include "scldebug.h"
+#include "sclcontroller.h"
+#include "sclcontext.h"
+#include "sclresourcecache.h"
+#include "scluibuilder.h"
+#include "sclwindows.h"
+#include "sclres_manager.h"
+
+#include <glib.h>
+#include <Elementary.h>
+#include <malloc.h>
+#ifdef WAYLAND
+#define EFL_BETA_API_SUPPORT
+#include <Ecore_Wl2.h>
+#else
+#include <Ecore_X.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#endif
+#include <dlog.h>
+#include "sclkeyfocushandler.h"
+
+using namespace scl;
+
+#ifndef WAYLAND
+static Ecore_X_Atom ATOM_WM_CLASS = 0;
+static Ecore_X_Window app_window = 0;
+#endif
+
+const sclint rotation_values_EFL[ROTATION_MAX] = {
+    0, // ROTATION_0
+    90, // ROTATION_90_CW
+    180, // ROTATION_180
+    270, // ROTATION_90_CCW
+};
+
+#include "sclgraphics-nui.h"
+#ifdef TEST_NEWBACKEND
+#include <Ecore_Evas.h>
+#include <Ecore.h>
+#include <vector>
+extern std::vector<ImageCache> g_ImageCache;
+extern std::vector<TextCache> g_TextCache;
+#else
+#endif
+
+/* When the base window is resized, any mouse events generated before this timestamp value
+ * that are waiting in the event queue, could be considered as outdated so we are going to
+ * skip those events */
+unsigned int g_timestamp_last_base_window_resized = 0;
+
+/**
+ * Constructor
+ */
+CSCLWindowsImplNui::CSCLWindowsImplNui()
+{
+    SCL_DEBUG();
+#ifndef WAYLAND
+    /* Initializes all window resources */
+    ATOM_WM_CLASS = ecore_x_atom_get("WM_CLASS");
+#endif
+
+    m_window_backend_callback = NULL;
+    m_window_backend_callback_data = NULL;
+}
+
+/**
+ * De-constructor
+ */
+CSCLWindowsImplNui::~CSCLWindowsImplNui()
+{
+    SCL_DEBUG();
+}
+
+static void window_show_cb(void *data, Evas *e, Evas_Object *obj, void *event)
+{
+    LOGD("INSIDE =-=-=-=- window_show_cb, Trying to Grab Key Board : \n");
+#ifdef USING_KEY_GRAB
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+
+    if (windows && focus_handler)
+        focus_handler->grab_keyboard(windows->get_base_window());
+#endif
+}
+
+void CSCLWindowsImplNui::init()
+{
+}
+
+void CSCLWindowsImplNui::fini()
+{
+}
+
+/**
+ * Create a content window and binds it into given parent window as a child
+ */
+sclwindow
+CSCLWindowsImplNui::create_base_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    sclwindow ret = SCLWINDOW_INVALID;
+
+    if (window_context) {
+        window_context->etc_info = NULL;
+        window_context->window = parent;
+
+        //Adding window show event handler
+        evas_object_event_callback_add(static_cast<Evas_Object*>(parent), EVAS_CALLBACK_SHOW, window_show_cb, NULL);
+
+        set_window_accepts_focus(parent, FALSE);
+
+#ifndef WAYLAND
+        ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast<Evas_Object*>(parent)), "Virtual Keyboard", "ISF");
+#endif
+
+        ret = window_context->window;
+    }
+
+    int rots[4] = {0, 90, 180, 270};
+    elm_win_wm_rotation_available_rotations_set(static_cast<Evas_Object*>(parent), rots, 4);
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    if (utils) {
+        utils->log("WinNui_createbasewin %p, %d %d\n",
+                parent, width, height);
+    }
+    return ret;
+}
+
+/**
+ * Creates a window
+ */
+sclwindow
+CSCLWindowsImplNui::create_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    Evas_Object *win = NULL;
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    win = elm_win_add(static_cast<Evas_Object*>(parent), "SCLPopup", ELM_WIN_UTILITY);
+
+    elm_win_borderless_set(win, EINA_TRUE);
+    elm_win_alpha_set(win, EINA_TRUE);
+    elm_win_title_set(win, "ISF Popup");
+
+    set_window_accepts_focus(win, FALSE);
+
+    int rots[4] = {0, 90, 180, 270};
+    elm_win_wm_rotation_available_rotations_set(win, rots, 4);
+
+    scl16 new_width = 0;
+    scl16 new_height = 0;
+    CSCLContext *context = CSCLContext::get_instance();
+    if (context) {
+        if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) {
+            new_width = height;
+            new_height = width;
+        } else {
+            new_width = width;
+            new_height = height;
+        }
+    }
+
+#ifndef FULL_SCREEN_TEST
+    //evas_object_resize(win, width, height);
+#endif
+
+#ifdef WAYLAND
+    Ecore_Wl2_Window *wl_window = (Ecore_Wl2_Window *)(elm_win_wl_window_get(win));
+    ecore_wl2_window_rotation_geometry_set(wl_window,
+        rotation_values_EFL[ROTATION_0], 0, 0, new_width, new_height);
+    ecore_wl2_window_rotation_geometry_set(wl_window,
+        rotation_values_EFL[ROTATION_90_CW], 0, 0, new_width, new_height);
+    ecore_wl2_window_rotation_geometry_set(wl_window,
+        rotation_values_EFL[ROTATION_180], 0, 0, new_width, new_height);
+    ecore_wl2_window_rotation_geometry_set(wl_window,
+        rotation_values_EFL[ROTATION_90_CCW], 0, 0, new_width, new_height);
+#else
+    /*
+    ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
+        rotation_values_EFL[ROTATION_0], 0, 0, new_width, new_height);
+    ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
+        rotation_values_EFL[ROTATION_90_CW], 0, 0, new_width, new_height);
+    ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
+        rotation_values_EFL[ROTATION_180], 0, 0, new_width, new_height);
+    ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
+        rotation_values_EFL[ROTATION_90_CCW], 0, 0, new_width, new_height);
+    */
+    ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), "ISF Popup", "ISF");
+
+    Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE  = 0;
+    unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect
+
+    ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE");
+    if (ATOM_WINDOW_EFFECT_ENABLE) {
+        ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1);
+    } else {
+        if (utils) {
+            utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n");
+        }
+    }
+#endif
+
+    if (context)
+        set_window_rotation(win, context->get_rotation());
+
+    //elm_win_override_set(win, EINA_TRUE);
+    if (utils) {
+        utils->log("WinNui_createwin %p, %d %d\n",
+                win, width, height);
+    }
+    return win;
+}
+
+
+/**
+* Creates a window
+*/
+sclwindow
+CSCLWindowsImplNui::create_magnifier_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    Evas_Object *win = NULL;
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    // FIXME
+#if 0
+    win = elm_win_add(static_cast<Evas_Object*>(parent), "Magnifier", ELM_WIN_UTILITY);
+    LOGD("Created magnifier window %p, using parent %p", win, parent);
+
+    elm_win_borderless_set(win, EINA_TRUE);
+    elm_win_alpha_set(win, EINA_TRUE);
+    elm_win_title_set(win, "ISF Magnifier");
+
+    /* We are not going to accept mouse events for magnifier window */
+    Eina_Rectangle rect_unset = { -1, -1, 1, 1 };
+    elm_win_input_rect_set(win, &rect_unset);
+
+    set_window_accepts_focus(win, FALSE);
+
+    int rots[4] = { 0, 90, 180, 270 };
+    elm_win_wm_rotation_available_rotations_set(win, rots, 4);
+
+#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    sclint scrx, scry, winx, winy;
+    if (windows && utils) {
+        utils->get_screen_resolution(&scrx, &scry);
+        SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());
+        if (window_context) evas_object_resize(win, scrx, height + window_context->height);
+    }
+#endif
+
+#ifdef WAYLAND
+    Ecore_Wl2_Window *wl_window = (Ecore_Wl2_Window *)(elm_win_wl_window_get(win));
+    ecore_wl2_window_rotation_geometry_set(wl_window,
+        rotation_values_EFL[ROTATION_0], 0, 0, width, height);
+    ecore_wl2_window_rotation_geometry_set(wl_window,
+        rotation_values_EFL[ROTATION_90_CW], 0, 0, height, width);
+    ecore_wl2_window_rotation_geometry_set(wl_window,
+        rotation_values_EFL[ROTATION_180], 0, 0, width, height);
+    ecore_wl2_window_rotation_geometry_set(wl_window,
+        rotation_values_EFL[ROTATION_90_CCW], 0, 0, height, width);
+#else
+    /*
+    ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
+        rotation_values_EFL[ROTATION_0], 0, 0, width, height);
+    ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
+        rotation_values_EFL[ROTATION_90_CW], 0, 0, height, width);
+    ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
+        rotation_values_EFL[ROTATION_180], 0, 0, width, height);
+    ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win),
+        rotation_values_EFL[ROTATION_90_CCW], 0, 0, height, width);
+    */
+    ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), "Key Magnifier", "ISF");
+    Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE  = 0;
+    unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect
+    ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE");
+    if (ATOM_WINDOW_EFFECT_ENABLE) {
+        ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1);
+    } else {
+        if (utils) {
+            utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n");
+        }
+    }
+#endif
+
+    CSCLContext *context = CSCLContext::get_instance();
+    if (context)
+        set_window_rotation(win, context->get_rotation());
+#endif
+
+    if (utils) {
+        utils->log("WinNui_createmagwin %p, %d %d\n",
+            win, width, height);
+    }
+
+    return win;
+}
+
+/**
+ * Creates the dim window
+ */
+sclwindow
+CSCLWindowsImplNui::create_dim_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    Evas_Object *win = NULL;
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    win = elm_win_add(static_cast<Evas_Object*>(parent), "SCLPopup", ELM_WIN_UTILITY);
+
+    elm_win_borderless_set(win, EINA_TRUE);
+    elm_win_alpha_set(win, EINA_TRUE);
+    elm_win_title_set(win, "ISF Dim");
+
+    evas_object_resize(win, width, height);
+
+    int rots[4] = {0, 90, 180, 270};
+    elm_win_wm_rotation_available_rotations_set(win, rots, 4);
+
+    set_window_accepts_focus(win, FALSE);
+
+#ifndef WAYLAND
+    ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), "ISF Popup", "ISF");
+
+    Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE  = 0;
+    unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect
+
+    ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE");
+    if (ATOM_WINDOW_EFFECT_ENABLE) {
+        ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast<Evas_Object*>(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1);
+    } else {
+        if (utils) {
+            utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n");
+        }
+    }
+#endif
+
+    CSCLContext *context = CSCLContext::get_instance();
+    if (context)
+        set_window_rotation(win, context->get_rotation());
+
+    /*Evas_Object *bg;
+    bg = elm_bg_add(win);
+    elm_win_resize_object_add(win, bg);
+    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    SclColor color = scl_dim_window_configure.dim_color;
+    evas_object_color_set(bg, color.r, color.g, color.b, color.a);
+    evas_object_show(bg);*/
+
+    hide_window(win);
+
+    if (utils) {
+        utils->log("WinNui_createdimwin %p, %d %d\n",
+            win, width, height);
+    }
+    return win;
+}
+
+/**
+ * Make a window relation between parent and child
+ * Caution: Currently, If we use transient_for them the ISE will occure some crash. It needs to check X11
+ */
+void
+CSCLWindowsImplNui::set_parent(const sclwindow parent, const sclwindow window)
+{
+    SCL_DEBUG();
+
+#ifndef WAYLAND
+    if (parent && window) {
+        ecore_x_icccm_transient_for_set(elm_win_xwindow_get(static_cast<Evas_Object*>(window)),
+                elm_win_xwindow_get(static_cast<Evas_Object*>(parent)));
+    }
+#endif
+}
+
+Eina_Bool destroy_later(void *data)
+{
+    evas_object_hide((Evas_Object*)data);
+    evas_object_del((Evas_Object*)data);
+    return ECORE_CALLBACK_CANCEL;
+}
+
+/**
+ * Destroys the given window
+ */
+bool
+CSCLWindowsImplNui::destroy_window(sclwindow window)
+{
+    SCL_DEBUG();
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    SclWindowContext *window_context = NULL;
+    if (windows && window && utils) {
+        window_context = windows->get_window_context(window);
+        if (window_context) {
+            utils->log("WinNui_destroywin %p %p (basewin %p mag %p)\n", window,
+                (!(window_context->is_virtual)) ? elm_win_xwindow_get(static_cast<Evas_Object*>(window)) : 0x01,
+                windows->get_base_window(), windows->get_magnifier_window());
+            if (window_context->etc_info) {
+                Eina_List *list = (Eina_List*)(window_context->etc_info);
+                Eina_List *iter = NULL;
+                Eina_List *iter_next = NULL;
+                void *data = NULL;
+
+                EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) {
+                    if (data) {
+                        EFLObject *object = (EFLObject*)(data);
+                        if (object) {
+                            Evas_Object* eo = object->object;
+                            if (object->extracted) {
+                                //evas_object_image_data_set(eo, NULL);
+                                void *image_data = evas_object_image_data_get(eo, 1);
+                                if (image_data) {
+                                    free(image_data);
+                                }
+                            }
+                            if (eo) {
+                                evas_object_del(eo);
+                                object->object = NULL;
+                            }
+                            if (object->type == EFLOBJECT_TEXTBLOCK) {
+                                Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data);
+                                if (st) {
+                                    evas_textblock_style_free(st);
+                                }
+#ifdef TEST_NEWBACKEND
+                                for (sclint loop = 0;loop < (sclint)g_TextCache.size();loop++) {
+                                    if (g_TextCache[loop].text == object->object) {
+                                        g_TextCache[loop].used = FALSE;
+                                    }
+                                }
+#endif
+                            } else if (object->type == EFLOBJECT_IMAGE) {
+#ifdef TEST_NEWBACKEND
+                                for (sclint loop = 0;loop < (sclint)g_ImageCache.size();loop++) {
+                                    if (g_ImageCache[loop].image == object->object) {
+                                        g_ImageCache[loop].used = FALSE;
+                                    }
+                                }
+#endif
+                            }
+                            delete object;
+                        }
+                    }
+                    list = eina_list_remove_list(list, iter);
+                }
+                window_context->etc_info = NULL;
+            }
+
+            if (!(window_context->is_virtual)) {
+                /* FIXME : A workaround for the bug that event on a window being hidden is delivered to
+                    e17, instead of the window itself or the window right below - Should report to WM */
+                if (window == windows->get_nth_popup_window(SCL_WINDOW_Z_TOP)) {
+                    ecore_timer_add(0.1f, destroy_later, (void*)window);
+                } else {
+                    Evas_Object *win = (Evas_Object*)window;
+                    evas_object_hide(win);
+                    evas_object_del(win);
+                }
+            }
+            utils->log("WinNui_destroywin %p (basewin %p mag %p)\n", window,
+                 windows->get_base_window(), windows->get_magnifier_window());
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * Shows the given window
+ */
+void
+CSCLWindowsImplNui::show_window(const sclwindow window, sclboolean queue)
+{
+    SCL_DEBUG();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    if (windows && context && window) {
+        SclWindowContext *window_context = windows->get_window_context(window);
+        if (!(context->get_hidden_state())) {
+            if (window_context) {
+                if (!(window_context->is_virtual)) {
+                    evas_object_show((Evas_Object*)window);
+                }
+
+                if (!(windows->get_update_pending())) {
+                    update_window(window);
+                }
+            }
+        }
+
+#ifndef WAYLAND
+        if (windows->get_base_window() == window) {
+            int  ret = 0;
+            Atom type_return;
+            int  format_return;
+            unsigned long    nitems_return;
+            unsigned long    bytes_after_return;
+            unsigned char   *data = NULL;
+
+            Ecore_X_Window win = elm_win_xwindow_get(static_cast<Evas_Object*>(window));
+            ret = XGetWindowProperty((Display *)ecore_x_display_get(),
+                    ecore_x_window_root_get(win),
+                    ecore_x_atom_get("_ISF_ACTIVE_WINDOW"),
+                    0, G_MAXLONG, False, XA_WINDOW, &type_return,
+                    &format_return, &nitems_return, &bytes_after_return,
+                    &data);
+
+            if (data) {
+                if (ret == Success) {
+                    if ((type_return == XA_WINDOW) && (format_return == 32) && (data)) {
+                        app_window = *(Window *)data;
+                    }
+                }
+                XFree(data);
+            }
+        }
+#endif
+        scl8 popup_index = windows->find_popup_window_index(window);
+        if (windows->get_magnifier_window() == window || popup_index != NOT_USED) {
+            /*
+             * FIXME a solution to make magnifier window always on top
+             * N_SE-17689: magnifier window showing behind of candidate window
+             *
+             * N_SE-52548: ...and modified if() for other popup windows as well...
+             */
+            if (window_context && !(window_context->is_virtual)) {
+#ifndef WAYLAND
+                ecore_x_icccm_transient_for_set
+                    (elm_win_xwindow_get(static_cast<Evas_Object*>(window)), app_window);
+#endif
+                elm_win_raise((Evas_Object *)window);
+            }
+        }
+
+        if (utils) {
+            utils->log("WinNui_showwin %p (basewin %p mag %p)\n",
+                window,
+                windows->get_base_window(), windows->get_magnifier_window());
+        }
+    }
+}
+
+/**
+ * Hides the given window
+ */
+void
+CSCLWindowsImplNui::hide_window(const sclwindow window,  sclboolean fForce)
+{
+    SCL_DEBUG();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    SclWindowContext *window_context = NULL;
+
+    if (windows && window) {
+#ifdef USING_KEY_GRAB
+    if (window == windows->get_base_window()) {
+        CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+        focus_handler->ungrab_keyboard(window);
+    }
+#endif
+
+        window_context = windows->get_window_context(window);
+        if (window_context) {
+            if (!(window_context->is_virtual)) {
+                Evas_Object *win = (Evas_Object*)window;
+                /* FIXME : A workaround for the bug that event on a window being hidden is delivered to
+                   e17, instead of the window itself or the window right below - Should report to WM */
+                if (window == windows->get_nth_popup_window(SCL_WINDOW_Z_TOP)) {
+                    evas_object_move(win, -10000, -10000);
+                } else {
+#ifdef WAYLAND
+                    /* Under wayland environment, the visibility of keyboard window is controlled by
+                     * wayland server, so it is not allowed to call evas_object_hide() for keyboard window
+                     * directly on the keyboard side */
+                    if (win != windows->get_base_window()) {
+                        evas_object_hide(win);
+                    }
+#else
+                    evas_object_hide(win);
+#endif
+                }
+            }
+        }
+    }
+
+    if (windows && utils && window) {
+        // Memory optimization */
+        if (window == windows->get_magnifier_window() || window == windows->get_dim_window()) {
+            if (window_context) {
+                if (window_context->etc_info) {
+#ifdef TEST_NEWBACKEND
+#else
+                    Eina_List *list = (Eina_List*)(window_context->etc_info);
+                    Eina_List *iter = NULL;
+                    Eina_List *iter_next = NULL;
+                    void *data = NULL;
+                    int iIndex = 0;
+                    EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) {
+                        if (data) {
+                            EFLObject *object = (EFLObject*)(data);
+                            if (object) {
+                                sclboolean bShouldRemove = FALSE;
+                                bShouldRemove = TRUE;
+                                if (bShouldRemove) {
+                                    Evas_Object* eo = object->object;
+                                    if (object->extracted) {
+                                        void *image_data = evas_object_image_data_get(eo, 1);
+                                        if (image_data) {
+                                            free(image_data);
+                                        }
+                                    }
+                                    if (eo) {
+                                        evas_object_del(eo);
+                                        object->object = NULL;
+                                    }
+                                    if (object->type == EFLOBJECT_TEXTBLOCK) {
+                                        Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data);
+                                        if (st) {
+                                            evas_textblock_style_free(st);
+                                        }
+#ifdef TEST_NEWBACKEND
+                                        for (sclint loop = 0;loop < g_TextCache.size();loop++) {
+                                            if (g_TextCache[loop].text == object->object) {
+                                                g_TextCache[loop].used = FALSE;
+                                            }
+                                        }
+#endif
+                                    } else if (object->type == EFLOBJECT_IMAGE) {
+#ifdef TEST_NEWBACKEND
+                                        for (sclint loop = 0;loop < g_ImageCache.size();loop++) {
+                                            if (g_ImageCache[loop].image == object->object) {
+                                                g_ImageCache[loop].used = FALSE;
+                                            }
+                                        }
+#endif
+                                    }
+                                    delete object;
+                                    list = eina_list_remove_list(list, iter);
+                                }
+                            }
+                            iIndex++;
+                        }
+                    }
+                    window_context->etc_info = list;
+#endif
+                }
+            }
+            //Evas *evas = evas_object_evas_get((Evas_Object*)window);
+            //evas_render_idle_flush(evas);
+        }
+        if (window == windows->get_base_window()) {
+            elm_cache_all_flush();
+            malloc_trim(0);
+        }
+        utils->log("WinNui_hidewin %p (basewin %p mag %p)\n",
+            window,
+            windows->get_base_window(), windows->get_magnifier_window());
+    }
+}
+
+/**
+ * Moves the window to the given position
+ */
+sclint magnifierx, magnifiery;
+void
+CSCLWindowsImplNui::move_window(const sclwindow window, scl16 x, scl16 y)
+{
+    SCL_DEBUG();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+
+    if (utils && context && windows && window) {
+        SclWindowContext *window_context = windows->get_window_context(window);
+        unsigned short win_width = 0;
+        unsigned short win_height = 0;
+        if (window_context) {
+            win_width = window_context->geometry.width;
+            win_height = window_context->geometry.height;
+        }
+
+        scl16 rotatex = x;
+        scl16 rotatey = y;
+        scl16 orgx = x;
+        scl16 orgy = y;
+
+        sclint scr_w, scr_h;
+        /* get window size */
+        utils->get_screen_resolution(&scr_w, &scr_h);
+
+#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW
+        if (window == windows->get_magnifier_window()) {
+            SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window(), FALSE);
+            rotatex = orgx = 0;
+            if (context->get_rotation_degree() == 90 || context->get_rotation_degree() == 270) {
+                rotatey = orgy = scr_w - base_window_context->height - win_height;
+                win_width = base_window_context->width;
+                win_height = base_window_context->height + win_height;
+            } else {
+                rotatey = orgy = scr_h - base_window_context->height - win_height;
+                win_width = base_window_context->width;
+                win_height = base_window_context->height + win_height;
+            }
+            magnifierx = x;
+            magnifiery = y - orgy;
+        }
+#endif
+
+        switch (context->get_rotation()) {
+            case ROTATION_90_CW: {
+                rotatex = orgy;
+                rotatey = scr_w - orgx - win_width;
+            }
+            break;
+            case ROTATION_180: {
+                rotatex = scr_w - orgx - win_width;
+                rotatey = scr_h - orgy - win_height;
+            }
+            break;
+            case ROTATION_90_CCW: {
+                rotatex = scr_h - orgy - win_height;
+                rotatey = orgx;
+            }
+            break;
+            case ROTATION_0: break;
+            default: break;
+        }
+
+    #ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW
+        if (window == windows->get_magnifier_window()) {
+            if (rotatex == window_context->x && rotatey == window_context->y) return;
+        }
+    #endif
+
+        Evas_Object *win = (Evas_Object*)window;
+#ifndef FULL_SCREEN_TEST
+        if (window != windows->get_base_window()) {
+            evas_object_move(win, rotatex, rotatey);
+        }
+#endif
+        //Evas_Object *window_object = (Evas_Object*)window;
+        //Evas *evas = evas_object_evas_get(window_object);
+        //evas_render_idle_flush(evas);
+
+        utils->log("WinNui_movewin %p %d %d %d %d (basewin %p mag %p)\n",
+            window,
+            x, y, rotatex, rotatey,
+            windows->get_base_window(), windows->get_magnifier_window());
+    }
+}
+
+/**
+* Resizes the window to the given metric
+*/
+void
+CSCLWindowsImplNui::resize_window(const sclwindow window, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    if (!windows || !utils) return;
+
+#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW
+    if (window == windows->get_magnifier_window()) {
+        SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());
+        if (window_context->width != width || window_context->height != height) {
+            sclint scrx, scry, winx, winy;
+            utils->get_screen_resolution(&scrx, &scry);
+            if (context->get_rotation_degree() == 90 || context->get_rotation_degree() == 270) {
+                evas_object_resize((Evas_Object*)window, scry, height + window_context->height);
+            } else {
+                evas_object_resize((Evas_Object*)window, scrx, height + window_context->height);
+            }
+        }
+        return;
+    }
+#endif
+
+    Evas_Object *win = (Evas_Object*)window;
+#ifndef FULL_SCREEN_TEST
+    if (windows && utils && window) {
+        utils->log("WinNui_resizewin %p %d %d (basewin %p mag %p)\n",
+            window, width, height,
+            windows->get_base_window(), windows->get_magnifier_window());
+    }
+#endif
+    //Evas_Object *window_object = (Evas_Object*)window;
+    //Evas *evas = evas_object_evas_get(window_object);
+    /*CSCLWindows *windows = CSCLWindows::get_instance();
+    if (windows) {
+        windows->update_window(window);
+    }*/
+    //evas_render_idle_flush(evas);
+    if (windows && window) {
+        if (window != windows->get_base_window()) {
+#ifdef WAYLAND
+            Ecore_Wl2_Window *wl_window = (Ecore_Wl2_Window *)(elm_win_wl_window_get(win));
+            ecore_wl2_window_rotation_geometry_set(wl_window,
+                rotation_values_EFL[ROTATION_0], 0, 0, width, height);
+            ecore_wl2_window_rotation_geometry_set(wl_window,
+                rotation_values_EFL[ROTATION_90_CW], 0, 0, height, width);
+            ecore_wl2_window_rotation_geometry_set(wl_window,
+                rotation_values_EFL[ROTATION_180], 0, 0, width, height);
+            ecore_wl2_window_rotation_geometry_set(wl_window,
+                rotation_values_EFL[ROTATION_90_CCW], 0, 0, height, width);
+#else
+            evas_object_resize(win, width, height);
+#endif
+        } else {
+            g_timestamp_last_base_window_resized = (unsigned int)(ecore_loop_time_get() * 1000.0f);
+        }
+
+        if (window == windows->get_dim_window()) {
+            hide_window(window);
+        }
+    }
+}
+
+/**
+* Resizes the window to the given metric
+*/
+void
+CSCLWindowsImplNui::move_resize_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+    Evas_Object *win = (Evas_Object*)window;
+#ifndef FULL_SCREEN_TEST
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    if (windows && utils && window) {
+        if (window != windows->get_base_window()) {
+            evas_object_move(win, x, y);
+            evas_object_resize(win, width, height);
+        }
+        utils->log("WinNui_moveresizewin %p %d %d %d %d (basewin %p)\n",
+            window, x, y, width, height, windows->get_base_window());
+    }
+#endif
+    //Evas_Object *window_object = (Evas_Object*)window;
+    //Evas *evas = evas_object_evas_get(window_object);
+    /*CSCLWindows *windows = CSCLWindows::get_instance();
+    if (windows) {
+        windows->update_window(window);
+    }*/
+    //evas_render_idle_flush(evas);
+}
+
+/**
+* Update the window to redraw given area
+*/
+void
+CSCLWindowsImplNui::update_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    if (m_window_backend_callback) {
+        LOGI("call update_window. x(%d), y(%d), w(%d), h(%d)", x, y, width, height);
+        m_window_backend_callback->update_window(x, y, width, height, m_window_backend_callback_data);
+    }
+    else {
+        LOGW("### No update window callback ###");
+    }
+
+    //return;
+
+    sclboolean removeall = FALSE;
+    SclRectangle updatearea = {x, y, width, height};
+    if (x + y + width + height == 0) {
+        removeall = TRUE;
+    }
+
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    SclWindowContext *window_context = NULL;
+
+    if (windows && window) {
+        //window_context = windows->get_window_context(window, FALSE);
+        window_context = windows->get_window_context(window);
+    }
+    if (windows && utils && window_context) {
+        if (window_context->is_virtual) {
+            SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+            if (base_window_context) {
+                updatearea.x += (window_context->geometry.x - base_window_context->geometry.x);
+                updatearea.y += (window_context->geometry.y - base_window_context->geometry.y);
+            }
+        }
+        if (window_context->etc_info) {
+            Eina_List *list = (Eina_List*)(window_context->etc_info);
+            Eina_List *iter = NULL;
+            Eina_List *iter_next = NULL;
+            void *data = NULL;
+            int iIndex = 0;
+
+            EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) {
+                if (data) {
+                    EFLObject *object = (EFLObject*)(data);
+                    if (object) {
+                        Evas_Object* eo = object->object;
+                        sclboolean bShouldRemove = FALSE;
+                        if (removeall || utils->is_rect_overlap(object->position, updatearea)) {
+                            bShouldRemove = TRUE;
+                        }
+                        if (iIndex == 0 && !removeall) {
+                            bShouldRemove = FALSE; // window's background
+                        }
+                        if (object->type == EFLOBJECT_CLIPOBJECT) {
+                            bShouldRemove = FALSE; // Clip objects are removed when the parent image object is removed
+                        }
+                        if (eo == NULL) { /* If this object is already removed, proceed removing */
+                            bShouldRemove = TRUE;
+                        }
+                        if (bShouldRemove) {
+#ifdef TEST_NEWBACKEND
+                            //if (object->type == EFLOBJECT_IMAGE) {
+                            SCL_DEBUG_ELAPSED_TIME_START();
+                            if (TRUE) {
+                                if (window_context->width != object->position.width || window_context->height != object->position.height ||
+                                    object->type == EFLOBJECT_TEXTBLOCK || window == windows->get_magnifier_window()) {
+                                    evas_object_hide(object->object);
+                                }
+                            } else {
+#else
+                            if (object->extracted) {
+                                void *image_data = evas_object_image_data_get(eo, 1);
+                                if (image_data) {
+                                    free(image_data);
+                                }
+                            }
+                            if (eo) {
+                                evas_object_del(eo);
+                                object->object = NULL;
+                            }
+                            if (object->type == EFLOBJECT_TEXTBLOCK) {
+                                Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data);
+                                if (st) {
+                                    evas_textblock_style_free(st);
+                                }
+#ifdef TEST_NEWBACKEND
+                                for (sclint loop = 0;loop < g_TextCache.size();loop++) {
+                                    if (g_TextCache[loop].text == object->object) {
+                                        g_TextCache[loop].used = FALSE;
+                                    }
+                                }
+#endif
+                            } else if (object->type == EFLOBJECT_IMAGE) {
+#ifdef TEST_NEWBACKEND
+                                for (sclint loop = 0;loop < g_ImageCache.size();loop++) {
+                                    if (g_ImageCache[loop].image == object->object) {
+                                        g_ImageCache[loop].used = FALSE;
+                                    }
+                                }
+#endif
+                                EFLObject *clip_object = (EFLObject*)(object->data);
+                                if (clip_object) {
+                                    if (clip_object->object) {
+                                        evas_object_del(clip_object->object);
+                                        clip_object->object = NULL;
+                                    }
+                                }
+                            }
+                            delete object;
+                            list = eina_list_remove_list(list, iter);
+#endif
+#ifdef TEST_NEWBACKEND
+                            }
+#endif
+                        }
+                    }
+                    iIndex++;
+                }
+            }
+            window_context->etc_info = list;
+
+            /*while ((Eina_List*)(window_context->etc_info))
+            {
+                EFLObject *object = (EFLObject*)eina_list_data_get((Eina_List*)(window_context->etc_info));
+                if (object) {
+                    Evas_Object* eo = object->object;
+                    if (eo) {
+                        evas_object_del(eo);
+                        object->object = NULL;
+                    }
+                }
+                window_context->etc_info = eina_list_remove_list((Eina_List*)(window_context->etc_info), (Eina_List*)(winctx->etc_info));
+                delete object;
+            }
+            window_context->etc_info = NULL;*/
+        }
+        CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+        builder->show_layout(window, x, y, width, height);
+    }
+
+    /*evas_image_cache_flush(evas_object_evas_get((Evas_Object*)window));
+    elm_cache_all_flush();
+    malloc_trim(0);*/
+    //edje_file_cache_flush();
+}
+
+/**
+ * Returns the position of x,y,width,height of the given window
+ */
+sclboolean
+CSCLWindowsImplNui::get_window_rect(const sclwindow window, SclRectangle *rect)
+{
+    SCL_DEBUG();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+
+    if (utils && context && rect && window) {
+        int x = 0, y = 0, width = 0, height = 0;
+        sclint scr_w = 0, scr_h = 0;
+        elm_win_screen_position_get(static_cast<Evas_Object*>(window), &x, &y);
+        evas_object_geometry_get(static_cast<Evas_Object*>(window), NULL, NULL, &width, &height);
+
+        utils->log("WinNui_getwinrect %p %d %d %d %d\n",
+            window, x, y, width, height);
+
+        /* get window size */
+        utils->get_screen_resolution(&scr_w, &scr_h);
+
+        switch (context->get_rotation())
+        {
+        case ROTATION_90_CW:
+            {
+                rect->width = width;
+                rect->height = height;
+                rect->x = scr_w - y - width;
+                rect->y = x;
+            }
+            break;
+        case ROTATION_180:
+            {
+                rect->x = scr_w - width - x;
+                rect->y = scr_h - height - y;
+                rect->width = width;
+                rect->height = height;
+            }
+            break;
+        case ROTATION_90_CCW:
+            {
+                rect->width = width;
+                rect->height = height;
+                rect->x = y;
+                rect->y = scr_h - x - height;
+            }
+            break;
+        default:
+            {
+                rect->x = x;
+                rect->y = y;
+                rect->width = width;
+                rect->height = height;
+            }
+            break;
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * Sets rotation
+ */
+void
+CSCLWindowsImplNui::set_window_rotation(const sclwindow window, SCLRotation rotation)
+{
+    SCL_DEBUG();
+}
+
+/**
+ * Shows a message box
+ */
+void
+CSCLWindowsImplNui::show_message_box(const sclwindow parent, scl8 msgType, sclchar* title, sclchar* msg)
+{
+    SCL_DEBUG();
+}
+
+void
+CSCLWindowsImplNui::set_keep_above(const sclwindow window, sclboolean keepabove)
+{
+    SCL_DEBUG();
+}
+
+void CSCLWindowsImplNui::set_window_accepts_focus(const sclwindow window, sclboolean acceptable)
+{
+    elm_win_prop_focus_skip_set(static_cast<Evas_Object*>(window), !acceptable);
+}
+
+void CSCLWindowsImplNui::set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data)
+{
+    m_window_backend_callback = callback;
+    m_window_backend_callback_data = data;
+}
diff --git a/scl/sclwindows-nui.h b/scl/sclwindows-nui.h
new file mode 100644 (file)
index 0000000..9b96235
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012 - 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 "sclwindows.h"
+#include "sclwindowbackendcallback.h"
+#include <Evas.h>
+#include <Eina.h>
+
+#ifndef __SCL_WINDOWS_NUI_H__
+#define __SCL_WINDOWS_NUI_H__
+
+typedef enum {
+    EFLOBJECT_NONE,
+    EFLOBJECT_IMAGE,
+    EFLOBJECT_CLIPOBJECT,
+    EFLOBJECT_TEXTBLOCK,
+    EFLOBJECT_RECTANGLE,
+} EFLOBJECT_TYPE;
+
+namespace scl
+{
+typedef struct {
+    EFLOBJECT_TYPE type;
+    SclRectangle position;
+    Evas_Object *object;
+    const char *etc_info;
+    sclboolean extracted;
+    void *data;
+} EFLObject;
+
+class CSCLWindowsImplNui : public CSCLWindowsImpl
+{
+public :
+    CSCLWindowsImplNui();
+    ~CSCLWindowsImplNui();
+
+    void init();
+    void fini();
+
+    sclwindow create_base_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height);
+    sclwindow create_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height);
+    sclwindow create_magnifier_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height);
+    sclwindow create_dim_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height);
+    bool destroy_window(sclwindow window);
+    void show_window(const sclwindow window, sclboolean queue);
+    void hide_window(const sclwindow window,  sclboolean fForce = FALSE);
+    void move_window(const sclwindow window, scl16 x, scl16 y);
+    void resize_window(const sclwindow window, scl16 width, scl16 height);
+    void move_resize_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height);
+    void update_window(const sclwindow window, scl16 x = 0, scl16 y = 0, scl16 width = 0, scl16 height = 0);
+    void set_window_rotation(const sclwindow window, SCLRotation rotation);
+    void show_message_box(const sclwindow parent, scl8 msgType, sclchar* title, sclchar* msg);
+    sclboolean get_window_rect(const sclwindow window, SclRectangle *rect);
+    void set_parent(const sclwindow parent, const sclwindow window);
+    void set_keep_above(const sclwindow window, sclboolean keepabove);
+
+    /* EFL specific utility functions */
+    void set_window_accepts_focus(const sclwindow window, sclboolean accepts);
+
+    void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data);
+
+private:
+    ISCLUIWindowBackendCallback* m_window_backend_callback;
+    void* m_window_backend_callback_data;
+};
+} /* End of scl namespace */
+#endif
diff --git a/scl/sclwindows.cpp b/scl/sclwindows.cpp
new file mode 100644 (file)
index 0000000..3c7631b
--- /dev/null
@@ -0,0 +1,1146 @@
+/*
+ * Copyright (c) 2012 - 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 "sclwindows.h"
+#ifdef  __WIN32__
+#include "sclwindows-win32.h"
+#elif defined(__EFL__)
+#include "sclwindows-efl.h"
+#elif defined(__NUI__)
+#include "sclwindows-nui.h"
+#else
+#include "sclwindows-gtk.h"
+#endif
+#include "scldebug.h"
+#include "sclevents.h"
+#include "sclresourcecache.h"
+#include "sclcontroller.h"
+#include "sclactionstate.h"
+#include "sclres_manager.h"
+#include "sclkeyfocushandler.h"
+#include "sclanimator.h"
+#include "scleventhandler.h"
+#include <dlog.h>
+
+using namespace scl;
+
+CSCLWindows::CSCLWindows()
+{
+    SCL_DEBUG();
+
+    sclint loop;
+
+    m_impl = NULL;
+
+    memset(&m_base_window_context, 0x00, sizeof(SclWindowContext));
+    memset(&m_magnifier_window_context, 0x00, sizeof(SclWindowContext));
+    memset(&m_dim_window_context, 0x00, sizeof(SclWindowContext));
+    memset(m_popup_window_context, 0x00, sizeof(SclWindowContext) * MAX_POPUP_WINDOW);
+
+    m_pending_update = FALSE;
+    m_initialized = FALSE;
+
+    for (loop = 0;loop < MAX_ZORDER_NUM;loop++) {
+        m_Z_order_list[loop] = SCLWINDOW_INVALID;
+    }
+}
+
+CSCLWindows::~CSCLWindows()
+{
+    SCL_DEBUG();
+
+    if (m_impl) {
+        delete m_impl;
+        m_impl = NULL;
+    }
+}
+
+void CSCLWindows::init()
+{
+    int loop;
+    CSCLWindowsImpl *impl = get_scl_windows_impl();
+    if (impl) {
+        impl->init();
+    }
+    for (loop = 0;loop < MAX_ZORDER_NUM;loop++) {
+        m_Z_order_list[loop] = SCLWINDOW_INVALID;
+    }
+    m_initialized = TRUE;
+}
+
+void CSCLWindows::fini()
+{
+    CSCLWindowsImpl* impl = get_scl_windows_impl();
+
+    if (impl) {
+        impl->fini();
+
+        if (SCLWINDOW_INVALID != m_base_window_context.window) {
+            impl->destroy_window(m_base_window_context.window);
+            m_base_window_context.window = SCLWINDOW_INVALID;
+        }
+
+        if (SCLWINDOW_INVALID != m_magnifier_window_context.window) {
+            impl->destroy_window(m_magnifier_window_context.window);
+            m_magnifier_window_context.window = SCLWINDOW_INVALID;
+        }
+
+        if (SCLWINDOW_INVALID != m_dim_window_context.window) {
+            impl->destroy_window(m_dim_window_context.window);
+            m_dim_window_context.window = SCLWINDOW_INVALID;
+        }
+
+        for (int loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+            if (m_popup_window_context[loop].window != SCLWINDOW_INVALID) {
+                if (!m_popup_window_context[loop].is_virtual) {
+                    impl->destroy_window(m_popup_window_context[loop].window);
+                }
+                m_popup_window_context[loop].window = SCLWINDOW_INVALID;
+            }
+        }
+    }
+
+    m_initialized = FALSE;
+}
+
+CSCLWindowsImpl*
+CSCLWindows::get_scl_windows_impl()
+{
+    if (m_impl == 0) {
+#ifdef  __WIN32__
+        m_impl = new CSCLWindowsImplWin32;
+#elif defined(__EFL__)
+        m_impl = new CSCLWindowsImplEfl;
+#elif defined(__NUI__)
+        m_impl = new CSCLWindowsImplNui;
+#else
+        m_impl = new CSCLWindowsImplGtk;
+#endif
+    }
+    return m_impl;
+}
+
+CSCLWindows*
+CSCLWindows::get_instance()
+{
+    static CSCLWindows instance;
+    return &instance;
+}
+
+sclwindow CSCLWindows::open_popup(const SclWindowOpener opener, const SclRectangle &geometry, sclshort inputmode, sclshort layout, SCLPopupType popup_type, sclboolean is_virtual, sclboolean use_dim_window, sclint img_offset_x, sclint img_offset_y, sclint timeout)
+{
+    sclwindow window = SCLWINDOW_INVALID;
+
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLController *controller = CSCLController::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    if (events && state && controller && cache && context && windows && utils) {
+        for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+            if (m_popup_window_context[loop].window != SCLWINDOW_INVALID) {
+                if (m_popup_window_context[loop].layout == layout) return SCLWINDOW_INVALID;
+            }
+        }
+
+        window = create_window(opener, geometry, inputmode, layout, popup_type, is_virtual, img_offset_x, img_offset_y, timeout);
+        events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+        if (timeout > 0) {
+            events->create_timer(SCL_TIMER_POPUP_TIMEOUT, timeout, layout);
+        }
+
+        LOGD("create window (%p) x: %d, y:%d, width:%d, height:%d , layout:%d, popuptype:%d",
+            window, geometry.x, geometry.y, geometry.width, geometry.height, layout, popup_type);
+
+        events->connect_window_events(window, SCL_EVENT_MOUSE | SCL_EVENT_EXPOSE);
+        controller->handle_engine_signal(SCL_SIG_POPUP_SHOW, window);
+
+        /* Shows the dim window if it uses the dim_window */
+        if (use_dim_window) {
+            sclwindow dim_window = get_dim_window();
+
+            /* Currently, get_window_rect does not work normally (need to check X). So I have commented it*/
+            SclRectangle rect;
+            get_window_rect(get_base_window(), &rect);
+            resize_window(dim_window, rect.width, rect.height);
+            move_window(dim_window, rect.x, rect.y);
+            events->connect_window_events(dim_window, SCL_EVENT_MOUSE);
+            /*If we use transient_for them the ISE will occur some crash. It needs to check X11*/
+            set_parent(opener.window, dim_window);
+            SclWindowContext *dim_window_context = get_window_context(get_dim_window());
+            if (dim_window_context) {
+                if (dim_window_context->is_virtual) {
+                    set_parent(opener.window, window);
+                } else {
+                    set_parent(dim_window, window);
+                }
+            }
+            show_window(dim_window);
+        } else {
+            /*If we use transient_for them the ISE will occur some crash. It needs to check X11*/
+            set_parent(opener.window, window);
+        }
+        show_window(window);
+
+        push_window_in_Z_order_list(window);
+
+        state->set_cur_action_state(ACTION_STATE_POPUP_INIT);
+
+        const SclLayout *cur_layout = cache->get_cur_layout(window);
+        if (cur_layout) {
+            /* If the newly opened popup window has POPUP_GRAB style, lets press the nearest button on the new window */
+            if (cur_layout->style == LAYOUT_STYLE_POPUP_GRAB) {
+                sclwindow pressed_window = context->get_cur_pressed_window(context->get_last_touch_device_id());
+                sclbyte pressed_key = context->get_cur_pressed_key(context->get_last_touch_device_id());
+
+                const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+                sclwindow moving_window = context->get_cur_moving_window(context->get_last_touch_device_id());
+                SclPoint moving_point = context->get_cur_moving_point(context->get_last_touch_device_id());
+                SclWindowContext *moving_window_context = windows->get_window_context(moving_window);
+                SclWindowContext *popup_window_context = windows->get_window_context(window);
+                if (moving_window_context && popup_window_context) {
+                    moving_point.x =
+                        (moving_window_context->geometry.x - popup_window_context->geometry.x) + moving_point.x;
+                    moving_point.y =
+                        (moving_window_context->geometry.y - popup_window_context->geometry.y) + moving_point.y;
+                }
+
+                /* Find the nearest button on the autopopup window */
+                sclboolean ended = FALSE;
+                sclfloat min_dist = (float)((sclu32)(-1));
+                sclint min_dist_index = NOT_USED;
+                for (sclint loop = 0;loop < MAX_KEY && !ended;loop++) {
+                    SclButtonContext *popup_button_context = cache->get_cur_button_context(window, loop);
+                    const SclLayoutKeyCoordinate *popup_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+                    if (popup_button_context && popup_coordinate) {
+                        if (!(popup_button_context->used)) {
+                            ended = TRUE;
+                        } else if (popup_button_context->state != BUTTON_STATE_DISABLED &&
+                            popup_coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                                if (popup_coordinate) {
+                                    float dist = utils->get_approximate_distance(moving_point.x, moving_point.y,
+                                        popup_coordinate->x + (popup_coordinate->width / 2) -
+                                        cur_layout->mouse_manipulate_x,
+                                        popup_coordinate->y + (popup_coordinate->height / 2) -
+                                        cur_layout->mouse_manipulate_y);
+                                    if (dist < min_dist) {
+                                        min_dist_index = loop;
+                                        min_dist = dist;
+                                    }
+                                }
+                        }
+                    }
+                }
+                /* When we found the nearest button, make it pressed */
+                if (min_dist_index != NOT_USED) {
+                    const SclLayoutKeyCoordinate *popup_coordinate =
+                        cache->get_cur_layout_key_coordinate(window, min_dist_index);
+                    if (popup_coordinate) {
+                        sclint x = popup_coordinate->x + (popup_coordinate->width / 2) -
+                            cur_layout->mouse_manipulate_x;
+                        sclint y = popup_coordinate->y + (popup_coordinate->height / 2) -
+                            cur_layout->mouse_manipulate_y;
+                        controller->mouse_press(window, x, y, context->get_last_touch_device_id());
+                    }
+                }
+
+                /* The below code block seems unnecessary since we already invoked mouse_press() */
+                /*context->set_cur_pressed_window(context->get_last_touch_device_id(), window);
+                context->set_cur_pressed_key(context->get_last_touch_device_id(), min_dist_index);
+                if (button_context) {
+                    button_context->state = BUTTON_STATE_NORMAL;
+                }*/
+
+                if (windows && coordinate)
+                    windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+            }
+        }
+    }
+
+    return window;
+}
+
+bool CSCLWindows::close_popup(sclwindow window, sclboolean timed_out)
+{
+    LOGD("close_popup window (%p)", window);
+
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+
+    if (handler) {
+        SclNotiPopupClosingDesc desc;
+        desc.ui_event_desc = NULL;
+        desc.input_mode = NULL;
+        desc.timed_out = timed_out;
+
+        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+        if (sclres_manager) {
+            const PSclInputModeConfigure sclres_input_mode_configure =
+                sclres_manager->get_input_mode_configure_table();
+            SclWindowContext *window_context = get_window_context(window);
+            if (window_context && sclres_input_mode_configure) {
+                if (scl_check_arrindex(window_context->inputmode, MAX_SCL_INPUT_MODE)) {
+                    desc.input_mode = sclres_input_mode_configure[window_context->inputmode].name;
+                }
+            }
+        }
+
+        if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_CLOSING, &desc)) {
+            SclNotiPopupClosedDesc closed_desc;
+            closed_desc.ui_event_desc = NULL;
+            closed_desc.input_mode = desc.input_mode;
+            closed_desc.timed_out = desc.timed_out;
+            handler->on_event_notification(SCL_UINOTITYPE_POPUP_CLOSED, &desc);
+
+            CSCLKeyFocusHandler *focus_handler = CSCLKeyFocusHandler::get_instance();
+            if (focus_handler) {
+                focus_handler->popup_closed(window);
+            }
+            pop_window_in_Z_order_list(window);
+
+            hide_window(get_dim_window());
+            hide_window(window);
+            return destroy_window(window);
+        }
+    }
+
+    return FALSE;
+}
+
+bool CSCLWindows::close_all_popups(sclwindow skip_window /* = SCLWINDOW_INVALID */, sclboolean timed_out)
+{
+    sclboolean all_closed = TRUE;
+    /* Close all the popup windows except the targetWindow */
+    int loop = 0;
+    sclwindow window;
+    do {
+        window = get_nth_popup_window(loop);
+        if (window) {
+            if (window != skip_window) {
+                close_popup(window, timed_out);
+            } else {
+                all_closed = FALSE;
+            }
+        }
+        loop++;
+    } while (window);
+
+    /* If there is a popup still opened, don't destroy POPUP_TIMEOUT timer */
+    return all_closed;
+}
+
+sclwindow
+CSCLWindows::create_base_window(const sclwindow parent, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    if (m_initialized) {
+        CSCLWindowsImpl* impl = get_scl_windows_impl();
+
+        m_base_window_context.hidden = TRUE;
+        m_base_window_context.geometry.width = width;
+        m_base_window_context.geometry.height = height;
+        m_base_window_context.is_virtual = FALSE;
+        m_base_window_context.popup_type = POPUP_TYPE_NONE;
+        m_base_window_context.opener.window = parent;
+        m_base_window_context.geometry.x = m_base_window_context.geometry.y = 0;
+        m_base_window_context.etc_info = NULL;
+        m_base_window_context.window = SCLWINDOW_INVALID;
+
+        if (impl) {
+            m_base_window_context.window = impl->create_base_window(parent, &m_base_window_context, width, height);
+            push_window_in_Z_order_list(m_base_window_context.window);
+        }
+    }
+
+    // Update the position information
+    //get_window_context(parent, TRUE);
+
+    return m_base_window_context.window;
+}
+
+/**
+ * Creates a new top-level window
+ *
+ * @Code
+ *  CSCLGwes* gwes = CSCLGwes::get_instance();
+ *  sclwindow popupWindow = gwes->m_windows->create_window(window, 100, 500, 200, 100, 4, POPUP_TYPE_BTN_RELEASE_POPUP, FALSE);
+ *  if (popupWindow != NULL) {
+ *     gwes->m_events->connect_window_events(popupWindow, SCL_EVENT_MOUSE | SCL_EVENT_EXPOSE);
+ *      cache->recompute_layout(popupWindow);
+ *      gwes->m_windows->show_window(popupWindow);
+ *  }
+ */
+sclwindow
+CSCLWindows::create_window(const SclWindowOpener opener, const SclRectangle &geometry, sclshort inputmode, sclshort layout, SCLPopupType popup_type, sclboolean is_virtual, sclint img_offset_x, sclint img_offset_y, sclint timeout)
+{
+    SCL_DEBUG();
+
+    CSCLWindowsImpl* impl = get_scl_windows_impl();
+    sclwindow window = SCLWINDOW_INVALID;
+
+    if (impl) {
+        for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+            if (m_popup_window_context[loop].window == SCLWINDOW_INVALID) {
+                m_popup_window_context[loop].hidden = TRUE;
+                m_popup_window_context[loop].opener = opener;
+                m_popup_window_context[loop].etc_info = NULL;
+                m_popup_window_context[loop].inputmode = inputmode;
+                m_popup_window_context[loop].layout = layout;
+                m_popup_window_context[loop].popup_type = popup_type;
+                m_popup_window_context[loop].is_virtual = is_virtual;
+
+                m_popup_window_context[loop].geometry = geometry;
+
+                m_popup_window_context[loop].layout_image_offset.x = img_offset_x;
+                m_popup_window_context[loop].layout_image_offset.y = img_offset_y;
+
+                m_popup_window_context[loop].timeout = timeout;
+
+                if (!is_virtual) {
+                    window = impl->create_window(opener.window,
+                        &(m_popup_window_context[loop]), geometry.width, geometry.height);
+                } else {
+                    window = reinterpret_cast<sclwindow>(loop + 1);
+                }
+                if (window) {
+                    m_popup_window_context[loop].window = window;
+                }
+                //set_window_rotation(window, context->get_rotation_degree());
+                if (!m_popup_window_context[loop].is_virtual) {
+                    impl->move_window(window, geometry.x, geometry.y);
+                }
+                break;
+            }
+        }
+
+        // Update the position information
+        //get_window_context(window, TRUE);
+
+        if (window == NULL) {
+            LOGW("Failed to create a new window. The size of window buffer has exceeded.");
+        }
+    }
+    return window;
+}
+
+sclwindow
+CSCLWindows::create_magnifier_window(const sclwindow parent, scl16 x, scl16 y, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    CSCLWindowsImpl* impl = get_scl_windows_impl();
+    sclwindow window = SCLWINDOW_INVALID;
+
+    if (impl && m_initialized) {
+        if (m_magnifier_window_context.window == SCLWINDOW_INVALID) {
+            window = impl->create_magnifier_window(parent, &m_magnifier_window_context, width, height);
+            impl->set_keep_above(window, TRUE);
+            if (window) {
+                m_magnifier_window_context.window = window;
+                m_magnifier_window_context.geometry.width = width;
+                m_magnifier_window_context.geometry.height = height;
+                m_magnifier_window_context.hidden = TRUE;
+            }
+        } else {
+            window = m_magnifier_window_context.window;
+        }
+        set_parent(parent, window);
+
+        if (window == NULL) {
+            LOGW("Failed to create a new window. The size of window buffer has exceeded.");
+        } else {
+            LOGD("Magnifier Window %p created", window);
+        }
+    }
+
+    // Update the position information
+    //get_window_context(window, TRUE);
+
+    return window;
+}
+
+sclwindow
+CSCLWindows::get_magnifier_window()
+{
+    SCL_DEBUG();
+    return m_magnifier_window_context.window;
+}
+
+sclwindow
+CSCLWindows::create_dim_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    CSCLWindowsImpl* impl = get_scl_windows_impl();
+    sclwindow window = SCLWINDOW_INVALID;
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    PSclDefaultConfigure default_configure = NULL;
+    if (sclres_manager) {
+        default_configure = sclres_manager->get_default_configure();
+    }
+
+    if (impl && m_initialized && default_configure) {
+        if (m_dim_window_context.window == NULL) {
+            m_dim_window_context.hidden = TRUE;
+            if (default_configure->use_actual_dim_window) {
+                window = impl->create_dim_window(parent, &m_dim_window_context, width, height);
+            } else {
+                window = reinterpret_cast<sclwindow>(SCLWINDOW_VIRTUAL_DIM);
+                m_dim_window_context.is_virtual = TRUE;
+            }
+            if (window) {
+                m_dim_window_context.window = window;
+            }
+        } else {
+            window = m_dim_window_context.window;
+        }
+
+        if (window == NULL) {
+            LOGW("Failed to create a new window. The size of window buffer has exceeded");
+        }
+    }
+
+    return window;
+}
+
+sclwindow
+CSCLWindows::get_dim_window()
+{
+    SCL_DEBUG();
+    return m_dim_window_context.window;
+}
+
+bool
+CSCLWindows::destroy_window(sclwindow window)
+{
+    SCL_DEBUG();
+
+    CSCLWindowsImpl* impl = get_scl_windows_impl();
+    sclboolean ret = FALSE;
+
+    if (impl) {
+        if (window == m_base_window_context.window) {
+            impl->destroy_window(window);
+            memset(&m_base_window_context, 0x00, sizeof(SclWindowContext));
+            m_base_window_context.window = SCLWINDOW_INVALID;
+            ret = TRUE;
+        } else if (window == m_magnifier_window_context.window) {
+            impl->destroy_window(window);
+            memset(&m_magnifier_window_context, 0x00, sizeof(SclWindowContext));
+            m_magnifier_window_context.window = SCLWINDOW_INVALID;
+            ret = TRUE;
+        } else if (window == m_dim_window_context.window) {
+            impl->destroy_window(window);
+            memset(&m_dim_window_context, 0x00, sizeof(SclWindowContext));
+            m_dim_window_context.window = SCLWINDOW_INVALID;
+            ret = TRUE;
+        } else {
+            for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+                if (m_popup_window_context[loop].window == window) {
+                    impl->destroy_window(window);
+                    memset(&m_popup_window_context[loop], 0x00, sizeof(SclWindowContext));
+                    ret = TRUE;
+                    m_popup_window_context[loop].window = SCLWINDOW_INVALID;
+                    break;
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+sclwindow
+CSCLWindows::get_base_window()
+{
+    SCL_DEBUG();
+
+    return m_base_window_context.window;
+}
+
+sclboolean
+CSCLWindows::is_base_window(sclwindow window)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+
+    if (window != SCLWINDOW_INVALID) {
+        if (window == m_base_window_context.window) {
+            ret = TRUE;
+        }
+    }
+
+    return ret;
+}
+
+sclwindow
+CSCLWindows::find_by_etcinfo(void* etc_info)
+{
+    SCL_DEBUG();
+
+    sclwindow ret = SCLWINDOW_INVALID;
+
+    if (etc_info == m_base_window_context.etc_info) {
+        ret = m_base_window_context.window;
+    } else if (etc_info == m_magnifier_window_context.etc_info) {
+        ret = m_magnifier_window_context.window;
+    } else if (etc_info == m_dim_window_context.etc_info) {
+        ret = m_dim_window_context.window;
+    } else {
+        for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+            if (etc_info == m_popup_window_context[loop].etc_info) {
+                ret = m_popup_window_context[loop].window;
+                break;
+            }
+        }
+    }
+
+    return ret;
+}
+
+SclWindowContext*
+//CSCLWindows::get_window_context(sclwindow window, sclboolean geometry_update)
+CSCLWindows::get_window_context(sclwindow window)
+{
+    SCL_DEBUG();
+
+    SclWindowContext* ret = NULL;
+
+    if (window == m_base_window_context.window) {
+        /*if (geometry_update) {
+            SclRectangle rect;
+            get_window_rect(window, &rect);
+            m_base_window_context.geometry.x = rect.x;
+            m_base_window_context.geometry.y = rect.y;
+        }*/
+        ret = &m_base_window_context;
+    } else if (window == m_magnifier_window_context.window) {
+        ret = &m_magnifier_window_context;
+    } else if (window == m_dim_window_context.window) {
+        ret = &m_dim_window_context;
+    } else {
+        for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+            if (m_popup_window_context[loop].window == window) {
+                /*if (geometry_update) {
+                    SclRectangle rect;
+                    get_window_rect(window, &rect);
+                    m_popup_window_context[loop].geometry.x = rect.x;
+                    m_popup_window_context[loop].geometry.y = rect.y;
+                }*/
+                ret = &m_popup_window_context[loop];
+                break;
+            }
+        }
+    }
+
+    return ret;
+}
+
+void
+CSCLWindows::set_window_context(sclwindow window, SclWindowContext* context)
+{
+    SCL_DEBUG();
+
+    if (window == m_base_window_context.window) {
+        memcpy(&m_base_window_context, context, sizeof(SclWindowContext));
+    } else {
+        for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+            if (m_popup_window_context[loop].window == window) {
+                memcpy(&m_popup_window_context[loop], context, sizeof(SclWindowContext));
+                break;
+            }
+        }
+    }
+}
+
+scl8
+CSCLWindows::find_popup_window_index(sclwindow window)
+{
+    SCL_DEBUG();
+
+    scl8 ret = NOT_USED;
+
+    for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+        if (m_popup_window_context[loop].window == window) {
+            ret = loop;
+            break;
+        }
+    }
+
+    return ret;
+}
+
+void
+CSCLWindows::move_window(const sclwindow window, scl16 x, scl16 y)
+{
+    SCL_DEBUG();
+
+    sclboolean is_virtual = FALSE;
+    if (window == m_base_window_context.window) {
+        m_base_window_context.geometry.x = x;
+        m_base_window_context.geometry.y = y;
+        is_virtual = m_base_window_context.is_virtual;
+    } else if (window == m_magnifier_window_context.window) {
+        m_magnifier_window_context.geometry.x = x;
+        m_magnifier_window_context.geometry.y = y;
+        is_virtual = m_magnifier_window_context.is_virtual;
+    } else if (window == m_dim_window_context.window) {
+        m_dim_window_context.geometry.x = x;
+        m_dim_window_context.geometry.y = y;
+        is_virtual = m_dim_window_context.is_virtual;
+    } else {
+        for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+            if (m_popup_window_context[loop].window == window) {
+                m_popup_window_context[loop].geometry.x = x;
+                m_popup_window_context[loop].geometry.y = y;
+                is_virtual = m_popup_window_context[loop].is_virtual;
+                break;
+            }
+        }
+    }
+    if (!is_virtual) {
+        CSCLWindowsImpl* impl = get_scl_windows_impl();
+        if (impl) {
+            impl->move_window(window, x, y);
+        }
+    }
+}
+
+void
+CSCLWindows::resize_window(const sclwindow window, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    sclboolean is_virtual = FALSE;
+    if (window == m_base_window_context.window) {
+        m_base_window_context.geometry.width = width;
+        m_base_window_context.geometry.height = height;
+        is_virtual = m_base_window_context.is_virtual;
+    } else if (window == m_magnifier_window_context.window) {
+        m_magnifier_window_context.geometry.width = width;
+        m_magnifier_window_context.geometry.height = height;
+        is_virtual = m_magnifier_window_context.is_virtual;
+    } else if (window == m_dim_window_context.window) {
+        m_dim_window_context.geometry.width = width;
+        m_dim_window_context.geometry.height = height;
+        is_virtual = m_dim_window_context.is_virtual;
+    } else {
+        for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+            if (m_popup_window_context[loop].window == window) {
+                m_popup_window_context[loop].geometry.width = width;
+                m_popup_window_context[loop].geometry.height = height;
+                is_virtual = m_popup_window_context[loop].is_virtual;
+                break;
+            }
+        }
+    }
+    if (!is_virtual) {
+        CSCLWindowsImpl* impl = get_scl_windows_impl();
+        if (impl) {
+            impl->resize_window(window, width, height);
+        }
+    }
+}
+
+void
+CSCLWindows::move_resize_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height)
+{
+    SCL_DEBUG();
+
+    sclboolean is_virtual = FALSE;
+    if (window == m_base_window_context.window) {
+        m_base_window_context.geometry.x = x;
+        m_base_window_context.geometry.y = y;
+        m_base_window_context.geometry.width = width;
+        m_base_window_context.geometry.height = height;
+        is_virtual = m_base_window_context.is_virtual;
+    } else if (window == m_magnifier_window_context.window) {
+        m_magnifier_window_context.geometry.x = x;
+        m_magnifier_window_context.geometry.y = y;
+        m_magnifier_window_context.geometry.width = width;
+        m_magnifier_window_context.geometry.height = height;
+        is_virtual = m_magnifier_window_context.is_virtual;
+    } else if (window == m_dim_window_context.window) {
+        m_dim_window_context.geometry.x = x;
+        m_dim_window_context.geometry.y = y;
+        m_dim_window_context.geometry.width = width;
+        m_dim_window_context.geometry.height = height;
+        is_virtual = m_dim_window_context.is_virtual;
+    } else {
+        for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+            if (m_popup_window_context[loop].window == window) {
+                m_popup_window_context[loop].geometry.x = x;
+                m_popup_window_context[loop].geometry.y = y;
+                m_popup_window_context[loop].geometry.width = width;
+                m_popup_window_context[loop].geometry.height = height;
+                is_virtual = m_popup_window_context[loop].is_virtual;
+                break;
+            }
+        }
+    }
+    if (!is_virtual) {
+        CSCLWindowsImpl* impl = get_scl_windows_impl();
+        if (impl) {
+            impl->move_resize_window(window, x, y, width, height);
+        }
+    }
+}
+
+
+/* Push given window into a Z-order list */
+void CSCLWindows::push_window_in_Z_order_list(sclwindow window)
+{
+    SCL_DEBUG();
+
+    sclint loop;
+
+    for (loop = 0;loop < MAX_ZORDER_NUM;loop++) {
+        if (m_Z_order_list[loop] == SCLWINDOW_INVALID) {
+            m_Z_order_list[loop] = window;
+            return;
+        }
+    }
+}
+
+/* Pop given window from a Z-order list */
+void CSCLWindows::pop_window_in_Z_order_list(sclwindow window)
+{
+    SCL_DEBUG();
+
+    sclint loop;
+    sclboolean found = FALSE;
+
+    for (loop = 0;loop < MAX_ZORDER_NUM - 1;loop++) {
+        if (m_Z_order_list[loop] == window || found) {
+            found = TRUE;
+            m_Z_order_list[loop] = m_Z_order_list[loop + 1];
+        }
+    }
+
+    m_Z_order_list[MAX_ZORDER_NUM - 1] = SCLWINDOW_INVALID;
+}
+
+/* Search n-th window in the Z-order stack, starting from the top (TOPMOST window would be the 0 index) */
+sclwindow CSCLWindows::get_nth_window_in_Z_order_list(sclbyte index)
+{
+    SCL_DEBUG();
+
+    sclint loop;
+
+    for (loop = MAX_ZORDER_NUM - 1;loop >= 0;loop--) {
+        if (m_Z_order_list[loop] != SCLWINDOW_INVALID) {
+            if (index == 0) {
+                return m_Z_order_list[loop];
+            }
+            index--;
+        }
+    }
+
+    return SCLWINDOW_INVALID;
+}
+
+sclwindow CSCLWindows::get_nth_popup_window(sclbyte index)
+{
+    SCL_DEBUG();
+
+    scl_assert_return_null(index >= 0 && index < MAX_POPUP_WINDOW);
+
+    if (index < MAX_POPUP_WINDOW) {
+        return m_popup_window_context[index].window;
+    }
+
+    return SCLWINDOW_INVALID;
+}
+
+sclbyte CSCLWindows::get_Z_order(sclwindow window)
+{
+    SCL_DEBUG();
+
+    sclbyte loop;
+    for (loop = 0;loop < MAX_ZORDER_NUM;loop++) {
+        if (m_Z_order_list[loop] == window) {
+            return loop;
+        }
+    }
+    return NOT_USED;
+}
+
+void CSCLWindows::set_parent(const sclwindow parent, const sclwindow window)
+{
+    /* Do not set parent if the window is a virtual window */
+    //SclWindowContext *window_context = get_window_context(window, FALSE);
+    SclWindowContext *window_context = get_window_context(window);
+    if (window_context) {
+        if (!(window_context->is_virtual)) {
+            CSCLWindowsImpl* impl = get_scl_windows_impl();
+            if (impl) {
+                impl->set_parent(parent, window);
+            }
+        }
+    }
+}
+
+void CSCLWindows::set_window_rotation(const sclwindow window, SCLRotation rotation)
+{
+    SCL_DEBUG();
+
+    CSCLWindowsImpl* impl = get_scl_windows_impl();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    if (impl && utils) {
+        if (window == NULL) {
+            impl->set_window_rotation(m_base_window_context.window, rotation);
+            if (SCLWINDOW_INVALID != m_magnifier_window_context.window) {
+                SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+                PSclMagnifierWndConfigure magnifier_configure = NULL;
+                if (sclres_manager) {
+                    magnifier_configure = sclres_manager->get_magnifier_configure();
+                }
+                if (magnifier_configure) {
+                    m_magnifier_window_context.geometry.width =
+                        magnifier_configure->width * utils->get_custom_scale_rate_x();
+                    m_magnifier_window_context.geometry.height =
+                        magnifier_configure->height * utils->get_custom_scale_rate_y();
+
+                    impl->set_window_rotation(m_magnifier_window_context.window, rotation);
+                }
+            }
+
+            if (SCLWINDOW_INVALID != m_dim_window_context.window) {
+                /* For individual window rotation */
+                impl->set_window_rotation(m_dim_window_context.window, rotation);
+                //resize_window(m_dim_window_context.window, m_base_window_context.width, m_base_winctx.height);
+                //move_window(m_dim_window_context.window, m_base_window_context.x, m_base_winctx.y);
+                hide_window(m_dim_window_context.window);
+            }
+            /* For individual window rotation
+            for (int loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+                if (m_popup_window_context[loop].window != SCLWINDOW_INVALID) {
+                    if (!m_popup_window_context[loop].isVirtual) {
+                        get_scl_windows_impl()->set_window_rotation(m_popup_window_context[loop].window, degree);
+                    }
+                }
+            }
+            */
+        } else {
+            impl->set_window_rotation(window, rotation);
+            LOGD("## set_window_rotation : %d", rotation);
+        }
+    }
+
+    // Update the position information
+    //get_window_context(window, TRUE);
+    SclWindowContext *window_context = get_window_context(window);
+    if (window_context) {
+        get_window_rect(window, &(window_context->geometry));
+    }
+}
+
+
+void
+CSCLWindows::show_window(const sclwindow window, sclboolean queue /*= FALSE*/)
+{
+    SCL_DEBUG();
+
+    if (window == m_base_window_context.window) {
+        m_base_window_context.hidden = FALSE;
+    } else if (window == m_magnifier_window_context.window) {
+        m_magnifier_window_context.hidden = FALSE;
+    } else if (window == m_dim_window_context.window) {
+        m_dim_window_context.hidden = FALSE;
+    } else {
+        for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+            if (m_popup_window_context[loop].window == window) {
+                m_popup_window_context[loop].hidden = FALSE;
+                break;
+            }
+        }
+    }
+
+    CSCLWindowsImpl* impl = get_scl_windows_impl();
+    if (impl) {
+        impl->show_window(window, queue);
+    }
+}
+
+void
+CSCLWindows::hide_window(const sclwindow window, sclboolean force /*= FALSE*/)
+{
+    SCL_DEBUG();
+
+    if (window == m_base_window_context.window) {
+        m_base_window_context.hidden = TRUE;
+    } else if (window == m_magnifier_window_context.window) {
+        m_magnifier_window_context.hidden = TRUE;
+    } else if (window == m_dim_window_context.window) {
+        m_dim_window_context.hidden = TRUE;
+    } else {
+        for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+            if (m_popup_window_context[loop].window == window) {
+                m_popup_window_context[loop].hidden = TRUE;
+                break;
+            }
+        }
+    }
+
+    CSCLWindowsImpl* impl = get_scl_windows_impl();
+    if (impl) {
+        impl->hide_window(window, force);
+    }
+}
+
+void
+CSCLWindows::set_keep_above(const sclwindow window, sclboolean keep_above)
+{
+    CSCLWindowsImpl* impl = get_scl_windows_impl();
+    if (impl) {
+        impl->set_keep_above(window, keep_above);
+    }
+}
+
+void
+CSCLWindows::set_update_pending(sclboolean pend)
+{
+    m_pending_update = pend;
+    if (!pend) {
+        update_window(m_base_window_context.window);
+    }
+}
+
+sclboolean
+CSCLWindows::get_update_pending()
+{
+    return m_pending_update;
+}
+
+void
+CSCLWindows::update_window(const sclwindow window,
+                           scl16 x /*= 0*/, scl16 y /*= 0*/, scl16 width /*= 0*/, scl16 height /*= 0*/ )
+{
+    if (!m_pending_update) {
+        CSCLWindowsImpl* impl = get_scl_windows_impl();
+        CSCLAnimator *animator = CSCLAnimator::get_instance();
+        CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+        CSCLContext *context = CSCLContext::get_instance();
+        CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+
+        if (impl) {
+            impl->update_window(window, x, y, width, height);
+
+            /* If we are not updating the whole screen */
+            if (animator && cache && context && focus_handler && (x != 0 || y != 0 || width != 0 || height != 0)) {
+                sclboolean draw_highlight_ui = TRUE;
+                SclAnimationState *state = NULL;
+
+                if (animator) {
+                    sclint id = animator->find_animator_by_type(ANIMATION_TYPE_HIGHLIGHT_UI);
+                    state = animator->get_animation_state(id);
+                }
+                if (state) {
+                    // If currently the highlight UI is being animated, don't update here
+                    if (state->active) {
+                        draw_highlight_ui = FALSE;
+                    }
+                }
+
+                SclWindowContext *window_context = get_window_context(window);
+                if (focus_handler->get_current_focus_window() == window) {
+                    sclint startx = 0;
+                    sclint starty = 0;
+
+                    SclWindowContext *base_window_context = get_window_context(get_base_window());
+                    if (window_context && base_window_context) {
+                        if (window_context->is_virtual) {
+                            startx += (window_context->geometry.x - base_window_context->geometry.x);
+                            starty += (window_context->geometry.y - base_window_context->geometry.y);
+                        }
+                    }
+                    if (draw_highlight_ui && context->get_highlight_ui_enabled()) {
+                        const SclLayoutKeyCoordinate *coordinate = NULL;
+                        scl8 current_key_index = focus_handler->get_current_focus_key();
+                        coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
+                        if (coordinate) {
+                            // Update the highlighted area as well
+                            LOGD("startx: %d, starty: %d", startx, starty);
+                            LOGD("coordinate x(%d), y(%d), w(%d), h(%d)", coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+
+                            impl->update_window(window, startx + coordinate->x, starty + coordinate->y, coordinate->width, coordinate->height);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+sclboolean
+CSCLWindows::get_window_rect(const sclwindow window, SclRectangle *rect) {
+    SCL_DEBUG();
+
+    sclboolean is_virtual = FALSE;
+    sclboolean ret = FALSE;
+    if (rect) {
+        if (window == m_base_window_context.window) {
+            is_virtual = m_base_window_context.is_virtual;
+            if (is_virtual) {
+                *rect = m_base_window_context.geometry;
+            }
+        } else if (window == m_magnifier_window_context.window) {
+            is_virtual = m_magnifier_window_context.is_virtual;
+            if (is_virtual) {
+                *rect = m_magnifier_window_context.geometry;
+            }
+        } else if (window == m_dim_window_context.window) {
+            is_virtual = m_dim_window_context.is_virtual;
+            if (is_virtual) {
+                *rect = m_dim_window_context.geometry;
+            }
+        } else {
+            for (sclint loop = 0;loop < MAX_POPUP_WINDOW;loop++) {
+                if (m_popup_window_context[loop].window == window) {
+                    is_virtual = m_popup_window_context[loop].is_virtual;
+                    if (is_virtual) {
+                        *rect = m_popup_window_context[loop].geometry;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    if (!is_virtual) {
+         CSCLWindowsImpl* impl = get_scl_windows_impl();
+         if (impl) {
+             ret = impl->get_window_rect(window, rect);
+         }
+    }
+
+    return ret;
+}
+
+void CSCLWindows::set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data)
+{
+    CSCLWindowsImpl* impl = get_scl_windows_impl();
+    if (impl) {
+        impl->set_window_backend_callback(callback, data);
+    }
+}
\ No newline at end of file
diff --git a/scl/sclwindows.h b/scl/sclwindows.h
new file mode 100644 (file)
index 0000000..579b2dd
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2012 - 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "scltypes.h"
+#include "sclconfig.h"
+#include "sclwindowbackendcallback.h"
+
+#ifndef __SCL_WINDOWS_H__
+#define __SCL_WINDOWS_H__
+
+#ifdef __cplusplus
+//SCL_BEGIN_DECLS
+#endif
+
+namespace scl
+{
+#define MAX_POPUP_WINDOW 1
+#define MAX_ZORDER_NUM (MAX_POPUP_WINDOW + 1 ) /* Popup + Base */
+
+#define SCL_WINDOW_Z_TOP 0
+
+/**@brief A struct for identifying who opened this window */
+typedef struct _SclWindowOpener {
+    sclwindow   window;
+    sclint      key;
+} SclWindowOpener;
+
+/**@brief  window context structure */
+typedef struct _SclWindowContext {
+    sclboolean          is_virtual;
+    sclwindow           window;
+    sclshort            inputmode;
+    sclshort            layout;
+    sclboolean          hidden;
+    SCLPopupType        popup_type;
+
+    SclWindowOpener     opener;
+    SclRectangle        geometry;
+
+    sclint              timeout;
+
+    SclPoint            layout_image_offset;
+    const void*         etc_info;
+} SclWindowContext;
+
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLWindowsImpl
+{
+public :
+    CSCLWindowsImpl() {}
+    virtual ~CSCLWindowsImpl() {}
+
+    virtual void init() = 0;
+    virtual void fini() = 0;
+
+    virtual sclwindow create_base_window(const sclwindow parent,
+        SclWindowContext *window_context, scl16 width, scl16 height) = 0;
+    virtual sclwindow create_window(const sclwindow parent,
+        SclWindowContext *window_context, scl16 width, scl16 height) = 0;
+    virtual sclwindow create_magnifier_window(const sclwindow parent,
+        SclWindowContext *window_context, scl16 width, scl16 height) = 0;
+    virtual sclwindow create_dim_window(const sclwindow parent,
+        SclWindowContext *window_context, scl16 width, scl16 height) = 0;
+    virtual bool destroy_window(sclwindow window) = 0;
+    virtual void set_parent(const sclwindow parent, const sclwindow window) = 0;
+    virtual void show_window(const sclwindow window, sclboolean queue) = 0;
+    virtual void set_window_rotation(const sclwindow window, SCLRotation rotation) = 0;
+    virtual void hide_window(const sclwindow window,  sclboolean force = FALSE) = 0;
+    virtual void move_window(const sclwindow window, scl16 x, scl16 y) = 0;
+    virtual void move_resize_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height) = 0;
+    virtual void resize_window(const sclwindow window, scl16 width, scl16 height) = 0;
+    virtual void update_window(const sclwindow window, scl16 x = 0, scl16 y = 0, scl16 width = 0, scl16 height = 0) = 0;
+    virtual sclboolean get_window_rect(const sclwindow window, SclRectangle *rect) = 0;
+
+    virtual void set_keep_above(const sclwindow window, sclboolean keep_above) = 0;
+
+    virtual void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data) = 0;
+};
+
+class CSCLWindows
+{
+private:
+    CSCLWindows();
+public :
+    virtual ~CSCLWindows();
+
+    static CSCLWindows* get_instance();
+
+    void init();
+    void fini();
+
+    sclwindow open_popup(const SclWindowOpener opener, const SclRectangle& geometry,
+        sclshort inputmode, sclshort layout, SCLPopupType popup_type, sclboolean is_virtual,
+        sclboolean use_dim_window, sclint img_offset_x = 0, sclint img_offset_y = 0, sclint timeout = 0);
+    bool close_popup(sclwindow window, sclboolean timed_out = FALSE);
+    bool close_all_popups(sclwindow skip_window = SCLWINDOW_INVALID, sclboolean timed_out = FALSE);
+
+    sclwindow create_base_window(const sclwindow parent, scl16 width, scl16 height);
+
+    void show_window(const sclwindow window, sclboolean queue = FALSE);
+    void hide_window(const sclwindow window,  sclboolean force = FALSE);
+    void set_parent(const sclwindow parent, const sclwindow window);
+    void set_keep_above(const sclwindow window, sclboolean keep_above);
+
+    void set_window_rotation(const sclwindow window, SCLRotation rotation);
+
+    void move_window(const sclwindow window, scl16 x, scl16 y);
+    void resize_window(const sclwindow window, scl16 width, scl16 height);
+    void move_resize_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height);
+    void update_window(const sclwindow window, scl16 x = 0, scl16 y = 0, scl16 width = 0, scl16 height = 0);
+    sclboolean get_window_rect(const sclwindow window, SclRectangle *rect);
+    sclwindow get_base_window();
+    sclboolean is_base_window(sclwindow window);
+    sclwindow find_by_etcinfo(void* etc_info);
+    scl8 find_popup_window_index(sclwindow window);
+    //SclWindowContext* get_window_context(sclwindow window, sclboolean geometry_update = FALSE);
+    SclWindowContext* get_window_context(sclwindow window);
+    void set_window_context(sclwindow window, SclWindowContext* context);
+
+    sclwindow create_magnifier_window(const sclwindow parent, scl16 x, scl16 y, scl16 width, scl16 height);
+    sclwindow get_magnifier_window();
+
+    sclwindow get_nth_window_in_Z_order_list(sclbyte index);
+    sclwindow get_nth_popup_window(sclbyte index);
+    sclbyte get_Z_order(sclwindow window);
+
+    sclwindow create_dim_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height);
+    sclwindow get_dim_window();
+
+    void set_update_pending(sclboolean pend);
+    sclboolean get_update_pending();
+
+    void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data);
+
+protected :
+    CSCLWindowsImpl* get_scl_windows_impl();
+
+    sclwindow create_window(const SclWindowOpener opener, const SclRectangle &geometry,
+        sclshort inputmode, sclshort layout, SCLPopupType popup_type, sclboolean is_virtual,
+        sclint img_offset_x = 0, sclint img_offset_y = 0, sclint timeout = 0);
+    bool destroy_window(sclwindow window);
+
+    void push_window_in_Z_order_list(sclwindow window);
+    void pop_window_in_Z_order_list(sclwindow window);
+
+private :
+    CSCLWindowsImpl* m_impl;
+    SclWindowContext m_base_window_context;
+    SclWindowContext m_popup_window_context[MAX_POPUP_WINDOW];
+
+    SclWindowContext m_magnifier_window_context;
+    SclWindowContext m_dim_window_context;
+
+    sclboolean m_pending_update;
+    sclboolean m_initialized;
+
+    sclwindow m_Z_order_list[MAX_ZORDER_NUM];
+};
+
+
+} /* End of scl namespace */
+
+#ifdef __cplusplus
+//SCL_END_DECLS
+#endif
+
+#endif //__SCL_WINDOWS_H__
diff --git a/scl/string_bin_parser.cpp b/scl/string_bin_parser.cpp
new file mode 100644 (file)
index 0000000..a912cdb
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012 - 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 <string>
+#include <string.h>
+#include <stdio.h>
+#include "string_bin_parser.h"
+using namespace std;
+
+String_Bin_Parser::String_Bin_Parser(const FileStorage& storage, int offset, int size) {
+    m_storage.get_storage(storage, offset, size);
+    parse();
+}
+
+/*delete all strings*/
+String_Bin_Parser::~String_Bin_Parser() {
+    m_vec_str_depository.clear();
+}
+void
+String_Bin_Parser::parse() {
+    /* from the string encoder rule*/
+    static const int MAX_NUM_WIDTH = 4;
+
+    /* get the strings' num*/
+    int size = m_storage.get<sint_t>(MAX_NUM_WIDTH);
+
+    /* get each string */
+    for (int i = 0; i < size; ++i) {
+        const char* temp = m_storage.get_str();
+        m_vec_str_depository.push_back(temp);
+    }
+}
+
diff --git a/scl/string_bin_parser.h b/scl/string_bin_parser.h
new file mode 100644 (file)
index 0000000..64c08d9
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 - 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 __STRING_BIN_PARSER_H__
+#define __STRING_BIN_PARSER_H__
+#include <string>
+#include <vector>
+#include "file_storage_impl.h"
+class String_Bin_Parser{
+    public:
+    String_Bin_Parser(const FileStorage& storage, int offset, int size);
+    ~String_Bin_Parser();
+    const std::vector<const char*>& get_string_depository()const {
+        return m_vec_str_depository;
+    }
+    private:
+    void parse();
+    std::vector<const char*> m_vec_str_depository;
+    FileStorage m_storage;
+};
+#endif
diff --git a/scl/string_collector.h b/scl/string_collector.h
new file mode 100644 (file)
index 0000000..5473117
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012 - 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 __NEW_STRING_COLLECTOR_H__
+#define __NEW_STRING_COLLECTOR_H__
+#include <vector>
+#include "istring_collector.h"
+class StringCollector: public IStringCollector{
+    public:
+        StringCollector() {
+        }
+        void add(char* str) {
+            if (str != NULL) {
+                m_vec_string_collection.push_back(str);
+            }
+        }
+        ~StringCollector() {
+            std::vector<char*>::iterator it;
+            for (it = m_vec_string_collection.begin();
+                    it != m_vec_string_collection.end(); ++it) {
+                char* p = *it;
+                if (p) {
+                    delete[] p;
+                }
+
+                p = NULL;
+            }
+
+            m_vec_string_collection.clear();
+        }
+
+    private:
+        std::vector<char*> m_vec_string_collection;
+};
+#endif
diff --git a/scl/string_provider.h b/scl/string_provider.h
new file mode 100644 (file)
index 0000000..a29b7b7
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 - 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 __STRING_PROVIDER_H__
+#define __STRING_PROVIDER_H__
+#include <string>
+#include <vector>
+#include "string_bin_parser.h"
+#include "istring_provider.h"
+class String_Provider: public IString_Provider{
+    public:
+        String_Provider(const String_Bin_Parser* sp): m_sp(sp) {}
+        const char* get_string_by_id(int id)const {
+            if (m_sp == NULL) return NULL;
+
+            const std::vector<const char*>& string_depository = m_sp->get_string_depository();
+            if (id >= 0 && id < (int)string_depository.size())
+                return string_depository.at(id);
+
+            return NULL;
+        }
+    private:
+        const String_Bin_Parser *m_sp;
+};
+#endif
diff --git a/scl/xml_parser_utils.cpp b/scl/xml_parser_utils.cpp
new file mode 100644 (file)
index 0000000..5ec17c0
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012 - 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 "xml_parser_utils.h"
+#include <string.h>
+#include <assert.h>
+#include <sstream>
+
+using namespace std;
+
+int
+get_content_int(const xmlNodePtr cur_node) {
+    assert(cur_node != NULL);
+
+    int num = -1;
+
+    xmlChar* key = xmlNodeGetContent(cur_node);
+    if (key!= NULL) {
+        if (0 == strcmp("NOT_USED", (const char*)key)) {
+            num = -1;
+        } else {
+            num = atoi((const char*)key);
+        }
+        xmlFree(key);
+    }
+    return num;
+}
+
+bool
+get_content_bool(const xmlNodePtr cur_node) {
+    assert(cur_node != NULL);
+
+    bool bVal = false;
+
+    xmlChar* key = xmlNodeGetContent(cur_node);
+
+    if (key != NULL) {
+        if (0 == xmlStrcmp(key, (const xmlChar*)"true")) {
+            bVal = true;
+        }
+        xmlFree(key);
+    }
+    return bVal;
+}
+
+bool
+equal_prop(const xmlNodePtr cur_node, const char* prop, const char* str) {
+    bool val = false;
+
+    xmlChar* key = xmlGetProp(cur_node, (const xmlChar*)prop);
+
+    if (NULL != key) {
+        if (0 == xmlStrcmp(key, (const xmlChar*)str)) {
+            val = true;
+        }
+        xmlFree(key);
+    }
+
+    return val;
+}
+
+bool
+get_prop_bool(const xmlNodePtr cur_node, const char* prop, sclboolean *ret) {
+    assert(cur_node != NULL);
+
+    bool succeeded = false;
+
+    xmlChar* key = xmlGetProp(cur_node, (const xmlChar*)prop);
+
+    if (ret && key != NULL) {
+        succeeded = true;
+        if (0 == xmlStrcmp(key, (const xmlChar*)"true")) {
+            *ret = true;
+        } else {
+            *ret = false;
+        }
+        xmlFree(key);
+    }
+
+    return succeeded;
+}
+
+int
+dex_string_to_int(const char* str) {
+    assert(str != NULL);
+
+    int val = -1;
+    stringstream convertor(str);
+
+    convertor >> hex >> val;
+    if (convertor.fail() == true) {
+        val = -1;
+    }
+
+    return val;
+}
+
+int
+get_content_dex_string_int(const xmlNodePtr cur_node) {
+    assert(NULL != cur_node);
+
+    int val = -1;
+
+    xmlChar* key = xmlNodeGetContent(cur_node);
+
+    if (key != NULL) {
+        val = dex_string_to_int((const char*)key);
+        xmlFree(key);
+    }
+
+    return val;
+}
+
diff --git a/scl/xml_parser_utils.h b/scl/xml_parser_utils.h
new file mode 100644 (file)
index 0000000..b72faf2
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012 - 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 __XML_PARSER_UTILS_H__
+#define __XML_PARSER_UTILS_H__
+#include <assert.h>
+#include <limits.h>
+#include <libxml/parser.h>
+#include "scltypes.h"
+
+using namespace scl;
+
+int get_content_int(const xmlNodePtr cur_node);
+bool get_content_bool(const xmlNodePtr cur_node);
+
+
+bool equal_prop(const xmlNodePtr cur_node, const char* prop, const char* str);
+
+template <class T>
+bool get_prop_number(const xmlNodePtr cur_node, const char* prop, T *ret) {
+    assert(cur_node != NULL);
+
+    bool succeeded = false;
+
+    xmlChar* key = xmlGetProp(cur_node, (const xmlChar*)prop);
+
+    if (ret && key != NULL) {
+        succeeded = true;
+        *ret = (T)atoi((const char*)key);
+        xmlFree(key);
+    }
+
+    return succeeded;
+}
+bool get_prop_bool(const xmlNodePtr cur_node, const char* prop, sclboolean *ret);
+int dex_string_to_int(const char* str);
+int get_content_dex_string_int(const xmlNodePtr cur_node);
+#endif
diff --git a/scl/xmlresource.cpp b/scl/xmlresource.cpp
new file mode 100644 (file)
index 0000000..a3a917d
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2012 - 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 <libxml/parser.h>
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include "xmlresource.h"
+#include "simple_debug.h"
+using namespace std;
+using namespace xmlresource;
+
+string g_entry_filepath;
+
+XMLResource::XMLResource() {
+    m_main_entry_parser = NULL;
+    m_input_mode_configure_parser = NULL;
+    m_layout_parser = NULL;
+    m_modifier_decoration_parser = NULL;
+    m_label_properties_parser = NULL;
+    m_default_configure_parser = NULL;
+    m_autopopup_configure_parser = NULL;
+    m_magnifier_configure_parser = NULL;
+    m_nine_patch_file_list_parser = NULL;
+}
+
+XMLResource::~XMLResource() {
+    m_main_entry_parser = NULL;
+    m_input_mode_configure_parser = NULL;
+    m_layout_parser = NULL;
+    m_modifier_decoration_parser = NULL;
+    m_label_properties_parser = NULL;
+    m_default_configure_parser = NULL;
+    m_autopopup_configure_parser = NULL;
+    m_magnifier_configure_parser = NULL;
+    m_nine_patch_file_list_parser = NULL;
+}
+
+XMLResource*
+XMLResource::get_instance() {
+    static XMLResource instance;
+    return &instance;
+}
+
+static void
+get_layout_files(PSclInputModeConfigure input_mode_table,
+    size_t input_mode_size, vector<string> &vec_file) {
+    vec_file.clear();
+    for (unsigned int mode = 0; mode < input_mode_size; mode++) {
+        SclInputModeConfigure &input_mode = input_mode_table[mode];
+        for (int direct = 0; direct < DISPLAYMODE_MAX; direct++) {
+            char * layout_file_path = input_mode.layouts[direct];
+            if (layout_file_path
+                    && 0 != strcmp(layout_file_path, "")) {
+                vec_file.push_back(layout_file_path);
+            }
+        }
+    }
+
+    // quick sort
+    std::sort(vec_file.begin(), vec_file.end());
+    // use std::unique() to puts duplicates to the [last, end)
+    vector<string>::iterator last = std::unique(vec_file.begin(), vec_file.end());
+    // remove the duplicated items, [last, end)
+    vec_file.erase(last, vec_file.end());
+}
+
+void
+XMLResource::init(const char *entry_filepath) {
+    g_entry_filepath = entry_filepath;
+    if (m_main_entry_parser == NULL) {
+        m_main_entry_parser = MainEntryParser::get_instance();
+        char input_file[_POSIX_PATH_MAX] = {0};
+        snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), entry_filepath);
+        if (0 != m_main_entry_parser->init(input_file)) {
+            /* main entry is necessary */
+            SCLLOG(SclLog::ERROR, "main entry init");
+        }
+    }
+
+    /* get each type of xml file name */
+    XMLFiles& xml_files = m_main_entry_parser->get_xml_files();
+
+    SCLLOG(SclLog::MESSAGE, "init inputmode configure\n\n");
+    if (m_input_mode_configure_parser == NULL) {
+        m_input_mode_configure_parser = InputModeConfigParser::get_instance();
+        char input_file[_POSIX_PATH_MAX] = {0};
+        snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.input_mode_configure);
+        if (0 != m_input_mode_configure_parser->init(input_file)) {
+            /* input mode configure is necessary */
+            SCLLOG(SclLog::ERROR, "input mode configure init");
+        }
+    }
+
+    SCLLOG(SclLog::MESSAGE, "init default_configure\n\n");
+    if (m_default_configure_parser == NULL) {
+        m_default_configure_parser = DefaultConfigParser::get_instance();
+        char input_file[_POSIX_PATH_MAX] = {0};
+        snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.default_configure);
+
+        if (0 != m_default_configure_parser->init(input_file)) {
+            /* default configure is not necessary */
+            SCLLOG(SclLog::WARNING, "default configure init");
+        }
+    }
+
+    SCLLOG(SclLog::MESSAGE, "init modifier_decoration\n\n");
+    if (m_modifier_decoration_parser == NULL) {
+        m_modifier_decoration_parser = ModifierDecorationParser::get_instance();
+        char input_file[_POSIX_PATH_MAX] = {0};
+        snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.modifier_decoration);
+
+        if (0 != m_modifier_decoration_parser->init(input_file)) {
+            /* modifier decoration is not necessary */
+            SCLLOG(SclLog::WARNING, "modifier decoration init");
+        }
+    }
+    SCLLOG(SclLog::MESSAGE, "init label_properties\n\n");
+    if (m_label_properties_parser == NULL) {
+        m_label_properties_parser = LabelPropertyParser::get_instance();
+        char input_file[_POSIX_PATH_MAX] = {0};
+        snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.key_label_property);
+
+        if (0 != m_label_properties_parser->init(input_file)) {
+            /* label properties is not necessary */
+            SCLLOG(SclLog::WARNING, "label properties init");
+        }
+    }
+
+    SCLLOG(SclLog::MESSAGE, "init autopopup_configure\n\n");
+    if (m_autopopup_configure_parser == NULL) {
+        m_autopopup_configure_parser = AutoPopupConfigParser::get_instance();
+        char input_file[_POSIX_PATH_MAX] = {0};
+        snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.autopopup_configure);
+        if (0 != m_autopopup_configure_parser->init(input_file)) {
+            /* autopopup configure is not necessary */
+            SCLLOG(SclLog::WARNING, "autopopup configure init");
+        }
+    }
+    SCLLOG(SclLog::MESSAGE, "init magnifier_configure\n\n");
+    if (m_magnifier_configure_parser == NULL) {
+        m_magnifier_configure_parser = MagnifierConfigParser::get_instance();
+        char input_file[_POSIX_PATH_MAX] = {0};
+        snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.magnifier_configure);
+
+        if (0 != m_magnifier_configure_parser->init(input_file)) {
+            /* magnifier configure is not necessary */
+            SCLLOG(SclLog::WARNING, "magnifier configure init");
+        }
+    }
+
+    SCLLOG(SclLog::MESSAGE, "init nine_patch_file_list\n\n");
+    if (m_nine_patch_file_list_parser == NULL) {
+        m_nine_patch_file_list_parser = NinePatchFileParser::get_instance();
+        char input_file[_POSIX_PATH_MAX] = {0};
+        snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.nine_patch_file_list);
+
+        if (0 != m_nine_patch_file_list_parser->init(input_file)) {
+            /* nine patch file list is not necessary */
+            SCLLOG(SclLog::WARNING, "nine patch file list init");
+        }
+    }
+
+    SCLLOG(SclLog::MESSAGE, "init layout\n\n");
+    if (m_layout_parser == NULL) {
+        m_layout_parser = LayoutParser::get_instance();
+
+        vector<string> vec_layout_file_name;
+        get_layout_files(
+            m_input_mode_configure_parser->get_input_mode_configure_table(),
+            m_input_mode_configure_parser->get_inputmode_size(),
+            vec_layout_file_name);
+        if ( 0 != m_layout_parser->init(get_resource_directory(),
+            vec_layout_file_name)) {
+            /* layout is necessary */
+            SCLLOG(SclLog::ERROR, "layout init");
+        }
+    }
+
+    SCLLOG(SclLog::MESSAGE, "init Text XML resources OK.\n\n");
+}
+
+
+void
+XMLResource::load(int layout_id) {
+    m_layout_parser->load(layout_id);
+}
+
+void
+XMLResource::unload() {
+    m_layout_parser->unload();
+}
+
+bool
+XMLResource::loaded(int layout_id) {
+    return m_layout_parser->loaded(layout_id);
+}
+
+void
+XMLResource::reload() {
+    if (m_main_entry_parser) {
+        char input_file[_POSIX_PATH_MAX] = { 0 };
+        snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), g_entry_filepath.c_str());
+        if (0 != m_main_entry_parser->reload(input_file)) {
+            /* main entry is necessary */
+            SCLLOG(SclLog::ERROR, "main entry reload");
+        }
+
+        /* get each type of xml file name */
+        XMLFiles& xml_files = m_main_entry_parser->get_xml_files();
+
+        if (m_input_mode_configure_parser) {
+            char input_file[_POSIX_PATH_MAX] = { 0 };
+            snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.input_mode_configure);
+            if (0 != m_input_mode_configure_parser->reload(input_file)) {
+                /* input mode configure is necessary */
+                SCLLOG(SclLog::ERROR, "input mode configure reload");
+            }
+        }
+
+        SCLLOG(SclLog::MESSAGE, "reload default_configure\n\n");
+        if (m_default_configure_parser) {
+            char input_file[_POSIX_PATH_MAX] = { 0 };
+            snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.default_configure);
+
+            if (0 != m_default_configure_parser->reload(input_file)) {
+                /* default configure is not necessary */
+                SCLLOG(SclLog::WARNING, "default configure reload");
+            }
+        }
+
+        SCLLOG(SclLog::MESSAGE, "reload modifier_decoration\n\n");
+        if (m_modifier_decoration_parser) {
+            char input_file[_POSIX_PATH_MAX] = { 0 };
+            snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.modifier_decoration);
+
+            if (0 != m_modifier_decoration_parser->reload(input_file)) {
+                /* modifier decoration is not necessary */
+                SCLLOG(SclLog::WARNING, "modifier decoration reload");
+            }
+        }
+        SCLLOG(SclLog::MESSAGE, "reload label_properties\n\n");
+        if (m_label_properties_parser) {
+            char input_file[_POSIX_PATH_MAX] = { 0 };
+            snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.key_label_property);
+
+            if (0 != m_label_properties_parser->reload(input_file)) {
+                /* label properties is not necessary */
+                SCLLOG(SclLog::WARNING, "label properties reload");
+            }
+        }
+
+        SCLLOG(SclLog::MESSAGE, "reload autopopup_configure\n\n");
+        if (m_autopopup_configure_parser) {
+            char input_file[_POSIX_PATH_MAX] = { 0 };
+            snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.autopopup_configure);
+            if (0 != m_autopopup_configure_parser->reload(input_file)) {
+                /* autopopup configure is not necessary */
+                SCLLOG(SclLog::WARNING, "autopopup configure reload");
+            }
+        }
+        SCLLOG(SclLog::MESSAGE, "reload magnifier_configure\n\n");
+        if (m_magnifier_configure_parser) {
+            char input_file[_POSIX_PATH_MAX] = { 0 };
+            snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.magnifier_configure);
+
+            if (0 != m_magnifier_configure_parser->reload(input_file)) {
+                /* magnifier configure is not necessary */
+                SCLLOG(SclLog::WARNING, "magnifier configure reload");
+            }
+        }
+
+        SCLLOG(SclLog::MESSAGE, "reload nine_patch_file_list\n\n");
+        if (m_nine_patch_file_list_parser) {
+            char input_file[_POSIX_PATH_MAX] = { 0 };
+            snprintf(input_file, _POSIX_PATH_MAX, "%s/%s", get_resource_directory(), xml_files.nine_patch_file_list);
+
+            if (0 != m_nine_patch_file_list_parser->reload(input_file)) {
+                /* nine patch file list is not necessary */
+                SCLLOG(SclLog::WARNING, "nine patch file list reload");
+            }
+        }
+
+        SCLLOG(SclLog::MESSAGE, "reload layout\n\n");
+        if (m_layout_parser && m_input_mode_configure_parser) {
+            vector<string> vec_layout_file_name;
+            get_layout_files(
+                m_input_mode_configure_parser->get_input_mode_configure_table(),
+                m_input_mode_configure_parser->get_inputmode_size(),
+                vec_layout_file_name);
+            if (0 != m_layout_parser->reload(get_resource_directory(),
+                vec_layout_file_name)) {
+                /* layout is necessary */
+                SCLLOG(SclLog::ERROR, "layout init");
+            }
+        }
+    }
+}
+
+SclNinePatchInfo*
+XMLResource::get_nine_patch_list() {
+    return m_nine_patch_file_list_parser->get_nine_patch_list();
+}
+
+int
+XMLResource::get_labelproperty_size() {
+    return m_label_properties_parser->get_size();
+}
+
+bool
+XMLResource::get_nine_patch_info(const char *filename, SclNinePatchInfo *info) {
+    return m_nine_patch_file_list_parser->get_nine_patch_info(filename, info);
+}
+
+int
+XMLResource::get_inputmode_id(const char *name) {
+    return m_input_mode_configure_parser->get_inputmode_id(name);
+}
+
+const char*
+XMLResource::get_inputmode_name(int id) {
+    return m_input_mode_configure_parser->get_inputmode_name(id);
+}
+
+int
+XMLResource::get_inputmode_size() {
+    return m_input_mode_configure_parser->get_inputmode_size();
+}
+
+PSclInputModeConfigure
+XMLResource::get_input_mode_configure_table() {
+    return m_input_mode_configure_parser->get_input_mode_configure_table();
+}
+
+int
+XMLResource::get_layout_id(const char *name) {
+    return m_layout_parser->get_layout_index(name);
+}
+
+int
+XMLResource::get_layout_size() {
+    return m_layout_parser->get_layout_size();
+}
+
+int
+XMLResource::get_modifier_decoration_id(const char *name) {
+    return m_modifier_decoration_parser->get_modifier_decoration_id(name);
+}
+
+PSclLayout
+XMLResource::get_layout_table() {
+    return m_layout_parser->get_layout_table();
+}
+
+PSclLayoutKeyCoordinatePointerTable
+XMLResource::get_key_coordinate_pointer_frame() {
+    return m_layout_parser->get_key_coordinate_pointer_frame();
+}
+
+PSclModifierDecoration
+XMLResource::get_modifier_decoration_table() {
+    return m_modifier_decoration_parser->get_modifier_decoration_table();
+}
+
+PSclLabelPropertiesTable
+XMLResource::get_label_properties_frame() {
+    return m_label_properties_parser->get_label_properties_frame();
+}
+
+PSclDefaultConfigure
+XMLResource::get_default_configure() {
+    return m_default_configure_parser->get_default_configure();
+}
+
+PSclAutoPopupConfigure
+XMLResource::get_autopopup_configure() {
+    return m_autopopup_configure_parser->get_autopopup_configure();
+}
+
+PSclMagnifierWndConfigure
+XMLResource::get_magnifier_configure() {
+    return m_magnifier_configure_parser->get_magnifier_configure();
+}
diff --git a/scl/xmlresource.h b/scl/xmlresource.h
new file mode 100644 (file)
index 0000000..7552999
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012 - 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 __XMLRESOURCE__
+#define __XMLRESOURCE__
+
+#include "main_entry_parser.h"
+#include "input_mode_configure_parser.h"
+#include "layout_parser.h"
+#include "modifier_decoration_parser.h"
+#include "label_properties_parser.h"
+#include "default_configure_parser.h"
+#include "autopopup_configure_parser.h"
+#include "magnifier_configure_parser.h"
+#include "nine_patch_file_list_parser.h"
+#include "sclres.h"
+
+namespace xmlresource {
+class XMLResource: public sclres::SclRes{
+    public:
+    ~XMLResource();
+    static XMLResource* get_instance();
+    void init(const char *entry_filepath);
+    void reload();
+
+    /* These functions are for dynamic (lazy) loading layouts */
+    void load(int layout_id);
+    void unload();
+    bool loaded(int layout_id);
+
+    public:
+    PSclInputModeConfigure get_input_mode_configure_table();
+    PSclLayout get_layout_table();
+    PSclLayoutKeyCoordinatePointerTable get_key_coordinate_pointer_frame();
+    PSclModifierDecoration get_modifier_decoration_table();
+    PSclLabelPropertiesTable get_label_properties_frame();
+    PSclDefaultConfigure get_default_configure();
+    PSclAutoPopupConfigure get_autopopup_configure();
+    PSclMagnifierWndConfigure get_magnifier_configure();
+    SclNinePatchInfo* get_nine_patch_list();
+    int get_inputmode_id(const char *name);
+    const char* get_inputmode_name(int id);
+    int get_inputmode_size();
+    int get_layout_id(const char* name);
+    int get_layout_size();
+    int get_labelproperty_size();
+    int get_modifier_decoration_id(const char *name);
+    bool get_nine_patch_info(const char *filename, SclNinePatchInfo *info);
+
+    const char* get_name() {
+        return "xmlparser";
+    }
+
+    private:
+    XMLResource();
+
+    private:
+    MainEntryParser *m_main_entry_parser;
+    InputModeConfigParser *m_input_mode_configure_parser;
+    LayoutParser *m_layout_parser;
+    ModifierDecorationParser *m_modifier_decoration_parser;
+    LabelPropertyParser *m_label_properties_parser;
+    DefaultConfigParser *m_default_configure_parser;
+    AutoPopupConfigParser *m_autopopup_configure_parser;
+    MagnifierConfigParser *m_magnifier_configure_parser;
+    NinePatchFileParser *m_nine_patch_file_list_parser;
+};
+}
+
+#endif
+
diff --git a/xml2binary/CMakeLists.txt b/xml2binary/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d5dbcd3
--- /dev/null
@@ -0,0 +1,70 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(xml2binary CXX)
+
+SET(SRCS
+    ../xmlresource/autopopup_configure_parser.cpp
+    ../xmlresource/default_configure_parser.cpp
+    ../xmlresource/input_mode_configure_parser.cpp
+    ../xmlresource/label_properties_parser.cpp
+    ../xmlresource/layout_parser.cpp
+    ../xmlresource/layout_parser_helper.cpp
+    ../xmlresource/magnifier_configure_parser.cpp
+    ../xmlresource/main_entry_parser.cpp
+    ../xmlresource/modifier_decoration_parser.cpp
+    ../xmlresource/nine_patch_file_list_parser.cpp
+    ../xmlresource/xml_parser_utils.cpp
+    ../xmlresource/xmlresource.cpp
+    encode_metadata.cpp
+    encode_input_mode_configure.cpp
+    encode_layout.cpp
+    encode_key_coordinate_frame.cpp
+    encode_label_properties_frame.cpp
+    encode_default_configure.cpp
+    encode_autopopup_configure.cpp
+    encode_magnifier_configure.cpp
+    encode_modifier_decoration.cpp
+    encode_nine_patch.cpp
+    metadata_handler.cpp
+    xml2dat.cpp
+    ../sclres/sclres.cpp
+    ../res/simple_debug.cpp
+)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(BINDIR "${PREFIX}/bin")
+SET(METADATADIR "${PREFIX}/share/libscl-ui")
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+    SET(CMAKE_BUILD_TYPE "Release")
+ENDIF()
+MESSAGE(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/xml2binary/include
+                    ${CMAKE_SOURCE_DIR}/xmlresource/include
+                    ${CMAKE_SOURCE_DIR}/scl/include
+                    ${CMAKE_SOURCE_DIR}/res
+                    ${CMAKE_SOURCE_DIR}/sclres )
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+        elementary
+        libxml-2.0
+        glib-2.0
+        dlog
+        )
+
+FOREACH(flag ${pkgs_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpie -Wall")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -g")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR})
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/metadata.xml DESTINATION ${METADATADIR})
diff --git a/xml2binary/data/auto_codes.py b/xml2binary/data/auto_codes.py
new file mode 100755 (executable)
index 0000000..4319b89
--- /dev/null
@@ -0,0 +1,82 @@
+#!/usr/bin/python
+
+from xml.dom import minidom
+import shutil, os
+
+def write_note(output):
+    output.writelines("/*This file is generated by auto_codes.py.*/\n\n")
+
+def get_record_width_struct_name(record_name):
+    return (record_name + "_width").capitalize()
+
+def get_metadata(filename='metadata.xml'):
+    doc = minidom.parse(filename)
+    root = doc.documentElement
+
+    record_nodes = root.getElementsByTagName('record')
+    record_list = []
+    for record_node in record_nodes:
+        record_name = record_node.getAttribute('name')
+        fields_node = record_node.getElementsByTagName('field')
+
+        field_list = []
+        for field_node in fields_node:
+            field_name = field_node.getAttribute('name')
+            field_type = field_node.getAttribute('type')
+            field_data = {"name":field_name, "type":field_type}
+            field_list.append(field_data)
+        record_data = {"name":record_name, "field_list":field_list}
+        record_list.append(record_data);
+    return record_list
+
+def gen_auto_metadata_h(record_list):
+    output = open('_auto_metadata.h', 'w')
+    write_note(output)
+    codes_list = []
+    codes_list.append('#ifndef __AUTO_METADATA_H__\n')
+    codes_list.append('#define __AUTO_METADATA_H__\n\n')
+
+    codes_list.append('#include <memory.h>\n')
+    for record_data in record_list:
+        struct_name = get_record_width_struct_name(record_data['name'])
+
+        codes_list.append("typedef struct _" + struct_name +  " {\n")
+        field_list = record_data['field_list']
+        for field_data in field_list:
+            codes_list.append("\tint " + field_data['name'] + ";\n")
+
+
+        codes_list.append("}" + struct_name + ";");
+        codes_list.append("\n\n")
+
+    for record_data in record_list:
+        function_name = "set_" + record_data['name'] + "_width"
+        struct_name = get_record_width_struct_name(record_data['name'])
+        parameter = "T& md_helper,\n\t";
+        parameter += struct_name + " & " + "record_width"
+        codes_list.append("template <class T>\n")
+        codes_list.append("void " + function_name + "(" + parameter + ") {\n")
+        codes_list.append("\tmd_helper.set_current_metadata_record(\"" + record_data['name'] + "\");\n")
+        codes_list.append("\tmemset(&record_width, 0x00, sizeof("+ struct_name +"));\n")
+        codes_list.append("\n")
+
+        field_list = record_data['field_list']
+        for field_data in field_list:
+            codes_list.append("\trecord_width." + field_data['name'] + " = md_helper.get_width(\"" + field_data['name'] + "\");\n")
+        codes_list.append('}\n\n')
+
+    codes_list.append("\n")
+    codes_list.append('#endif //End __AUTO_METADATA_H__\n')
+    output.writelines(codes_list)
+    output.close()
+
+record_list = get_metadata()
+gen_auto_metadata_h(record_list)
+shutil.copyfile('_auto_metadata.h', '../include/_auto_metadata.h')
+shutil.copyfile('_auto_metadata.h', '../../binary_xmlresource/include/_auto_metadata.h')
+os.remove('_auto_metadata.h')
+
+print '\n'
+print '----MESSAGE-----\n'
+print '_auto_metadata.h is generated in ../include/_auto_metadata.h successfully\n'
+print '_auto_metadata.h is generated in ../../binary_xmlresource/include/_auto_metadata.h successfully\n'
diff --git a/xml2binary/data/metadata.xml b/xml2binary/data/metadata.xml
new file mode 100644 (file)
index 0000000..ad81a7c
--- /dev/null
@@ -0,0 +1,172 @@
+<!--Example of metadata.xml -->
+<!-- 1. the order of the field list in record is not sensitive -->
+
+<metadata version = "0.1">
+<metadata_type>
+    <type name = "string_id" width = "2"/>
+</metadata_type>
+<record name = "input_mode_configure">
+    <field name = "name" type = "string_id" />
+    <field name = "layout_portrait" type = "string_id" />
+    <field name = "layout_landscape" type = "string_id" />
+    <field name = "use_virtual_window" type = "int8" />
+    <field name = "use_dim_window" type = "int8" />
+    <field name = "timeout" type = "int32" />
+</record>
+<record name = "layout">
+    <field name = "name" type = "string_id"/>
+    <field name = "display_mode" type = "int8"/>
+    <field name = "style" type = "int8"/>
+    <field name = "width" type = "int16"/>
+    <field name = "height" type = "int16"/>
+    <field name = "use_sw_button" type = "int8"/>
+    <field name = "use_magnifier_window" type = "int8"/>
+    <field name = "extract_background" type = "int8"/>
+    <field name = "key_width" type = "int16"/>
+    <field name = "key_height" type = "int16"/>
+    <field name = "key_spacing" type = "int16"/>
+    <field name = "row_spacing" type = "int16"/>
+    <field name = "use_sw_background" type = "int8"/>
+    <field name = "bg_color" type = "int8"/>
+    <field name = "bg_line_width" type = "float32"/>
+    <field name = "bg_line_color" type = "int8"/>
+    <field name = "add_grab_left" type = "int16"/>
+    <field name = "add_grab_right" type = "int16"/>
+    <field name = "add_grab_top" type = "int16"/>
+    <field name = "add_grab_bottom" type = "int16"/>
+    <field name = "image_path" type = "string_id"/>
+    <field name = "key_background_image" type = "string_id"/>
+    <field name = "sound_style" type = "string_id"/>
+    <field name = "vibe_style" type = "string_id"/>
+    <field name = "label_type" type = "string_id"/>
+    <field name = "modifier_decorator" type = "string_id"/>
+</record>
+<record name = "key_coordinate_record">
+    <field name = "x" type = "int16"/>
+    <field name = "y" type = "int16"/>
+    <field name = "width" type = "int16"/>
+    <field name = "height" type = "int16"/>
+    <field name = "add_hit_left" type = "int16"/>
+    <field name = "add_hit_right" type = "int16"/>
+    <field name = "add_hit_top" type = "int16"/>
+    <field name = "add_hit_bottom" type = "int16"/>
+    <field name = "popup_relative_x" type = "int16"/>
+    <field name = "popup_relative_y" type = "int16"/>
+    <field name = "extract_offset_x" type = "int16"/>
+    <field name = "extract_offset_y" type = "int16"/>
+    <field name = "sub_layout" type = "string_id"/>
+    <field name = "magnifier_offset_x" type = "int16"/>
+    <field name = "magnifier_offset_y" type = "int16"/>
+    <field name = "custom_id" type = "string_id"/>
+    <field name = "button_type" type = "int8"/>
+    <field name = "key_type" type = "int8"/>
+    <field name = "popup_type" type = "int8"/>
+    <field name = "use_magnifier" type = "int8"/>
+    <field name = "use_long_key_magnifier" type = "int8"/>
+    <field name = "popup_input_mode" type = "string_id"/>
+    <field name = "sound_style" type = "string_id"/>
+    <field name = "vibe_style" type = "string_id"/>
+    <field name = "is_side_button" type = "int8"/>
+    <field name = "label_count" type = "int16"/>
+    <field name = "label" type = "int16"/>
+    <field name = "label_type" type = "int16"/>
+    <field name = "image_label_path" type = "int16"/>
+    <field name = "image_label_type" type = "int16"/>
+    <field name = "bg_image_path" type = "int16"/>
+    <field name = "key_value_count" type = "int16"/>
+    <field name = "key_value" type = "int16"/>
+    <field name = "key_event" type = "int32"/>
+    <field name = "long_key_type" type = "int8"/>
+    <field name = "long_key_value" type = "int16"/>
+    <field name = "long_key_event" type = "int32"/>
+    <field name = "use_repeat_key" type = "int8"/>
+    <field name = "autopopup_key_labels" type = "string_id"/>
+    <field name = "autopopup_key_values" type = "string_id"/>
+    <field name = "autopopup_key_events" type = "int32"/>
+    <field name = "dont_close_popup" type = "int8"/>
+    <field name = "extra_option" type = "int8"/>
+    <field name = "multitouch_type" type = "int8"/>
+    <field name = "modifier_decorator" type = "string_id"/>
+    <field name = "magnifier_label" type = "string_id"/>
+</record>
+<record name = "label_properties_record">
+    <field name = "label_type" type = "int16"/>
+    <field name = "font_name" type = "int16"/>
+    <field name = "font_size" type = "int16"/>
+    <field name = "font_color" type = "int8"/>
+    <field name = "alignment" type = "int8"/>
+    <field name = "padding_x" type = "int16"/>
+    <field name = "padding_y" type = "int16"/>
+    <field name = "inner_width" type = "int16"/>
+    <field name = "inner_height" type = "int16"/>
+    <field name = "shadow_distance" type = "int16"/>
+    <field name = "shadow_direction" type = "int8"/>
+    <field name = "shadow_color" type = "int8"/>
+</record>
+<record name = "default_configure">
+    <field name = "display_mode" type = "int8"/>
+    <field name = "input_mode" type = "string_id"/>
+    <field name = "image_file_base_path" type = "string_id"/>
+    <field name = "target_screen_width" type = "int16"/>
+    <field name = "target_screen_height" type = "int16"/>
+    <field name = "auto_detect_landscape" type = "int8"/>
+    <field name = "use_magnifier_window" type = "int8"/>
+    <field name = "use_auto_popup" type = "int8"/>
+    <field name = "use_zoom_window" type = "int8"/>
+    <field name = "on_error_noti_send" type = "int8"/>
+    <field name = "use_word_deletion" type = "int8"/>
+    <field name = "sw_button_style" type = "int8"/>
+    <field name = "touch_offset_level" type = "int16"/>
+    <field name = "touch_offset" type = "int16"/>
+    <field name = "default_sub_layout" type = "string_id"/>
+    <field name = "use_actual_dim_window" type = "int8"/>
+    <field name = "dim_color" type = "int8"/>
+</record>
+<record name = "magnifier_configure">
+    <field name = "style" type = "int8"/>
+    <field name = "width" type = "int16"/>
+    <field name = "height" type = "int16"/>
+    <field name = "label_area_rect" type = "int16"/>
+    <field name = "bg_image_path" type = "string_id"/>
+    <field name = "bg_shift_image_path" type = "string_id"/>
+    <field name = "bg_shift_lock_image_path" type = "string_id"/>
+    <field name = "bg_long_key_image_path" type = "string_id"/>
+    <field name = "use_actual_window" type = "int8"/>
+    <field name = "label_type" type = "string_id"/>
+    <field name = "padding_x" type = "int16"/>
+    <field name = "padding_y" type = "int16"/>
+    <field name = "show_shift_label" type = "int8"/>
+</record>
+<record name = "autopopup_configure">
+    <field name = "bg_image_path" type = "string_id"/>
+    <field name = "bg_color" type = "int8"/>
+    <field name = "bg_line_width" type = "float32"/>
+    <field name = "bg_line_color" type = "int8"/>
+    <field name = "bg_padding" type = "int8"/>
+    <field name = "button_image_path" type = "string_id"/>
+    <field name = "sw_button_style" type = "int8"/>
+    <field name = "button_width" type = "int16"/>
+    <field name = "button_height" type = "int16"/>
+    <field name = "button_spacing" type = "int8"/>
+    <field name = "label_type" type = "string_id"/>
+    <field name = "decoration_image_path" type = "string_id"/>
+    <field name = "decoration_size" type = "int8"/>
+    <field name = "max_column" type = "int8"/>
+    <field name = "add_grab_left" type = "int16"/>
+    <field name = "add_grab_right" type = "int16"/>
+    <field name = "add_grab_top" type = "int16"/>
+    <field name = "add_grab_bottom" type = "int16"/>
+</record>
+<record name = "modifier_decoration">
+    <field name = "extract_background" type = "int8"/>
+    <field name = "name" type = "string_id"/>
+    <field name = "bg_image_path" type = "string_id"/>
+</record>
+<record name = "nine_patch">
+    <field name = "image_path" type = "string_id"/>
+    <field name = "left" type = "int16" />
+    <field name = "right" type = "int16" />
+    <field name = "top" type = "int16" />
+    <field name = "bottom" type = "int16" />
+</record>
+</metadata>
diff --git a/xml2binary/encode_autopopup_configure.cpp b/xml2binary/encode_autopopup_configure.cpp
new file mode 100644 (file)
index 0000000..c7ed81c
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012 - 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 "encode_autopopup_configure.h"
+#include "xmlresource.h"
+#include "resource_storage_impl.h"
+#include "put_record.h"
+#include "_auto_metadata.h"
+using namespace xmlresource;
+static void _encode_color(ResourceStorage& storage, const SclColor& color, int width) {
+    if (width <= 0) return;
+
+    storage.put<sint_t>(color.r, width);
+    storage.put<sint_t>(color.g, width);
+    storage.put<sint_t>(color.b, width);
+    storage.put<sint_t>(color.a, width);
+}
+static void
+encode_autopopup_configure_record(ResourceStorage& storage, const PSclAutoPopupConfigure cur, const Autopopup_configure_width& record_width) {
+    //bg_image_path
+    storage.encode_string(cur->bg_image_path, record_width.bg_image_path);
+
+    //bg_color
+    _encode_color(storage, cur->bg_color, record_width.bg_color);
+
+    //double value
+    storage.put<float_t>(cur->bg_line_width, record_width.bg_line_width);
+
+    //bg_line_color
+        _encode_color(storage, cur->bg_line_color, record_width.bg_line_color);
+
+    //bg_padding
+    storage.put<sint_t>(cur->bg_padding, record_width.bg_padding);
+
+    //button_image_path
+    for (int i = 0; i < SCL_BUTTON_STATE_MAX; ++i) {
+        storage.encode_string(cur->button_image_path[i], record_width.button_image_path);
+    }
+
+    //sw_button_style
+    storage.put<sint_t>(cur->sw_button_style, record_width.sw_button_style);
+
+    //button_width
+    storage.put<sint_t>(cur->button_width, record_width.button_width);
+
+    //button_height
+    storage.put<sint_t>(cur->button_height, record_width.button_height);
+
+    //button_spacing
+    storage.put<sint_t>(cur->button_spacing, record_width.button_spacing);
+
+    storage.encode_string(cur->label_type, record_width.label_type);
+
+    for (int i = 0; i < MAX_WND_DECORATOR; ++i) {
+        storage.encode_string(cur->decoration_image_path[i], record_width.decoration_image_path);
+    }
+
+    //decoration_size
+    storage.put<sint_t>(cur->decoration_size, record_width.decoration_size);
+
+    //max_column
+    storage.put<sint_t>(cur->max_column, record_width.max_column);
+
+    //add_grab_left
+    storage.put<sint_t>(cur->add_grab_left, record_width.add_grab_left);
+
+    //add_grab_right
+    storage.put<sint_t>(cur->add_grab_right, record_width.add_grab_right);
+
+    //add_grab_top
+    storage.put<sint_t>(cur->add_grab_top, record_width.add_grab_top);
+
+    //add_grab_bottom
+    storage.put<sint_t>(cur->add_grab_bottom, record_width.add_grab_bottom);
+}
+
+int
+encode_autopopup_configure_file(ResourceStorage& storage, IMetaData_Helper& md_helper) {
+    int init_size = storage.get_size();
+
+    XMLResource *xmlresource = XMLResource::get_instance();
+    PSclAutoPopupConfigure autopopupConfigure = xmlresource->get_autopopup_configure();
+
+#ifdef __SCL_TXT_DEBUG
+    put_autopopup_configure(ENCODE, *autopopupConfigure);
+
+#endif
+
+    Autopopup_configure_width record_width;
+    set_autopopup_configure_width(md_helper, record_width);
+
+    storage.reserve(8);
+
+    encode_autopopup_configure_record(storage, autopopupConfigure, record_width);
+
+    int size = storage.get_size() - init_size;
+    storage.random_put<sint_t>(size, 8, init_size);
+
+    return storage.get_size();
+}
+
+int
+encode_autopopup_configure_file(const char* file, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+    ResourceStorage storage;
+    encode_autopopup_configure_file(storage, md_helper);
+    storage.toFile(file);
+    return storage.get_size();
+}
+int
+encode_autopopup_configure_file(const char* file, int &offset, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+    ResourceStorage storage;
+    encode_autopopup_configure_file(storage, md_helper);
+    storage.toFile(file, offset);
+
+    return storage.get_size();
+}
diff --git a/xml2binary/encode_default_configure.cpp b/xml2binary/encode_default_configure.cpp
new file mode 100644 (file)
index 0000000..55c45da
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2012 - 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 "encode_default_configure.h"
+#include "xmlresource.h"
+#include "resource_storage_impl.h"
+using namespace xmlresource;
+
+#include "put_record.h"
+#include "_auto_metadata.h"
+static void _encode_color(ResourceStorage& storage, const SclColor& color, int width) {
+    if (width <= 0) return;
+
+    storage.put<sint_t>(color.r, width);
+    storage.put<sint_t>(color.g, width);
+    storage.put<sint_t>(color.b, width);
+    storage.put<sint_t>(color.a, width);
+}
+static void
+encode_default_configure_record(ResourceStorage& storage, const PSclDefaultConfigure cur, const Default_configure_width& record_width) {
+    //display_mode
+    storage.put<sint_t>((int)cur->display_mode, record_width.display_mode);
+
+    //input_mode
+    storage.encode_string(cur->input_mode, record_width.input_mode);
+
+    //image_file_base_path
+    storage.encode_string(cur->image_file_base_path, record_width.image_file_base_path);
+
+    //target_screen_width
+    storage.put<sint_t>(cur->target_screen_width, record_width.target_screen_width);
+
+    //target_screen_height
+    storage.put<sint_t>(cur->target_screen_height, record_width.target_screen_height);
+
+    //auto_detect_landscape
+    storage.put<sint_t>(cur->auto_detect_landscape, record_width.auto_detect_landscape);
+
+    //use_magnifier_window
+    storage.put<sint_t>(cur->use_magnifier_window, record_width.use_magnifier_window);
+
+    //use_auto_popup
+    storage.put<sint_t>(cur->use_auto_popup, record_width.use_auto_popup);
+
+    //use_zoom_window
+    storage.put<sint_t>(cur->use_zoom_window, record_width.use_zoom_window);
+
+    //on_error_noti_send
+    storage.put<sint_t>(cur->on_error_noti_send, record_width.on_error_noti_send);
+
+    //use_word_deletion
+    storage.put<sint_t>(cur->use_word_deletion, record_width.use_word_deletion);
+
+    //sw_button_style
+    storage.put<sint_t>(cur->sw_button_style, record_width.sw_button_style);
+
+    //touch_offset_level
+    for (int i = 0; i < DISPLAYMODE_MAX; ++i) {
+        storage.put<sint_t>((int)cur->touch_offset_level[i], record_width.touch_offset_level);
+    }
+
+    //touch_offset
+    for (int i = 0; i < DISPLAYMODE_MAX; ++i) {
+        storage.put<sint_t>((int)cur->touch_offset[i].x, record_width.touch_offset);
+        storage.put<sint_t>((int)cur->touch_offset[i].y, record_width.touch_offset);
+    }
+
+    //default_sub_layout
+    storage.encode_string(cur->default_sub_layout, record_width.default_sub_layout);
+
+    //use_actual_dim_window
+    storage.put<sint_t>(cur->use_actual_dim_window, record_width.use_actual_dim_window);
+
+    //dim_color
+    _encode_color(storage, cur->dim_color, record_width.dim_color);
+}
+
+int
+encode_default_configure_file(ResourceStorage& storage, IMetaData_Helper& md_helper) {
+    int init_size = storage.get_size();
+
+    XMLResource *xmlresource = XMLResource::get_instance();
+    PSclDefaultConfigure defaultConfigure = xmlresource->get_default_configure();
+
+#ifdef __SCL_TXT_DEBUG
+    put_default_configure(ENCODE, *defaultConfigure);
+
+#endif
+    Default_configure_width record_width;
+    set_default_configure_width(md_helper, record_width);
+
+    storage.reserve(8);
+    encode_default_configure_record(storage, defaultConfigure, record_width);
+
+    int size = storage.get_size() - init_size;
+    storage.random_put<sint_t>(size, 8, init_size);
+    return storage.get_size();
+}
+
+int
+encode_default_configure_file(const char* file, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+    encode_default_configure_file(storage, md_helper);
+    storage.toFile(file);
+
+    return storage.get_size();
+}
+
+int
+encode_default_configure_file(const char* file, int& offset, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+    encode_default_configure_file(storage, md_helper);
+    storage.toFile(file, offset);
+
+    return storage.get_size();
+}
diff --git a/xml2binary/encode_input_mode_configure.cpp b/xml2binary/encode_input_mode_configure.cpp
new file mode 100644 (file)
index 0000000..da43390
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012 - 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 "resource_storage_impl.h"
+#include "encode_input_mode_configure.h"
+#include <string>
+#include <libxml/parser.h>
+#include "xmlresource.h"
+#include "imetadata_helper.h"
+#include "put_record.h"
+#include "_auto_metadata.h"
+using namespace std;
+using namespace xmlresource;
+
+static void
+encode_input_mode_configure_record(ResourceStorage& storage, const PSclInputModeConfigure cur, const Input_mode_configure_width& record_width) {
+    //name
+    storage.encode_string(cur->name, record_width.name);
+    //layout_portrait
+    storage.encode_string(cur->layouts[0], record_width.layout_portrait);
+    //layout_landscape
+    storage.encode_string(cur->layouts[1], record_width.layout_landscape);
+    //use_virtual_window
+    storage.put<sint_t>(cur->use_virtual_window, record_width.use_virtual_window);
+    //use_dim_window
+    storage.put<sint_t>(cur->use_dim_window, record_width.use_dim_window);
+    //timeout
+    storage.put<sint_t>(cur->timeout, record_width.timeout);
+}
+
+int encode_input_mode_configure_file(ResourceStorage& storage, IMetaData_Helper& md_helper) {
+    int init_size = storage.get_size();
+    /*size 4bytes*/
+    const int INPUT_MODE_CONFIGURE_SIZE_WIDTH = 4;
+
+
+    XMLResource *xmlresource = XMLResource::get_instance();
+    PSclInputModeConfigure inputModeConfigureTable = xmlresource->get_input_mode_configure_table();
+    int size = xmlresource->get_inputmode_size();
+#ifdef __SCL_TXT_DEBUG
+    put_input_mode_configure_table(ENCODE, inputModeConfigureTable);
+
+#endif
+    PSclInputModeConfigure cur = inputModeConfigureTable;
+
+    //first 8 byte is the size of the block
+    storage.reserve(8);
+    storage.put<sint_t>(size, INPUT_MODE_CONFIGURE_SIZE_WIDTH);
+
+    Input_mode_configure_width record_width;
+    set_input_mode_configure_width(md_helper, record_width);
+    for ( int i = 0; i < size; ++i ) {
+        encode_input_mode_configure_record(storage, cur, record_width);
+        cur++;
+    }
+
+    int advance_size = storage.get_size() - init_size;
+    storage.random_put<sint_t>(advance_size, 8, init_size);
+    return storage.get_size();
+}
+
+int encode_input_mode_configure_file(const char* file, int& offset, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+    encode_input_mode_configure_file(storage, md_helper);
+    storage.toFile(file, offset);
+
+    return storage.get_size();
+}
+
+int encode_input_mode_configure_file(const char* file, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+    encode_input_mode_configure_file(storage, md_helper);
+    storage.toFile(file);
+
+    return storage.get_size();
+}
diff --git a/xml2binary/encode_key_coordinate_frame.cpp b/xml2binary/encode_key_coordinate_frame.cpp
new file mode 100644 (file)
index 0000000..87566c6
--- /dev/null
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2012 - 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 "resource_storage_impl.h"
+#include "encode_key_coordinate_frame.h"
+#include <string>
+#include "xmlresource.h"
+#include "put_record.h"
+#include "_auto_metadata.h"
+using namespace xmlresource;
+using namespace std;
+static void
+encode_key_coordinate_record(ResourceStorage& storage, const PSclLayoutKeyCoordinate cur, const Key_coordinate_record_width& record_width) {
+    if (cur == NULL) return;
+
+    //x
+    storage.put<sint_t>(cur->x, record_width.x);
+
+    //y
+    storage.put<sint_t>(cur->y, record_width.y);
+
+    //width
+    storage.put<sint_t>(cur->width, record_width.width);
+
+    //height
+    storage.put<sint_t>(cur->height, record_width.height);
+
+    //add_hit_left
+    storage.put<sint_t>(cur->add_hit_left, record_width.add_hit_left);
+
+    //add_hit_right
+    storage.put<sint_t>(cur->add_hit_right, record_width.add_hit_right);
+
+    //add_hit_top
+    storage.put<sint_t>(cur->add_hit_top, record_width.add_hit_top);
+
+    //add_hit_bottom
+    storage.put<sint_t>(cur->add_hit_bottom, record_width.add_hit_bottom);
+
+    //popup_relative_x
+    storage.put<sint_t>(cur->popup_relative_x, record_width.popup_relative_x);
+
+    //popup_relative_y
+    storage.put<sint_t>(cur->popup_relative_y, record_width.popup_relative_y);
+
+    //extract_offset_x
+    storage.put<sint_t>(cur->extract_offset_x, record_width.extract_offset_x);
+
+    //extract_offset_y
+    storage.put<sint_t>(cur->extract_offset_y, record_width.extract_offset_y);
+
+    storage.encode_string(cur->sub_layout, record_width.sub_layout);
+
+    //magnifier_offset_x
+    storage.put<sint_t>(cur->magnifier_offset_x, record_width.magnifier_offset_x);
+
+    //magnifier_offset_y
+    storage.put<sint_t>(cur->magnifier_offset_y, record_width.magnifier_offset_y);
+
+    storage.encode_string(cur->custom_id, record_width.custom_id);
+
+    //button_type
+    storage.put<sint_t>(cur->button_type, record_width.button_type);
+
+    //key_type
+    storage.put<sint_t>(cur->key_type, record_width.key_type);
+
+    //popup_type
+    storage.put<sint_t>(cur->popup_type, record_width.popup_type);
+
+    storage.put<sint_t>(cur->use_magnifier, record_width.use_magnifier);
+    storage.put<sint_t>(cur->use_long_key_magnifier, record_width.use_long_key_magnifier);
+
+    //popup_input_mode
+    for (int i = 0; i < SCL_DRAG_STATE_MAX; ++i) {
+        storage.encode_string(cur->popup_input_mode[i], record_width.popup_input_mode);
+    }
+
+    storage.encode_string(cur->sound_style, record_width.sound_style);
+    storage.encode_string(cur->vibe_style, record_width.vibe_style);
+    storage.put<sint_t>(cur->is_side_button, record_width.is_side_button);
+
+    //label_count
+    storage.put<sint_t>(cur->label_count, record_width.label_count);
+
+    //label
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_LABEL_FOR_ONE; ++j) {
+            storage.encode_string(cur->label[i][j], record_width.label);
+        }
+    }
+
+    storage.encode_string(cur->label_type, record_width.label_type);
+
+    //label_image_path
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            storage.encode_string(cur->image_label_path[i][j], record_width.image_label_path);
+        }
+    }
+
+    storage.encode_string(cur->image_label_type, record_width.image_label_type);
+
+    //bg_image_path
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            storage.encode_string(cur->bg_image_path[i][j], record_width.bg_image_path);
+        }
+    }
+
+    //key_value_count
+    storage.put<sint_t>(cur->key_value_count, record_width.key_value_count);
+
+    //key_value
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_MULTITAP_CHAR; ++j) {
+            storage.encode_string(cur->key_value[i][j], record_width.key_value);
+        }
+    }
+    //key_event
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_LABEL_FOR_ONE; ++j) {
+            storage.put<sint_t>(cur->key_event[i][j], record_width.key_event);
+        }
+    }
+
+    storage.put<sint_t>(cur->long_key_type, record_width.long_key_type);
+
+    //long_key_value
+    storage.encode_string(cur->long_key_value, record_width.long_key_value);
+
+    //long_key_event
+    storage.put<sint_t>(cur->long_key_event, record_width.long_key_event);
+
+    storage.put<sint_t>(cur->use_repeat_key, record_width.use_repeat_key);
+
+    //autopopup_keys
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_AUTOPOPUP_STRING; ++j) {
+            storage.encode_string(cur->autopopup_key_labels[i][j], record_width.autopopup_key_labels);
+            storage.encode_string(cur->autopopup_key_values[i][j], record_width.autopopup_key_values);
+            storage.put<sint_t>(cur->autopopup_key_events[i][j], record_width.autopopup_key_events);
+        }
+    }
+
+    storage.put<sint_t>(cur->dont_close_popup, record_width.dont_close_popup);
+
+    //extra_option
+    storage.put<sint_t>(cur->extra_option, record_width.extra_option);
+
+    //multitouch_type
+    storage.put<sint_t>(cur->multitouch_type, record_width.multitouch_type);
+
+    //modifier_decorator
+    storage.encode_string(cur->modifier_decorator, record_width.modifier_decorator);
+
+    //magnifier_label
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_LABEL_FOR_ONE; ++j) {
+            storage.encode_string(cur->magnifier_label[i][j], record_width.magnifier_label);
+        }
+    }
+
+    // hint_string
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < MAX_SIZE_OF_MULTITAP_CHAR; ++j) {
+            storage.encode_string(cur->hint_string[i][j], record_width.hint_string);
+        }
+    }
+}
+
+int get_layout_num(const PSclLayoutKeyCoordinatePointerTable keyCoordinatePointerFrame) {
+    assert(keyCoordinatePointerFrame != NULL);
+    int layout_num = MAX_SCL_LAYOUT;
+    for ( int i = 0; i < MAX_SCL_LAYOUT; ++i ) {
+        // NULL is the end flag
+        if (keyCoordinatePointerFrame[i][0] == NULL) {
+            layout_num = i;
+            break;
+        }
+    }
+
+    return layout_num;
+}
+
+int get_key_num(const PSclLayoutKeyCoordinatePointerTable keyCoordinatePointerFrame, const int layout_no) {
+    assert(keyCoordinatePointerFrame != NULL);
+    int key_num = MAX_KEY;
+
+    SclLayoutKeyCoordinatePointer* curLayoutRecordPointers = keyCoordinatePointerFrame[layout_no];
+    for (int i = 0; i < MAX_KEY; ++i) {
+        if (curLayoutRecordPointers[i] == NULL) {
+            key_num = i;
+            break;
+        }
+    }
+
+    return key_num;
+}
+
+
+int
+encode_key_coordinate_frame_file(ResourceStorage& storage, IMetaData_Helper& md_helper) {
+    XMLResource *xmlresource = XMLResource::get_instance();
+
+    int layout_num = xmlresource->get_layout_size();
+    assert(layout_num >= 0);
+    SclLayoutKeyCoordinatePointer _key_coordinate_pointer_frame[MAX_SCL_LAYOUT][MAX_KEY];
+    memset(_key_coordinate_pointer_frame, 0x00, MAX_KEY * MAX_SCL_LAYOUT * sizeof(SclLayoutKeyCoordinatePointer));
+
+    for (int i = 0; i < layout_num; ++i) {
+        xmlresource->load(i);
+        for (int j = 0; j < MAX_KEY; ++j) {
+            _key_coordinate_pointer_frame[i][j] = xmlresource->get_key_coordinate_pointer_frame()[i][j];
+        }
+    }
+    // 4 byte (range[0-4,294,967,295))
+    const int DATA_SIZE_BYTES = 4;
+    // 1 byte (range[0-128))
+    const int REC_NUM_BYTES = 1;
+    const int KEY_NUM_BYTES = 1;
+    // 2 byte (range[0-65536))
+    const int KEY_COORDIANTE_REC_DATA_SIZE_BYTES = 2;
+
+    int init_size = storage.get_size();
+    // data size
+    storage.reserve(DATA_SIZE_BYTES);
+
+    //TODO: assert layout_num < REC_NUM_BYTES's range
+    storage.put<uint_t>(layout_num, REC_NUM_BYTES);
+
+    int *pKey_num_array = new int[layout_num];
+    memset(pKey_num_array, 0x00, layout_num * sizeof(int));
+    for (int i = 0; i < layout_num; ++i) {
+        pKey_num_array[i] = get_key_num(_key_coordinate_pointer_frame, i);
+        //TODO: assert key_num < KEY_NUM_BYTES's range
+        storage.put<uint_t>(pKey_num_array[i], KEY_NUM_BYTES);
+    }
+
+    // key_coordinate_rec_data_size
+    storage.reserve(KEY_COORDIANTE_REC_DATA_SIZE_BYTES);
+
+    Key_coordinate_record_width record_width;
+    set_key_coordinate_record_width(&md_helper, record_width);
+
+
+    int key_coordinate_rec_data_size = 0;
+    for ( int i = 0; i < layout_num; ++i ) {
+        for ( int j = 0; j < pKey_num_array[i]; ++j ) {
+            int pre_size = storage.get_size();
+
+            SclLayoutKeyCoordinatePointer cur = _key_coordinate_pointer_frame[i][j];
+            if (!cur) break;
+            encode_key_coordinate_record(storage, cur, record_width);
+
+            int aft_size = storage.get_size();
+            if (key_coordinate_rec_data_size == 0) {
+                key_coordinate_rec_data_size = aft_size - pre_size;
+            }
+            assert(key_coordinate_rec_data_size == aft_size - pre_size);
+        }
+    }
+
+    delete[] pKey_num_array;
+
+    int advance_size = storage.get_size() - init_size;
+    storage.random_put<sint_t>(advance_size, DATA_SIZE_BYTES, init_size);
+
+    // random put key_coordinate_rec_data_size
+    int key_coordinate_rec_data_offset = init_size +
+                                        DATA_SIZE_BYTES +
+                                        REC_NUM_BYTES +
+                                        layout_num * KEY_NUM_BYTES;
+    storage.random_put<uint_t>(key_coordinate_rec_data_size,
+                                KEY_COORDIANTE_REC_DATA_SIZE_BYTES,
+                                key_coordinate_rec_data_offset);
+
+    return storage.get_size();
+}
+
+int
+encode_key_coordinate_frame_file(const char* file, int& offset, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+    encode_key_coordinate_frame_file(storage, md_helper);
+    storage.toFile(file, offset);
+
+    return storage.get_size();
+}
+
+int
+encode_key_coordinate_frame_file(const char* file, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+    encode_key_coordinate_frame_file(storage, md_helper);
+    storage.toFile(file);
+
+    return storage.get_size();
+}
diff --git a/xml2binary/encode_label_properties_frame.cpp b/xml2binary/encode_label_properties_frame.cpp
new file mode 100644 (file)
index 0000000..580905e
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012 - 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 "resource_storage_impl.h"
+#include "encode_label_properties_frame.h"
+#include <string>
+#include "xmlresource.h"
+#include "put_record.h"
+#include "_auto_metadata.h"
+using namespace xmlresource;
+using namespace std;
+static void _encode_color(ResourceStorage& storage, const SclColor& color, int width) {
+    if (width <= 0) return;
+    storage.put<sint_t>(color.r, width);
+    storage.put<sint_t>(color.g, width);
+    storage.put<sint_t>(color.b, width);
+    storage.put<sint_t>(color.a, width);
+}
+
+static void
+encode_label_properties_record(ResourceStorage& storage, const PSclLabelProperties cur, const Label_properties_record_width& record_width) {
+    if (cur == NULL) return;
+
+    //label_name
+    storage.encode_string(cur->label_type, record_width.label_type);
+
+    //font_name
+    storage.encode_string(cur->font_name, record_width.font_name);
+
+    //font_size
+    storage.put<sint_t>(cur->font_size, record_width.font_size);
+
+    //font color
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            _encode_color(storage, cur->font_color[i][j], record_width.font_color);
+        }
+    }
+
+    //alignment
+    storage.put<sint_t>(cur->alignment, record_width.alignment);
+
+    //padding_x
+    storage.put<sint_t>(cur->padding_x, record_width.padding_x);
+
+    //padding_y
+    storage.put<sint_t>(cur->padding_y, record_width.padding_y);
+
+    //inner_width
+    storage.put<sint_t>(cur->inner_width, record_width.inner_width);
+
+    //inner_height
+    storage.put<sint_t>(cur->inner_height, record_width.inner_height);
+
+    //shadow_distance
+    storage.put<sint_t>(cur->shadow_distance, record_width.shadow_distance);
+
+    //shadow_direction
+    storage.put<sint_t>(cur->shadow_direction, record_width.shadow_direction);
+
+    //shadow_color
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            _encode_color(storage, cur->shadow_color[i][j], record_width.shadow_color);
+        }
+    }
+}
+
+int
+encode_label_properties_frame_file(ResourceStorage& storage, IMetaData_Helper& md_helper) {
+    int init_size = storage.get_size();
+
+    /*size 4bytes*/
+    const int _SIZE_WIDTH = 4;
+
+    XMLResource *xmlresource = XMLResource::get_instance();
+    PSclLabelPropertiesTable labelPropertiesFrame = xmlresource->get_label_properties_frame();
+
+#ifdef __SCL_TXT_DEBUG
+    put_label_properties_frame(ENCODE, labelPropertiesFrame);
+
+#endif
+    int size = xmlresource->get_labelproperty_size();
+    int maxj = MAX_SIZE_OF_LABEL_FOR_ONE;
+
+    storage.reserve(8);
+
+    storage.put<sint_t>(size, _SIZE_WIDTH);
+    storage.put<sint_t>(maxj, _SIZE_WIDTH);
+
+    Label_properties_record_width record_width;
+    set_label_properties_record_width(md_helper, record_width);
+    for ( int i = 0; i < size; ++i ) {
+        for ( int j = 0; j < maxj; ++j ) {
+            SclLabelProperties cur = labelPropertiesFrame[i][j];
+            encode_label_properties_record(storage, &cur, record_width);
+        }
+    }
+
+    int advance_size = storage.get_size() - init_size;
+    storage.random_put<sint_t>(advance_size, 8, init_size);
+
+    return storage.get_size();
+}
+
+int
+encode_label_properties_frame_file(const char* file, int& offset, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+
+    ResourceStorage storage;
+    encode_label_properties_frame_file(storage, md_helper);
+    storage.toFile(file, offset);
+
+    return storage.get_size();
+}
+
+int
+encode_label_properties_frame_file(const char* file, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+
+    ResourceStorage storage;
+    encode_label_properties_frame_file(storage, md_helper);
+    storage.toFile(file);
+
+    return storage.get_size();
+}
diff --git a/xml2binary/encode_layout.cpp b/xml2binary/encode_layout.cpp
new file mode 100644 (file)
index 0000000..e557947
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2012 - 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 "resource_storage_impl.h"
+#include "encode_layout.h"
+#include <string>
+#include <libxml/parser.h>
+#include "xmlresource.h"
+#include "put_record.h"
+#include "_auto_metadata.h"
+using namespace std;
+using namespace xmlresource;
+extern IString_Encoder& string_encoder;
+
+static void _encode_color(ResourceStorage& storage, const SclColor& color, int width) {
+    if (width <= 0) return;
+
+    storage.put<sint_t>(color.r, width);
+    storage.put<sint_t>(color.g, width);
+    storage.put<sint_t>(color.b, width);
+    storage.put<sint_t>(color.a, width);
+}
+
+static void
+encode_layout_record(ResourceStorage& storage, PSclLayout cur, const Layout_width& record_width) {
+    //name
+    storage.encode_string((const char*)cur->name, record_width.name);
+    //display mode
+    storage.put<sint_t>(cur->display_mode, record_width.display_mode);
+
+    //style
+    storage.put<sint_t>(cur->style, record_width.style);
+
+    //width
+    storage.put<sint_t>(cur->width, record_width.width);
+
+    //height
+    storage.put<sint_t>(cur->height, record_width.height);
+
+    //use_sw_button
+    storage.put<sint_t>(cur->use_sw_button, record_width.use_sw_button);
+
+    //use_magnifier_window
+    storage.put<sint_t>(cur->use_magnifier_window, record_width.use_magnifier_window);
+
+    //extract_background
+    storage.put<sint_t>(cur->extract_background, record_width.extract_background);
+
+    //key_width
+    storage.put<sint_t>(cur->key_width, record_width.key_width);
+
+    //key_height
+    storage.put<sint_t>(cur->key_height, record_width.key_height);
+    //key_spacing
+    storage.put<sint_t>(cur->key_spacing, record_width.key_spacing);
+    //row_spacing
+    storage.put<sint_t>(cur->row_spacing, record_width.row_spacing);
+
+    //use_sw_background
+    storage.put<sint_t>(cur->use_sw_background, record_width.use_sw_background);
+
+    _encode_color(storage, cur->bg_color, record_width.bg_color);
+
+    //bg_line_width
+    storage.put<float_t>(cur->bg_line_width, record_width.bg_line_width);
+
+    _encode_color(storage, cur->bg_line_color, record_width.bg_line_color);
+
+    //add_grab_left
+    storage.put<sint_t>(cur->add_grab_left, record_width.add_grab_left);
+
+    //add_grab_right
+    storage.put<sint_t>(cur->add_grab_right, record_width.add_grab_right);
+
+    //add_grab_top
+    storage.put<sint_t>(cur->add_grab_top, record_width.add_grab_top);
+
+    //add_grab_bottom
+    storage.put<sint_t>(cur->add_grab_bottom, record_width.add_grab_bottom);
+
+    //image_path
+    for (int i = 0; i < SCL_BUTTON_STATE_MAX; ++i) {
+        storage.encode_string(cur->image_path[i], record_width.image_path);
+    }
+
+    //key_background_image
+    for (int i = 0; i < SCL_SHIFT_STATE_MAX; ++i) {
+        for (int j = 0; j < SCL_BUTTON_STATE_MAX; ++j) {
+            storage.encode_string(cur->key_background_image[i][j], record_width.key_background_image);
+        }
+    }
+
+    //sound_style
+    storage.encode_string(cur->sound_style, record_width.sound_style);
+    //vibe_style
+    storage.encode_string(cur->vibe_style, record_width.vibe_style);
+    //label_name
+    storage.encode_string(cur->label_type, record_width.label_type);
+    //modifier_decorator
+    storage.encode_string(cur->modifier_decorator, record_width.modifier_decorator);
+}
+
+int
+encode_layout_file(ResourceStorage& storage, IMetaData_Helper& md_helper) {
+    // 4 byte (range[0-4,294,967,295))
+    const int DATA_SIZE_BYTES = 4;
+    // 1 byte (range[0-128))
+    const int REC_NUM_BYTES = 1;
+    // 2 byte (range[0-65536))
+    const int LAYOUT_REC_DATA_SIZE_BYTES = 2;
+
+    const int init_size = storage.get_size();
+
+    XMLResource *xmlresource = XMLResource::get_instance();
+    PSclLayout layoutTable = xmlresource->get_layout_table();
+
+    int size = xmlresource->get_layout_size();
+
+#ifdef __SCL_TXT_DEBUG
+    put_layout_table(ENCODE, layoutTable);
+#endif
+
+    PSclLayout cur = layoutTable;
+
+    // data size
+    storage.reserve(DATA_SIZE_BYTES);
+
+    // rec_num
+    storage.put<sint_t>(size, REC_NUM_BYTES);
+
+    // rec data size
+    storage.reserve(LAYOUT_REC_DATA_SIZE_BYTES);
+
+    Layout_width record_width;
+    set_layout_width(md_helper, record_width);
+
+    int layout_rec_data_size = 0;
+    for ( int i = 0; i < size; ++i ) {
+        int pre_size = storage.get_size();
+        encode_layout_record(storage, cur, record_width);
+
+        int aft_size = storage.get_size();
+        if (layout_rec_data_size == 0) {
+            layout_rec_data_size = aft_size - pre_size;
+        }
+        assert(layout_rec_data_size == aft_size - pre_size);
+
+        cur++;
+    }
+
+    // back write data size
+    int advance_size = storage.get_size() - init_size;
+
+    // random put advance_size
+    int data_size_offset = init_size;
+    storage.random_put<sint_t>(advance_size, DATA_SIZE_BYTES, data_size_offset);
+
+    // random put layout_rec size
+    int layout_rec_data_offset = init_size + DATA_SIZE_BYTES + REC_NUM_BYTES;
+    storage.random_put<sint_t>(layout_rec_data_size, LAYOUT_REC_DATA_SIZE_BYTES, layout_rec_data_offset);
+
+    return storage.get_size();
+}
+
+int
+encode_layout_file(const char* file, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+    encode_layout_file(storage, md_helper);
+
+    storage.toFile(file);
+
+    return storage.get_size();
+}
+
+int
+encode_layout_file(const char* file, int& offset, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+    encode_layout_file(storage, md_helper);
+
+    storage.toFile(file, offset);
+
+    return storage.get_size();
+}
diff --git a/xml2binary/encode_magnifier_configure.cpp b/xml2binary/encode_magnifier_configure.cpp
new file mode 100644 (file)
index 0000000..779346b
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2012 - 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 "encode_magnifier_configure.h"
+#include "xmlresource.h"
+#include "resource_storage_impl.h"
+#include "put_record.h"
+#include "_auto_metadata.h"
+using namespace xmlresource;
+static void
+encode_magnifier_configure_record(ResourceStorage& storage, const PSclMagnifierWndConfigure cur, const Magnifier_configure_width& record_width) {
+    //style
+    storage.put<sint_t>(cur->style, record_width.style);
+    //width
+    storage.put<sint_t>(cur->width, record_width.width);
+    //height
+    storage.put<sint_t>(cur->height, record_width.height);
+    //label_area_record.left
+    storage.put<sint_t>(cur->label_area_rect.left, record_width.label_area_rect);
+    //label_area_rect.right
+    storage.put<sint_t>(cur->label_area_rect.right, record_width.label_area_rect);
+
+    //label_area_record.top
+    storage.put<sint_t>(cur->label_area_rect.top, record_width.label_area_rect);
+    //label_area_rect.bottom
+    storage.put<sint_t>(cur->label_area_rect.bottom, record_width.label_area_rect);
+    //bg_image_path
+    storage.encode_string(cur->bg_image_path, record_width.bg_image_path);
+
+    //bg_shift_image_path
+    storage.encode_string(cur->bg_shift_image_path, record_width.bg_shift_image_path);
+
+    //bg_shift_lock_image_path
+    storage.encode_string(cur->bg_shift_lock_image_path, record_width.bg_shift_lock_image_path);
+
+    //bg_long_key_image_path
+    storage.encode_string(cur->bg_long_key_image_path, record_width.bg_long_key_image_path);
+    //use_actual_window
+    storage.put<sint_t>(cur->use_actual_window, record_width.use_actual_window);
+    //label_name
+    storage.encode_string(cur->label_type, record_width.label_type);
+    //padding_x
+    storage.put<sint_t>(cur->padding_x, record_width.padding_x);
+    //padding_y
+    storage.put<sint_t>(cur->padding_y, record_width.padding_y);
+    //show_shift_label
+    storage.put<sint_t>(cur->show_shift_label, record_width.show_shift_label);
+}
+
+int
+encode_magnifier_configure_file(ResourceStorage& storage, IMetaData_Helper& md_helper) {
+    int init_size = storage.get_size();
+
+    XMLResource *xmlresource = XMLResource::get_instance();
+    PSclMagnifierWndConfigure magnifierConfigure = xmlresource->get_magnifier_configure();
+
+
+#ifdef __SCL_TXT_DEBUG
+    put_magnifier_wnd_configure(ENCODE, *magnifierConfigure);
+
+#endif
+    Magnifier_configure_width record_width;
+    set_magnifier_configure_width(md_helper, record_width);
+
+    storage.reserve(8);
+    encode_magnifier_configure_record(storage, magnifierConfigure, record_width);
+
+    int advance_size = storage.get_size() - init_size;
+
+    storage.random_put<sint_t>(advance_size, 8, init_size);
+
+    return storage.get_size();
+}
+
+int
+encode_magnifier_configure_file(const char* file, int& offset, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+
+    ResourceStorage storage;
+    encode_magnifier_configure_file(storage, md_helper);
+    storage.toFile(file, offset);
+
+    return storage.get_size();
+}
+
+int
+encode_magnifier_configure_file(const char* file, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+
+    ResourceStorage storage;
+    encode_magnifier_configure_file(storage, md_helper);
+    storage.toFile(file);
+
+    return storage.get_size();
+}
diff --git a/xml2binary/encode_metadata.cpp b/xml2binary/encode_metadata.cpp
new file mode 100644 (file)
index 0000000..d0262e6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 - 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 "encode_metadata.h"
+#include <assert.h>
+#include <stdio.h>
+#include "metadata.h"
+using namespace std;
+static const int FIELD_NUM_WIDTH = 2;
+static void
+encode_metadata_record(ResourceStorage& storage, const MetaData_Record& metadata_record ) {
+    storage.put(metadata_record.m_name);
+    unsigned short field_num = metadata_record.vField.size();
+    storage.put<sint_t>(field_num, FIELD_NUM_WIDTH);
+
+    std::vector<MetaData_Field>::const_iterator it;
+    for (it = metadata_record.vField.begin(); it != metadata_record.vField.end(); ++it) {
+        storage.put(it->m_name);
+        storage.put(it->m_type);
+        storage.put<sint_t>(it->m_width, FIELD_SIZE_WIDTH);
+    }
+}
+void
+encode_metadata(ResourceStorage& storage, const MetaData& metadata ) {
+    int init_size = storage.get_size();
+
+    storage.reserve(8);
+    storage.put(metadata.m_version);
+
+    unsigned short size = metadata.m_vec_metadata_record.size();
+    storage.put<sint_t>(size, RECORD_SIZE_WIDTH);
+
+    for (int i = 0; i < size; ++i) {
+        encode_metadata_record(storage, metadata.m_vec_metadata_record.at(i));
+    }
+
+    int block_size = storage.get_size() - init_size;
+    storage.random_put<sint_t>(block_size, 8, init_size);
+}
+
diff --git a/xml2binary/encode_modifier_decoration.cpp b/xml2binary/encode_modifier_decoration.cpp
new file mode 100644 (file)
index 0000000..4e42ea7
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012 - 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 "encode_modifier_decoration.h"
+#include "xmlresource.h"
+#include "resource_storage_impl.h"
+#include "put_record.h"
+#include "_auto_metadata.h"
+#include <dlog.h>
+
+using namespace xmlresource;
+static void
+encode_modifier_decoration_record(ResourceStorage& storage, const PSclModifierDecoration cur, const Modifier_decoration_width& record_width) {
+    storage.put<sint_t>(cur->extract_background, record_width.extract_background);
+    storage.encode_string(cur->name, record_width.name);
+    for (int i = 0; i < DISPLAYMODE_MAX; ++i) {
+        for (int j = 0; j < KEY_MODIFIER_MAX; ++j) {
+            storage.encode_string(cur->bg_image_path[i][j], record_width.bg_image_path);
+        }
+    }
+}
+
+int
+encode_modifier_decoration_file(ResourceStorage& storage, IMetaData_Helper& md_helper) {
+    int init_size = storage.get_size();
+
+    XMLResource *xmlresource = XMLResource::get_instance();
+    PSclModifierDecoration modifierDecorationTable = xmlresource->get_modifier_decoration_table();
+    if (modifierDecorationTable == NULL) {
+        LOGW("Error. modifier decoration table is NULL\n");
+        return 0;
+    }
+
+#ifdef __SCL_TXT_DEBUG
+    put_modifier_decoration(ENCODE, modifierDecorationTable);
+
+#endif
+    Modifier_decoration_width record_width;
+    set_modifier_decoration_width(md_helper, record_width);
+
+    storage.reserve(8);
+
+    storage.put<sint_t>(MAX_SCL_MODIFIER_DECORATION_NUM, 4);
+    PSclModifierDecoration cur = modifierDecorationTable;
+    for (int i = 0; i < MAX_SCL_MODIFIER_DECORATION_NUM; ++i) {
+        encode_modifier_decoration_record(storage, cur, record_width);
+        cur++;
+    }
+
+    int advance_size = storage.get_size() - init_size;
+    storage.random_put<sint_t>(advance_size, 8, init_size);
+
+    return storage.get_size();
+}
+
+int
+encode_modifier_decoration_file(const char* file, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+
+    encode_modifier_decoration_file(storage, md_helper);
+    storage.toFile(file);
+
+    return storage.get_size();
+}
+
+int
+encode_modifier_decoration_file(const char* file, int& offset, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+
+    encode_modifier_decoration_file(storage, md_helper);
+    storage.toFile(file, offset);
+
+    return storage.get_size();
+}
diff --git a/xml2binary/encode_nine_patch.cpp b/xml2binary/encode_nine_patch.cpp
new file mode 100644 (file)
index 0000000..fc747a4
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012 - 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 "encode_nine_patch.h"
+#include <string>
+#include "xmlresource.h"
+#include "imetadata_helper.h"
+#include "resource_storage_impl.h"
+#include "put_record.h"
+#include "_auto_metadata.h"
+#include <dlog.h>
+
+using namespace std;
+using namespace xmlresource;
+static void
+encode_nine_patch_info(ResourceStorage& storage, const SclNinePatchInfo* cur, const Nine_patch_width& record_width) {
+    assert(cur != NULL);
+    storage.encode_string(cur->image_path, record_width.image_path);
+    //left
+    storage.put<sint_t>(cur->left, record_width.left);
+    //right
+    storage.put<sint_t>(cur->right, record_width.right);
+    //top
+    storage.put<sint_t>(cur->top, record_width.top);
+    //bottom
+    storage.put<sint_t>(cur->bottom, record_width.bottom);
+}
+
+int
+encode_nine_patch_file(ResourceStorage& storage, IMetaData_Helper& md_helper) {
+    int init_size = storage.get_size();
+
+    XMLResource *xmlresource = XMLResource::get_instance();
+    if (xmlresource == NULL) {
+        LOGW("Error: failed to get xmlresource instance.\n");
+        return 0;
+    }
+    SclNinePatchInfo* ninePatchInfoTable = xmlresource->get_nine_patch_list();
+    if (ninePatchInfoTable == NULL) {
+        LOGW("Warning: nine patch list is null\n");
+        return 0;
+    }
+#ifdef __SCL_TXT_DEBUG
+    put_nine_patch_info(ENCODE, ninePatchInfoTable);
+
+#endif
+    storage.reserve(8);
+    storage.put<sint_t>(MAX_NINE_PATCH_FILE_LIST, 4);
+
+    Nine_patch_width record_width;
+    set_nine_patch_width(md_helper, record_width);
+    SclNinePatchInfo* cur = ninePatchInfoTable;
+    for (int i = 0; i < MAX_NINE_PATCH_FILE_LIST; ++i) {
+        encode_nine_patch_info(storage, cur, record_width);
+        cur++;
+    }
+
+    int size = storage.get_size() - init_size;
+    storage.random_put<sint_t>(size, 8, init_size);
+
+    return storage.get_size();
+}
+
+int
+encode_nine_patch_file(const char* file, IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+    encode_nine_patch_file(storage, md_helper);
+    storage.toFile(file);
+
+    return storage.get_size();
+}
+
+int
+encode_nine_patch_file(const char* file, int& offset,  IMetaData_Helper& md_helper) {
+    if (!file) return 0;
+
+    ResourceStorage storage;
+    encode_nine_patch_file(storage, md_helper);
+    storage.toFile(file, offset);
+
+    return storage.get_size();
+}
diff --git a/xml2binary/include/_auto_metadata.h b/xml2binary/include/_auto_metadata.h
new file mode 100644 (file)
index 0000000..c766a95
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * Copyright (c) 2012 - 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.
+ *
+ */
+
+/*This file is generated by auto_codes.py.*/
+
+#ifndef __AUTO_METADATA_H__
+#define __AUTO_METADATA_H__
+
+#include <memory.h>
+typedef struct _Input_mode_configure_width {
+       int name;
+       int layout_portrait;
+       int layout_landscape;
+       int use_virtual_window;
+       int use_dim_window;
+       int timeout;
+}Input_mode_configure_width;
+
+typedef struct _Layout_width {
+       int name;
+       int display_mode;
+       int style;
+       int width;
+       int height;
+       int use_sw_button;
+       int use_magnifier_window;
+       int extract_background;
+       int key_width;
+       int key_height;
+       int key_spacing;
+       int row_spacing;
+       int use_sw_background;
+       int bg_color;
+       int bg_line_width;
+       int bg_line_color;
+       int add_grab_left;
+       int add_grab_right;
+       int add_grab_top;
+       int add_grab_bottom;
+       int image_path;
+       int key_background_image;
+       int sound_style;
+       int vibe_style;
+       int label_type;
+       int modifier_decorator;
+}Layout_width;
+
+typedef struct _Key_coordinate_record_width {
+       int x;
+       int y;
+       int width;
+       int height;
+       int add_hit_left;
+       int add_hit_right;
+       int add_hit_top;
+       int add_hit_bottom;
+       int popup_relative_x;
+       int popup_relative_y;
+       int extract_offset_x;
+       int extract_offset_y;
+       int sub_layout;
+       int magnifier_offset_x;
+       int magnifier_offset_y;
+       int custom_id;
+       int button_type;
+       int key_type;
+       int popup_type;
+       int use_magnifier;
+       int use_long_key_magnifier;
+       int popup_input_mode;
+       int sound_style;
+       int vibe_style;
+       int is_side_button;
+       int label_count;
+       int label;
+       int label_type;
+       int image_label_path;
+       int image_label_type;
+       int bg_image_path;
+       int key_value_count;
+       int key_value;
+       int key_event;
+       int long_key_type;
+       int long_key_value;
+       int long_key_event;
+       int use_repeat_key;
+       int autopopup_key_labels;
+       int autopopup_key_values;
+       int autopopup_key_events;
+       int dont_close_popup;
+       int extra_option;
+       int multitouch_type;
+       int modifier_decorator;
+       int magnifier_label;
+       int hint_string;
+}Key_coordinate_record_width;
+
+typedef struct _Label_properties_record_width {
+       int label_type;
+       int font_name;
+       int font_size;
+       int font_color;
+       int alignment;
+       int padding_x;
+       int padding_y;
+       int inner_width;
+       int inner_height;
+       int shadow_distance;
+       int shadow_direction;
+       int shadow_color;
+}Label_properties_record_width;
+
+typedef struct _Default_configure_width {
+       int display_mode;
+       int input_mode;
+       int image_file_base_path;
+       int target_screen_width;
+       int target_screen_height;
+       int auto_detect_landscape;
+       int use_magnifier_window;
+       int use_auto_popup;
+       int use_zoom_window;
+       int on_error_noti_send;
+       int use_word_deletion;
+       int sw_button_style;
+       int touch_offset_level;
+       int touch_offset;
+       int default_sub_layout;
+       int use_actual_dim_window;
+       int dim_color;
+}Default_configure_width;
+
+typedef struct _Magnifier_configure_width {
+       int style;
+       int width;
+       int height;
+       int label_area_rect;
+       int bg_image_path;
+       int bg_shift_image_path;
+       int bg_shift_lock_image_path;
+       int bg_long_key_image_path;
+       int use_actual_window;
+       int label_type;
+       int padding_x;
+       int padding_y;
+       int show_shift_label;
+}Magnifier_configure_width;
+
+typedef struct _Autopopup_configure_width {
+       int bg_image_path;
+       int bg_color;
+       int bg_line_width;
+       int bg_line_color;
+       int bg_padding;
+       int button_image_path;
+       int sw_button_style;
+       int button_width;
+       int button_height;
+       int button_spacing;
+       int label_type;
+       int decoration_image_path;
+       int decoration_size;
+       int max_column;
+       int add_grab_left;
+       int add_grab_right;
+       int add_grab_top;
+       int add_grab_bottom;
+}Autopopup_configure_width;
+
+typedef struct _Modifier_decoration_width {
+       int extract_background;
+       int name;
+       int bg_image_path;
+}Modifier_decoration_width;
+
+typedef struct _Nine_patch_width {
+       int image_path;
+       int left;
+       int right;
+       int top;
+       int bottom;
+}Nine_patch_width;
+
+template <class T>
+void set_input_mode_configure_width(T& md_helper,
+       Input_mode_configure_width & record_width) {
+       md_helper.set_current_metadata_record("input_mode_configure");
+       memset(&record_width, 0x00, sizeof(Input_mode_configure_width));
+
+       record_width.name = md_helper.get_width("name");
+       record_width.layout_portrait = md_helper.get_width("layout_portrait");
+       record_width.layout_landscape = md_helper.get_width("layout_landscape");
+       record_width.use_virtual_window = md_helper.get_width("use_virtual_window");
+       record_width.use_dim_window = md_helper.get_width("use_dim_window");
+       record_width.timeout = md_helper.get_width("timeout");
+}
+
+template <class T>
+void set_layout_width(T& md_helper,
+       Layout_width & record_width) {
+       md_helper.set_current_metadata_record("layout");
+       memset(&record_width, 0x00, sizeof(Layout_width));
+
+       record_width.name = md_helper.get_width("name");
+       record_width.display_mode = md_helper.get_width("display_mode");
+       record_width.style = md_helper.get_width("style");
+       record_width.width = md_helper.get_width("width");
+       record_width.height = md_helper.get_width("height");
+       record_width.use_sw_button = md_helper.get_width("use_sw_button");
+       record_width.use_magnifier_window = md_helper.get_width("use_magnifier_window");
+       record_width.extract_background = md_helper.get_width("extract_background");
+       record_width.key_width = md_helper.get_width("key_width");
+       record_width.key_height = md_helper.get_width("key_height");
+       record_width.key_spacing = md_helper.get_width("key_spacing");
+       record_width.row_spacing = md_helper.get_width("row_spacing");
+       record_width.use_sw_background = md_helper.get_width("use_sw_background");
+       record_width.bg_color = md_helper.get_width("bg_color");
+       record_width.bg_line_width = md_helper.get_width("bg_line_width");
+       record_width.bg_line_color = md_helper.get_width("bg_line_color");
+       record_width.add_grab_left = md_helper.get_width("add_grab_left");
+       record_width.add_grab_right = md_helper.get_width("add_grab_right");
+       record_width.add_grab_top = md_helper.get_width("add_grab_top");
+       record_width.add_grab_bottom = md_helper.get_width("add_grab_bottom");
+       record_width.image_path = md_helper.get_width("image_path");
+       record_width.key_background_image = md_helper.get_width("key_background_image");
+       record_width.sound_style = md_helper.get_width("sound_style");
+       record_width.vibe_style = md_helper.get_width("vibe_style");
+       record_width.label_type = md_helper.get_width("label_type");
+       record_width.modifier_decorator = md_helper.get_width("modifier_decorator");
+}
+
+template <class T>
+void set_key_coordinate_record_width(T& md_helper,
+       Key_coordinate_record_width & record_width) {
+       md_helper.set_current_metadata_record("key_coordinate_record");
+       memset(&record_width, 0x00, sizeof(Key_coordinate_record_width));
+
+       record_width.x = md_helper.get_width("x");
+       record_width.y = md_helper.get_width("y");
+       record_width.width = md_helper.get_width("width");
+       record_width.height = md_helper.get_width("height");
+       record_width.add_hit_left = md_helper.get_width("add_hit_left");
+       record_width.add_hit_right = md_helper.get_width("add_hit_right");
+       record_width.add_hit_top = md_helper.get_width("add_hit_top");
+       record_width.add_hit_bottom = md_helper.get_width("add_hit_bottom");
+       record_width.popup_relative_x = md_helper.get_width("popup_relative_x");
+       record_width.popup_relative_y = md_helper.get_width("popup_relative_y");
+       record_width.extract_offset_x = md_helper.get_width("extract_offset_x");
+       record_width.extract_offset_y = md_helper.get_width("extract_offset_y");
+       record_width.sub_layout = md_helper.get_width("sub_layout");
+       record_width.magnifier_offset_x = md_helper.get_width("magnifier_offset_x");
+       record_width.magnifier_offset_y = md_helper.get_width("magnifier_offset_y");
+       record_width.custom_id = md_helper.get_width("custom_id");
+       record_width.button_type = md_helper.get_width("button_type");
+       record_width.key_type = md_helper.get_width("key_type");
+       record_width.popup_type = md_helper.get_width("popup_type");
+       record_width.use_magnifier = md_helper.get_width("use_magnifier");
+       record_width.use_long_key_magnifier = md_helper.get_width("use_long_key_magnifier");
+       record_width.popup_input_mode = md_helper.get_width("popup_input_mode");
+       record_width.sound_style = md_helper.get_width("sound_style");
+       record_width.vibe_style = md_helper.get_width("vibe_style");
+       record_width.is_side_button = md_helper.get_width("is_side_button");
+       record_width.label_count = md_helper.get_width("label_count");
+       record_width.label = md_helper.get_width("label");
+       record_width.label_type = md_helper.get_width("label_type");
+       record_width.image_label_path = md_helper.get_width("image_label_path");
+       record_width.image_label_type = md_helper.get_width("image_label_type");
+       record_width.bg_image_path = md_helper.get_width("bg_image_path");
+       record_width.key_value_count = md_helper.get_width("key_value_count");
+       record_width.key_value = md_helper.get_width("key_value");
+       record_width.key_event = md_helper.get_width("key_event");
+       record_width.long_key_type = md_helper.get_width("long_key_type");
+       record_width.long_key_value = md_helper.get_width("long_key_value");
+       record_width.long_key_event = md_helper.get_width("long_key_event");
+       record_width.use_repeat_key = md_helper.get_width("use_repeat_key");
+       record_width.autopopup_key_labels = md_helper.get_width("autopopup_key_labels");
+       record_width.autopopup_key_values = md_helper.get_width("autopopup_key_values");
+       record_width.autopopup_key_events = md_helper.get_width("autopopup_key_events");
+       record_width.dont_close_popup = md_helper.get_width("dont_close_popup");
+       record_width.extra_option = md_helper.get_width("extra_option");
+       record_width.multitouch_type = md_helper.get_width("multitouch_type");
+       record_width.modifier_decorator = md_helper.get_width("modifier_decorator");
+       record_width.magnifier_label = md_helper.get_width("magnifier_label");
+       record_width.hint_string = md_helper.get_width("hint_string");
+}
+
+template <class T>
+void set_label_properties_record_width(T& md_helper,
+       Label_properties_record_width & record_width) {
+       md_helper.set_current_metadata_record("label_properties_record");
+       memset(&record_width, 0x00, sizeof(Label_properties_record_width));
+
+       record_width.label_type = md_helper.get_width("label_type");
+       record_width.font_name = md_helper.get_width("font_name");
+       record_width.font_size = md_helper.get_width("font_size");
+       record_width.font_color = md_helper.get_width("font_color");
+       record_width.alignment = md_helper.get_width("alignment");
+       record_width.padding_x = md_helper.get_width("padding_x");
+       record_width.padding_y = md_helper.get_width("padding_y");
+       record_width.inner_width = md_helper.get_width("inner_width");
+       record_width.inner_height = md_helper.get_width("inner_height");
+       record_width.shadow_distance = md_helper.get_width("shadow_distance");
+       record_width.shadow_direction = md_helper.get_width("shadow_direction");
+       record_width.shadow_color = md_helper.get_width("shadow_color");
+}
+
+template <class T>
+void set_default_configure_width(T& md_helper,
+       Default_configure_width & record_width) {
+       md_helper.set_current_metadata_record("default_configure");
+       memset(&record_width, 0x00, sizeof(Default_configure_width));
+
+       record_width.display_mode = md_helper.get_width("display_mode");
+       record_width.input_mode = md_helper.get_width("input_mode");
+       record_width.image_file_base_path = md_helper.get_width("image_file_base_path");
+       record_width.target_screen_width = md_helper.get_width("target_screen_width");
+       record_width.target_screen_height = md_helper.get_width("target_screen_height");
+       record_width.auto_detect_landscape = md_helper.get_width("auto_detect_landscape");
+       record_width.use_magnifier_window = md_helper.get_width("use_magnifier_window");
+       record_width.use_auto_popup = md_helper.get_width("use_auto_popup");
+       record_width.use_zoom_window = md_helper.get_width("use_zoom_window");
+       record_width.on_error_noti_send = md_helper.get_width("on_error_noti_send");
+       record_width.use_word_deletion = md_helper.get_width("use_word_deletion");
+       record_width.sw_button_style = md_helper.get_width("sw_button_style");
+       record_width.touch_offset_level = md_helper.get_width("touch_offset_level");
+       record_width.touch_offset = md_helper.get_width("touch_offset");
+       record_width.default_sub_layout = md_helper.get_width("default_sub_layout");
+       record_width.use_actual_dim_window = md_helper.get_width("use_actual_dim_window");
+       record_width.dim_color = md_helper.get_width("dim_color");
+}
+
+template <class T>
+void set_magnifier_configure_width(T& md_helper,
+       Magnifier_configure_width & record_width) {
+       md_helper.set_current_metadata_record("magnifier_configure");
+       memset(&record_width, 0x00, sizeof(Magnifier_configure_width));
+
+       record_width.style = md_helper.get_width("style");
+       record_width.width = md_helper.get_width("width");
+       record_width.height = md_helper.get_width("height");
+       record_width.label_area_rect = md_helper.get_width("label_area_rect");
+       record_width.bg_image_path = md_helper.get_width("bg_image_path");
+       record_width.bg_shift_image_path = md_helper.get_width("bg_shift_image_path");
+       record_width.bg_shift_lock_image_path = md_helper.get_width("bg_shift_lock_image_path");
+       record_width.bg_long_key_image_path = md_helper.get_width("bg_long_key_image_path");
+       record_width.use_actual_window = md_helper.get_width("use_actual_window");
+       record_width.label_type = md_helper.get_width("label_type");
+       record_width.padding_x = md_helper.get_width("padding_x");
+       record_width.padding_y = md_helper.get_width("padding_y");
+       record_width.show_shift_label = md_helper.get_width("show_shift_label");
+}
+
+template <class T>
+void set_autopopup_configure_width(T& md_helper,
+       Autopopup_configure_width & record_width) {
+       md_helper.set_current_metadata_record("autopopup_configure");
+       memset(&record_width, 0x00, sizeof(Autopopup_configure_width));
+
+       record_width.bg_image_path = md_helper.get_width("bg_image_path");
+       record_width.bg_color = md_helper.get_width("bg_color");
+       record_width.bg_line_width = md_helper.get_width("bg_line_width");
+       record_width.bg_line_color = md_helper.get_width("bg_line_color");
+       record_width.bg_padding = md_helper.get_width("bg_padding");
+       record_width.button_image_path = md_helper.get_width("button_image_path");
+       record_width.sw_button_style = md_helper.get_width("sw_button_style");
+       record_width.button_width = md_helper.get_width("button_width");
+       record_width.button_height = md_helper.get_width("button_height");
+       record_width.button_spacing = md_helper.get_width("button_spacing");
+       record_width.label_type = md_helper.get_width("label_type");
+       record_width.decoration_image_path = md_helper.get_width("decoration_image_path");
+       record_width.decoration_size = md_helper.get_width("decoration_size");
+       record_width.max_column = md_helper.get_width("max_column");
+       record_width.add_grab_left = md_helper.get_width("add_grab_left");
+       record_width.add_grab_right = md_helper.get_width("add_grab_right");
+       record_width.add_grab_top = md_helper.get_width("add_grab_top");
+       record_width.add_grab_bottom = md_helper.get_width("add_grab_bottom");
+}
+
+template <class T>
+void set_modifier_decoration_width(T& md_helper,
+       Modifier_decoration_width & record_width) {
+       md_helper.set_current_metadata_record("modifier_decoration");
+       memset(&record_width, 0x00, sizeof(Modifier_decoration_width));
+
+       record_width.extract_background = md_helper.get_width("extract_background");
+       record_width.name = md_helper.get_width("name");
+       record_width.bg_image_path = md_helper.get_width("bg_image_path");
+}
+
+template <class T>
+void set_nine_patch_width(T& md_helper,
+       Nine_patch_width & record_width) {
+       md_helper.set_current_metadata_record("nine_patch");
+       memset(&record_width, 0x00, sizeof(Nine_patch_width));
+
+       record_width.image_path = md_helper.get_width("image_path");
+       record_width.left = md_helper.get_width("left");
+       record_width.right = md_helper.get_width("right");
+       record_width.top = md_helper.get_width("top");
+       record_width.bottom = md_helper.get_width("bottom");
+}
+
+
+#endif //End __AUTO_METADATA_H__
diff --git a/xml2binary/include/encode_autopopup_configure.h b/xml2binary/include/encode_autopopup_configure.h
new file mode 100644 (file)
index 0000000..3414dd9
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 - 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 __ENCODE_AUTOPOPUP__CONFIGURE_H__
+#define __ENCODE_AUTOPOPUP_CONFIGURE_H__
+#include "imetadata_helper.h"
+#include "resource_storage_impl.h"
+// return value: the block size of this file
+int encode_autopopup_configure_file(ResourceStorage& storage, IMetaData_Helper& metadata);
+
+// return value: the size of this file
+// para "offset" will added to the new offset by adding size
+int encode_autopopup_configure_file(const char* file, int& offset, IMetaData_Helper& metadata);
+int encode_autopopup_configure_file(const char* file, IMetaData_Helper& metadata);
+#endif
diff --git a/xml2binary/include/encode_default_configure.h b/xml2binary/include/encode_default_configure.h
new file mode 100644 (file)
index 0000000..6cf24ff
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 - 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 __ENCODE_DEFAULT_CONFIGURE_H__
+#define __ENCODE_DEFAULT_CONFIGURE_H__
+#include "imetadata_helper.h"
+#include "resource_storage_impl.h"
+int encode_default_configure_file(ResourceStorage& storage, IMetaData_Helper& metadata);
+
+int encode_default_configure_file(const char* file, int& offset, IMetaData_Helper& metadata);
+int encode_default_configure_file(const char* file, IMetaData_Helper& metadata);
+#endif
diff --git a/xml2binary/include/encode_input_mode_configure.h b/xml2binary/include/encode_input_mode_configure.h
new file mode 100644 (file)
index 0000000..0575317
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 - 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 __ENCODE_INPUT_MODE_CONFIGURE_H__
+#define __ENCODE_INPUT_MODE_CONFIGURE_H__
+#include "imetadata_helper.h"
+#include "resource_storage_impl.h"
+int encode_input_mode_configure_file(const char* file, IMetaData_Helper& metadata);
+
+int encode_input_mode_configure_file(const char* file, int& offset, IMetaData_Helper& metadata);
+
+int encode_input_mode_configure_file(ResourceStorage& storage, IMetaData_Helper& metadata);
+#endif
diff --git a/xml2binary/include/encode_key_coordinate_frame.h b/xml2binary/include/encode_key_coordinate_frame.h
new file mode 100644 (file)
index 0000000..5f11ca0
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 - 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 __ENCODE_KEY_COORDINATE_FRAME_H__
+#define __ENCODE_KEY_COORDINATE_FRAME_H__
+#include "metadata.h"
+#include "imetadata_helper.h"
+#include "resource_storage_impl.h"
+int encode_key_coordinate_frame_file(ResourceStorage& storage, IMetaData_Helper& md_helper);
+int encode_key_coordinate_frame_file(const char* file, int& offset, IMetaData_Helper& md_helper);
+int encode_key_coordinate_frame_file(const char* file, IMetaData_Helper& md_helper);
+
+#endif
diff --git a/xml2binary/include/encode_label_properties_frame.h b/xml2binary/include/encode_label_properties_frame.h
new file mode 100644 (file)
index 0000000..a128526
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012 - 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 __ENCODE_LABEL_PROPERTIES_FRAME_H__
+#define __ENCODE_LABEL_PROPERTIES_FRAME_H__
+
+#include "metadata.h"
+#include "imetadata_helper.h"
+#include "resource_storage_impl.h"
+int encode_label_properties_frame_file(ResourceStorage& storage, IMetaData_Helper& md_helper);
+int encode_label_properties_frame_file(const char* file, int& offset, IMetaData_Helper& md_helper);
+int encode_label_properties_frame_file(const char* file, IMetaData_Helper& md_helper);
+
+#endif
diff --git a/xml2binary/include/encode_layout.h b/xml2binary/include/encode_layout.h
new file mode 100644 (file)
index 0000000..5abff57
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 - 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 __ENCODE_LAYOUT_H__
+#define __ENCODE_LAYOUT_H__
+#include "metadata.h"
+#include "imetadata_helper.h"
+int encode_layout_file(const char* file, IMetaData_Helper& md_helper);
+
+int encode_layout_file(const char* file, int& offset, IMetaData_Helper& md_helper);
+int encode_layout_file(ResourceStorage& storage, IMetaData_Helper& md_helper);
+#endif
diff --git a/xml2binary/include/encode_magnifier_configure.h b/xml2binary/include/encode_magnifier_configure.h
new file mode 100644 (file)
index 0000000..d4e5730
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 - 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 __ENCODE_MAGNIFIER_CONFIGURE_H__
+#define __ENCODE_MAGNIFIER_CONFIGURE_H__
+#include "imetadata_helper.h"
+#include "resource_storage_impl.h"
+int encode_magnifier_configure_file(ResourceStorage& storage, IMetaData_Helper& metadata);
+
+int encode_magnifier_configure_file(const char* file, int& offset, IMetaData_Helper& metadata);
+int encode_magnifier_configure_file(const char* file, IMetaData_Helper& metadata);
+#endif
diff --git a/xml2binary/include/encode_metadata.h b/xml2binary/include/encode_metadata.h
new file mode 100644 (file)
index 0000000..592965d
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 - 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 __ENCODE_METADATA_H__
+#define __ENCODE_METADATA_H__
+#include "metadata.h"
+#include "resource_storage_impl.h"
+void encode_metadata(ResourceStorage& storage, const MetaData& metadata);
+#endif
diff --git a/xml2binary/include/encode_modifier_decoration.h b/xml2binary/include/encode_modifier_decoration.h
new file mode 100644 (file)
index 0000000..a6fd564
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 - 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 __ENCODE_MODIFIER_DECORATION_H__
+#define __ENCODE_MODIFIER_DECORATION_H__
+#include "imetadata_helper.h"
+#include "resource_storage_impl.h"
+int encode_modifier_decoration_file(ResourceStorage& storage, IMetaData_Helper& metadata);
+int encode_modifier_decoration_file(const char* file, int& offset,  IMetaData_Helper& metadata);
+int encode_modifier_decoration_file(const char* file, IMetaData_Helper& metadata);
+
+#endif
diff --git a/xml2binary/include/encode_nine_patch.h b/xml2binary/include/encode_nine_patch.h
new file mode 100644 (file)
index 0000000..f0bfc38
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 - 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 __ENCODE_NINE_PATCH_H__
+#define __ENCODE_NINE_PATCH_H__
+#include "imetadata_helper.h"
+#include "resource_storage_impl.h"
+int encode_nine_patch_file(ResourceStorage& storage, IMetaData_Helper& metadata);
+
+int encode_nine_patch_file(const char* file, int& offset, IMetaData_Helper& metadata);
+int encode_nine_patch_file(const char* file, IMetaData_Helper& metadata);
+#endif
diff --git a/xml2binary/include/imetadata_encoder.h b/xml2binary/include/imetadata_encoder.h
new file mode 100644 (file)
index 0000000..d1aac65
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 - 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 __INTERFACE_METADATA_ENCODER_H__
+#define __INTERFACE_METADATA_ENCODER_H__
+class IMetaData_Encoder{
+    public:
+        virtual int encode(const char* file) const = 0;
+        virtual int encode(const char* file, int& offset) const = 0;
+        virtual ~IMetaData_Encoder() {}
+};
+#endif
diff --git a/xml2binary/include/imetadata_helper.h b/xml2binary/include/imetadata_helper.h
new file mode 100644 (file)
index 0000000..698f98b
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 - 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 __INTERFACE_METADATA_HELPER_H__
+#define __INTERFACE_METADATA_HELPER_H__
+class IMetaData_Helper{
+    public:
+        virtual void set_current_metadata_record(const char* record_name) = 0;
+        virtual unsigned short get_width(const char* field_name) const = 0;
+        virtual ~IMetaData_Helper() {}
+};
+#endif
diff --git a/xml2binary/include/imetadata_parser.h b/xml2binary/include/imetadata_parser.h
new file mode 100644 (file)
index 0000000..99bef9d
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 - 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 __INTERFACE_METADATA_PARSER_H__
+#define __INTERFACE_METADATA_PARSER_H__
+#include "metadata.h"
+class IMetaData_Parser{
+    public:
+        virtual const MetaData* get_metadata() const = 0;
+        virtual ~IMetaData_Parser() {}
+};
+#endif
diff --git a/xml2binary/include/istring_encoder.h b/xml2binary/include/istring_encoder.h
new file mode 100644 (file)
index 0000000..08711c3
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 - 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 __INTERFACE_STRING_ENCODER_H__
+#define __INTERFACE_STRING_ENCODER_H__
+class ResourceStorage;
+class IString_Encoder{
+    public:
+        virtual int add(const char*) = 0;
+        virtual int encode() const = 0;
+        virtual int encode(int& offset) const = 0;
+        virtual int encode(ResourceStorage&) const = 0;
+        virtual ~IString_Encoder() {}
+};
+#endif
diff --git a/xml2binary/include/metadata.h b/xml2binary/include/metadata.h
new file mode 100644 (file)
index 0000000..ff24b3d
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012 - 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 __META_FIELD_H__
+#define __META_FIELD_H__
+//each field:
+//1. the name
+//2. the width of the field
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <vector>
+const int FIELD_NAME_WIDTH = 128;
+const int FIELD_TYPE_WIDTH = 32;
+const int FIELD_SIZE_WIDTH = 2;
+class MetaData_Field{
+    public:
+        MetaData_Field():m_width(0) {
+            memset(m_name, 0, FIELD_NAME_WIDTH);
+            memset(m_type, 0, FIELD_TYPE_WIDTH);
+        }
+       MetaData_Field(const char*name, const char* type, const int width) {
+            assert(name);
+            assert(type);
+            assert(width >= 0);
+
+            memset(m_name, 0, FIELD_NAME_WIDTH);
+            memset(m_type, 0, FIELD_TYPE_WIDTH);
+
+            strncpy(m_name, name, FIELD_NAME_WIDTH - 1);
+            strncpy(m_type, type, FIELD_TYPE_WIDTH -1);
+
+            m_width = width;
+        }
+
+        MetaData_Field& operator=(const MetaData_Field& other) {
+                if (&other == this) return *this;
+
+                //field name
+                memset(m_name, 0, FIELD_NAME_WIDTH);
+                strncpy(m_name, other.m_name, FIELD_NAME_WIDTH - 1);
+                //field type
+                memset(m_type, 0, FIELD_TYPE_WIDTH);
+                strncpy(m_type, other.m_name, FIELD_TYPE_WIDTH - 1);
+                //field width
+                m_width = other.m_width;
+                return *this;
+            }
+
+        public:
+        char m_name[FIELD_NAME_WIDTH];
+        char m_type[FIELD_TYPE_WIDTH];
+        int m_width;
+};
+
+const int RECORD_NAME_WIDTH = 128;
+const int RECORD_SIZE_WIDTH = 2;
+
+class MetaData_Record{
+    public:
+        MetaData_Record() {};
+        char m_name[RECORD_NAME_WIDTH];
+        std::vector<MetaData_Field> vField;
+};
+
+class MetaData{
+    public:
+        char m_version[RECORD_NAME_WIDTH];
+        std::vector<MetaData_Record> m_vec_metadata_record;
+};
+
+#endif
diff --git a/xml2binary/include/metadata_handler.h b/xml2binary/include/metadata_handler.h
new file mode 100644 (file)
index 0000000..c2f9538
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 - 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 __METADATA_HANDLER_H__
+#define __METADATA_HANDLER_H__
+#include <stdio.h>
+#include <libxml/parser.h>
+#include <string.h>
+#include "encode_metadata.h"
+#include "imetadata_encoder.h"
+#include "imetadata_parser.h"
+#include "imetadata_helper.h"
+class MetaData_Handler:private IMetaData_Encoder, IMetaData_Parser, public IMetaData_Helper{
+    private:
+        typedef struct __Metadata_Width {
+            int string_id_width;
+        }MetaData_Width;
+
+    public:
+        MetaData_Handler(const char* file);
+        void set_current_metadata_record(const char* record_name);
+        //encode all strings and output
+        // bin file is assigned by parameter "file"
+        int encode(const char* file)const;
+
+        //encode all strings and output
+        // bin file is assigned by parameter "file"
+        int encode(const char* file, int&offset)const;
+
+        // encode all strings and output to storage
+        int encode(ResourceStorage& storage)const;
+
+        unsigned short get_width(const char* field_name) const;
+
+    private:
+        unsigned short get_width(const char* name, const MetaData_Record& metadata_record) const;
+        int find_metadata_record_index(const char* name) const;
+        int parsing_field(const xmlNodePtr node, MetaData_Field& data, const MetaData_Width& metadataWidth);
+        int parsing_record(const xmlNodePtr curNode, MetaData_Record& metadataRecord, const MetaData_Width& metadataWidth);
+        int parsing_metadata_type(const xmlNodePtr curNode, MetaData_Width& metadataWidth);
+        void parsing_metadata();
+        const MetaData* get_metadata()const;
+
+    private:
+        MetaData metadata;
+        int m_current_metadata_record_id;
+        const char* file_name;
+};
+#endif
diff --git a/xml2binary/include/resource_storage.h b/xml2binary/include/resource_storage.h
new file mode 100644 (file)
index 0000000..01c9b6e
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012 - 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 __RESOURCE_STORAGE_H__
+#define __RESOURCE_STORAGE_H__
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <sstream>
+#include "istring_encoder.h"
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+typedef char int8;
+typedef short int16;
+typedef int int32;
+typedef long long int64;
+typedef float float32;
+typedef double float64;
+
+typedef uint64 uint_t;
+typedef int64 sint_t;
+typedef float64 float_t;
+
+/* use string_encoder to collect strings and encode them when necessary*/
+extern IString_Encoder& string_encoder;
+
+class ResourceStorage{
+    private:
+    static const int __NEW_LENGTH__ = 0x10000;/*64k*/
+    static const int __RE_NEW_LENGTH__ = 0x10000;/*64k*/
+    static const int __MAX_NEW_SIZE__ = 0x2000000;/*32M*/
+
+    public:
+    ResourceStorage();
+    ~ResourceStorage();
+
+    // use reserve for temp reserve
+    // latter we can use random_put to put values
+    void reserve(int bytes);
+
+    // put the string to storage
+    void put(const char* str);
+
+    // encode the string id
+    void encode_string(const char* str, int width);
+
+    // put the data to storage with width assigned as para
+    // It is specially for:
+    // 1) sint_t(signed integer, includes int8, int16, int32, int64),
+    // 2) uint_t(unsigned integer, includes uint8, uint16, uint32, uint64),
+    // 3) float_t(float type, includes float32, float64)
+    // other type will get a complie error
+    template <typename T>
+        int put(T data, int width);
+
+    // put the data to a random_offset assigned by parameter "random_offset"
+    // after done, it will go back to current offset of the file
+    template <typename T>
+        int random_put(T data, int width, int random_offset);
+
+    // get the current used size
+    int get_size() const;
+
+    // get the capability of the storage
+    int capability() const;
+
+    // put the storage array to file
+    // the fileName assigned
+    // return size that put
+    int toFile(const char* fileName);
+
+    // put the storage array to file
+    // the fileName and offset assigned
+    // return size that put
+    int toFile(const char* fileName, int& offset);
+
+    // put the storage array to a big storage
+    // return size that put
+    int storage_cat(ResourceStorage& storage);
+
+    private:
+    void init();
+
+    /*template <typename T>
+    void put_primitive_data(T data, MetaType type, bool ignore = false);*/
+
+    // This function is used to check whether the
+    // storage is enough
+    // the para "width" is the size of request to use
+    void check_storage(int width);
+
+    // If the space is not enough, use this function to
+    // new a new storage
+    void expand_storage();
+
+    /*****************put methods****************/
+
+    //unify put_xx method name
+    //the width is sizeof(T)
+    template <typename T>
+    void put_primitive_data(T data);
+
+    void put_uint8(uint8 data);
+    void put_uint16(uint16 data);
+    void put_uint32(uint32 data);
+    void put_uint64(uint64 data);
+    void put_int8(int8 data);
+    void put_int16(int16 data);
+    void put_int32(int32 data);
+    void put_int64(int64 data);
+    void put_float32(float32 data);
+    void put_float64(float64 data);
+    /*****************put methods end****************/
+
+
+    //Pointer to the storage
+    char* m_storage;
+
+    //Record the actual used size
+    int m_size;
+
+    //The total size of the Storage
+    int m_capability;
+};
+#endif
diff --git a/xml2binary/include/resource_storage_impl.h b/xml2binary/include/resource_storage_impl.h
new file mode 100644 (file)
index 0000000..d4d10fc
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2012 - 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 __RESOURCE_STORAGE_IMPL_H__
+#define __RESOURCE_STORAGE_IMPL_H__
+#include "resource_storage.h"
+#include <dlog.h>
+
+inline ResourceStorage::
+ResourceStorage() {
+    init();
+}
+
+inline void ResourceStorage::init() {
+    m_storage = new char[__NEW_LENGTH__];
+    if (m_storage == NULL) {
+        //throw "init error of ResourceStorage";
+        m_size = 0;
+        m_capability = 0;
+    } else {
+        m_size = 0;
+        m_capability = __NEW_LENGTH__;
+    }
+}
+inline ResourceStorage::
+~ResourceStorage() {
+    delete []m_storage;
+    m_size = 0;
+    m_capability = 0;
+}
+
+inline int ResourceStorage::
+get_size() const {
+    return m_size;
+}
+
+
+inline void ResourceStorage::
+put(const char* str) {
+    /*Not allowed str null here*/
+    assert(str != NULL);
+    int len = strlen(str);
+    /*1(record string length) + len + 1(\0))*/
+    int width = 1 + len + 1;
+    check_storage(width);
+    *(m_storage + m_size) = len;
+    m_size += 1;
+
+    memcpy(m_storage + m_size, str, len);
+    m_size += len;
+
+    /*Add '\0' to the end*/
+    *(m_storage + m_size) = '\0';
+    m_size += 1;
+}
+
+inline int ResourceStorage::
+capability() const {
+    return m_capability;
+}
+
+inline int ResourceStorage::
+toFile(const char* fileName) {
+    if (m_storage == NULL) {
+        return -1;
+    }
+    FILE *fp = fopen(fileName, "rb+");
+    if (!fp) {
+        perror(fileName);
+        return -1;
+    }
+
+    int actual_size = m_size;
+    fwrite(m_storage, actual_size, 1, fp);
+    fclose(fp);
+
+    return actual_size;
+}
+inline int ResourceStorage::
+toFile(const char* fileName, int& offset) {
+    if (m_storage == NULL) {
+        return -1;
+    }
+    FILE *fp = fopen(fileName, "rb+");
+    if (!fp) {
+        perror(fileName);
+        return -1;
+    }
+
+    if (0 != fseek(fp, offset, 0)) {
+        perror(fileName);
+        fclose(fp);
+        return -1;
+    }
+
+    if (m_size < 0) {
+        fclose(fp);
+        return -1;
+    }
+    fwrite(m_storage, m_size, 1, fp);
+    fclose(fp);
+
+    offset += m_size;
+    return m_size;
+}
+inline void ResourceStorage::
+reserve(int bytes) {
+    check_storage(bytes);
+    m_size += bytes;
+}
+inline int ResourceStorage::
+storage_cat(ResourceStorage& storage) {
+    if (storage.get_size() == 0) return 0;
+
+    int size = storage.get_size();
+    check_storage(size);
+    memcpy(m_storage + m_size, storage.m_storage, size);
+
+    m_size += size;
+    return m_size;
+}
+
+inline void ResourceStorage::
+check_storage(int width) {
+    if (m_size + width > m_capability) {
+        expand_storage();
+    }
+}
+inline void ResourceStorage::
+expand_storage() {
+    unsigned int _new_size = (unsigned int)(m_capability + __RE_NEW_LENGTH__);
+    if (_new_size > (unsigned int)__MAX_NEW_SIZE__) {
+        LOGW("expand_storage failed: size is limited to %d\n", __MAX_NEW_SIZE__);
+        return;
+    }
+
+    char* _p = new char[_new_size];
+    if (_p == NULL) {
+        LOGW("expand_storage error\n");
+        return;
+    }
+    memset(_p, 0x00, _new_size);
+    memcpy(_p, m_storage, m_size);
+    delete[] m_storage;
+
+    m_storage = _p;
+    m_capability = _new_size;
+
+    _p = NULL;
+}
+///////////////////////////////////////
+inline void ResourceStorage::
+put_uint8(uint8 data) {
+    check_storage(sizeof(uint8));
+    uint8* p = (uint8*)(m_storage + m_size);
+    *p = data;
+    m_size += sizeof(uint8);
+}
+inline void ResourceStorage::
+put_uint16(uint16 data) {
+    check_storage(sizeof(uint16));
+    uint16* p = (uint16*)(m_storage + m_size);
+    *p = data;
+    m_size += sizeof(uint16);
+}
+inline void ResourceStorage::
+put_uint32(uint32 data) {
+    check_storage(sizeof(uint32));
+    uint32* p = (uint32*)(m_storage + m_size);
+    *p = data;
+    m_size += sizeof(uint32);
+}
+inline void ResourceStorage::
+put_uint64(uint64 data) {
+    check_storage(sizeof(uint64));
+    uint64* p = (uint64*)(m_storage + m_size);
+    *p = data;
+    m_size += sizeof(uint64);
+}
+// signed value --> unsigned value
+//that is ok
+inline void ResourceStorage::
+put_int8(int8 data) {
+    put_uint8(data);
+}
+inline void ResourceStorage::
+put_int16(int16 data) {
+    put_uint16(data);
+}
+inline void ResourceStorage::
+put_int32(int32 data) {
+    put_uint32(data);
+}
+inline void ResourceStorage::
+put_int64(int64 data) {
+    put_uint64(data);
+}
+
+//float32
+inline void ResourceStorage::
+put_float32(float32 data) {
+    union{
+        float32 m;
+        uint32 n;
+    };
+
+    m = data;
+    put_uint32(n);
+}
+//float64
+inline void ResourceStorage::
+put_float64(float64 data) {
+    union{
+        float64 m;
+        uint64 n;
+    };
+
+    m = data;
+    put_uint64(n);
+}
+
+//unify put_xx method name
+//the width is sizeof(T)
+template <>
+inline void ResourceStorage::
+put_primitive_data<uint8>(uint8 data) {
+    put_uint8(data);
+}
+template <>
+inline void ResourceStorage::
+put_primitive_data<uint16>(uint16 data) {
+    put_uint16(data);
+}
+template <>
+inline void ResourceStorage::
+put_primitive_data<uint32>(uint32 data) {
+    put_uint32(data);
+}
+template <>
+inline void ResourceStorage::
+put_primitive_data<uint64>(uint64 data) {
+    put_uint64(data);
+}
+template <>
+inline void ResourceStorage::
+put_primitive_data<int8>(int8 data) {
+    put_int8(data);
+}
+template <>
+inline void ResourceStorage::
+put_primitive_data<int16>(int16 data) {
+    put_int16(data);
+}
+template <>
+inline void ResourceStorage::
+put_primitive_data<int32>(int32 data) {
+    put_int32(data);
+}
+template <>
+inline void ResourceStorage::
+put_primitive_data<int64>(int64 data) {
+    put_int64(data);
+}
+template <>
+inline void ResourceStorage::
+put_primitive_data<float32>(float32 data) {
+    put_float32(data);
+}
+template <>
+inline void ResourceStorage::
+put_primitive_data<float64>(float64 data) {
+    put_float64(data);
+}
+
+//put integer value to storage
+//width is assigned by para "width"
+template <>
+inline int ResourceStorage::
+put<sint_t>(sint_t data, int width) {
+    switch (width) {
+        case 0:
+            /*Nothing to put*/
+            break;
+        case 1:
+            put_primitive_data<int8>((int8)data);
+            break;
+        case 2:
+            put_primitive_data<int16>((int16)data);
+            break;
+        case 4:
+            put_primitive_data<int32>((int32)data);
+            break;
+        case 8:
+            put_primitive_data<int64>((int64)data);
+            break;
+        default:
+            return -1;
+    }
+
+    return 0;
+}
+template <>
+inline int ResourceStorage::
+put<uint_t>(uint_t data, int width) {
+    switch (width) {
+        case 0:
+            /*Nothing to put*/
+            break;
+        case 1:
+            put_primitive_data<uint8>((uint8)data);
+            break;
+        case 2:
+            put_primitive_data<uint16>((uint16)data);
+            break;
+        case 4:
+            put_primitive_data<uint32>((uint32)data);
+            break;
+        case 8:
+            put_primitive_data<uint64>((uint64)data);
+            break;
+        default:
+            return -1;
+    }
+
+    return 0;
+}
+template <>
+inline int ResourceStorage::
+put<float_t>(float_t data, int width) {
+    switch (width) {
+        case 0:
+            break;
+        case 4:
+            put_primitive_data<float32>((float32)data);
+            break;
+        case 8:
+            put_primitive_data<float64>((float64)data);
+            break;
+        default:
+            return -1;
+    }
+    return 0;
+}
+template<>
+inline int ResourceStorage::
+random_put<sint_t>(sint_t data, int width, int offset) {
+    if (offset <0 || offset + width > m_size) {
+        return -1;
+    }
+
+    //remember current_offset
+    int current_offset = m_size;
+
+    //temperary turn to random_offset
+    int random_offset = offset;
+    m_size = random_offset;
+
+    int ret = put<sint_t>(data, width);
+    //reback to current_offset
+    m_size = current_offset;
+
+    return ret;
+}
+template<>
+inline int ResourceStorage::
+random_put<uint_t>(uint_t data, int width, int offset) {
+    if (offset <0 || offset + width > m_size) {
+        return -1;
+    }
+
+    //remember current_offset
+    int current_offset = m_size;
+
+    //temperary turn to random_offset
+    int random_offset = offset;
+    m_size = random_offset;
+
+    int ret = put<uint_t>(data, width);
+    //reback to current_offset
+    m_size = current_offset;
+
+    return ret;
+}
+template <>
+inline int ResourceStorage::
+random_put<float_t>(float_t data, int width, int offset) {
+    if (offset <0 || offset + width > m_size) {
+        return -1;
+    }
+
+    //remember current_offset
+    int current_offset = m_size;
+
+    //temperary turn to random_offset
+    int random_offset = offset;
+    m_size = random_offset;
+
+    int ret = put<float_t>(data, width);
+    //reback to current_offset
+    m_size = current_offset;
+
+    return ret;
+}
+
+///////////////////////////////////////
+inline void ResourceStorage::
+encode_string(const char* str, int width) {
+    if (width <= 0) return;
+
+    int id = string_encoder.add(str);
+    put<sint_t>(id, width);
+}
+
+
+#endif
diff --git a/xml2binary/include/string_encoder.h b/xml2binary/include/string_encoder.h
new file mode 100644 (file)
index 0000000..9a7c0b7
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012 - 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 __STRING_ENCODER_H__
+#define __STRING_ENCODER_H__
+#include "istring_encoder.h"
+#include "resource_storage_impl.h"
+#include <vector>
+#include <string>
+/* limit the max num to 2^32-1*/
+const int MAX_NUM_WIDTH = 4;
+
+class String_Encoder:public IString_Encoder{
+    public:
+        String_Encoder() {
+            m_file.clear();
+        }
+
+        void set_path(const char* file) {
+            m_file = file;
+        }
+
+        /* @ insert str to string vector */
+        /* @ return the ID of the str */
+        int add(const char* str) {
+            if (str == NULL) return -1;
+
+            std::string str_temp = std::string(str);
+
+            /* check if the str_temp is already in the vector*/
+            std::vector<std::string>::iterator it;
+            for (it = m_vec_string.begin(); it != m_vec_string.end(); ++it) {
+                if (str_temp == *it) {
+                    return (it - m_vec_string.begin());
+                }
+            }
+
+            /* the str_temp is not in the vector, so insert it to the vector*/
+            m_vec_string.push_back(str_temp);
+            return m_vec_string.size() -1;
+        }
+        int encode() const {
+            ResourceStorage storage;
+            encode(storage);
+            storage.toFile(m_file.c_str());
+            return storage.get_size();
+        }
+        int encode(int& offset) const {
+            ResourceStorage storage;
+            encode(storage);
+            storage.toFile(m_file.c_str(), offset);
+
+            return storage.get_size();
+        }
+
+        int encode(ResourceStorage& storage) const {
+            /* record the strings' num*/
+            storage.put<sint_t>(m_vec_string.size(), MAX_NUM_WIDTH);
+
+            /* record each string*/
+            std::vector<std::string>::const_iterator it;
+            for (it = m_vec_string.begin(); it != m_vec_string.end(); ++it) {
+                storage.put(it->c_str());
+            }
+
+            return storage.get_size();
+        }
+
+    private:
+        std::vector<std::string> m_vec_string;
+        std::string m_file;
+};
+#endif
diff --git a/xml2binary/metadata_handler.cpp b/xml2binary/metadata_handler.cpp
new file mode 100644 (file)
index 0000000..f002323
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2012 - 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 "metadata_handler.h"
+
+MetaData_Handler::
+MetaData_Handler(const char* file) {
+    this->file_name = file;
+    m_current_metadata_record_id = -1;
+    parsing_metadata();
+}
+
+void MetaData_Handler::
+set_current_metadata_record(const char* record_name) {
+    if (record_name == NULL) {
+        m_current_metadata_record_id = -1;
+        return;
+    }
+    int idx = find_metadata_record_index(record_name);
+
+    m_current_metadata_record_id = idx;
+}
+
+int MetaData_Handler::
+encode(const char* file)const {
+    ResourceStorage storage;
+    encode_metadata(storage, metadata);
+    storage.toFile(file);
+
+    return storage.get_size();
+}
+
+int MetaData_Handler::
+encode(const char* file, int& offset)const {
+    ResourceStorage storage;
+    encode_metadata(storage, metadata);
+    storage.toFile(file, offset);
+
+    return storage.get_size();
+}
+
+int MetaData_Handler::
+encode(ResourceStorage& storage)const {
+    encode_metadata(storage, metadata);
+    return storage.get_size();
+}
+
+unsigned short MetaData_Handler::
+get_width(const char* field_name) const {
+    if (field_name == NULL) return 0;
+
+    int idx = m_current_metadata_record_id;
+    if (idx < 0 || idx > (int)metadata.m_vec_metadata_record.size()) return 0;
+
+    const MetaData_Record&  metadata_record = metadata.m_vec_metadata_record.at(idx);
+
+    int width = get_width(field_name, metadata_record);
+
+    return width;
+}
+
+unsigned short MetaData_Handler::
+get_width(const char* name, const MetaData_Record& metadata_record) const {
+    assert(name);
+    for (size_t i = 0; i < metadata_record.vField.size(); ++i) {
+        if (0 == strcmp(name, metadata_record.vField.at(i).m_name)) {
+            return metadata_record.vField.at(i).m_width;
+        }
+    }
+    return 0;
+}
+
+int MetaData_Handler::
+find_metadata_record_index(const char* name)const {
+    assert(name);
+
+    for (size_t i = 0; i < metadata.m_vec_metadata_record.size(); ++i) {
+        const MetaData_Record& metadata_record = metadata.m_vec_metadata_record.at(i);
+
+        if (0 == strcmp(metadata_record.m_name, name)) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+int MetaData_Handler::
+parsing_field(const xmlNodePtr node, MetaData_Field& data, const MetaData_Width& metadataWidth) {
+    memset(data.m_name, 0, sizeof(data.m_name));
+    memset(data.m_type, 0, sizeof(data.m_type));
+    data.m_width = 0;
+
+    xmlChar* name = xmlGetProp(node, (const xmlChar*)"name");
+    if (name == NULL) return -1;
+    /*FIXME strncpy ?*/
+    strncpy(data.m_name, (const char*)name, sizeof(data.m_name));
+    data.m_name[sizeof(data.m_name)-1] = '\0';
+    xmlFree(name);
+
+    xmlChar* type = xmlGetProp(node, (const xmlChar*)"type");
+    if (type == NULL) return -1;
+
+    int ret = 0;
+    if (0 == xmlStrcmp(type, (const xmlChar*)"string_id")) {
+        /*FIXME use vaule instead string*/
+        strncpy(data.m_type, (const char*)type, sizeof(data.m_type));
+        data.m_type[sizeof(data.m_type) - 1] = '\0';
+        data.m_width = metadataWidth.string_id_width;
+    } else if (0 == xmlStrcmp(type, (const xmlChar*)"int8")) {
+        strncpy(data.m_type, (const char*)type, sizeof(data.m_type));
+        data.m_type[sizeof(data.m_type) - 1] = '\0';
+        data.m_width = 1;
+    } else if (0 == xmlStrcmp(type, (const xmlChar*)"int16")) {
+        strncpy(data.m_type, (const char*)type, sizeof(data.m_type));
+        data.m_type[sizeof(data.m_type) - 1] = '\0';
+        data.m_width = 2;
+    } else if (0 == xmlStrcmp(type, (const xmlChar*)"int32")) {
+        strncpy(data.m_type, (const char*)type, sizeof(data.m_type));
+        data.m_type[sizeof(data.m_type) - 1] = '\0';
+        data.m_width = 4;
+    } else if (0 == xmlStrcmp(type, (const xmlChar*)"float32")) {
+        strncpy(data.m_type, (const char*)type, sizeof(data.m_type));
+        data.m_type[sizeof(data.m_type) - 1] = '\0';
+        data.m_width = 4;
+    } else if (0 == xmlStrcmp(type, (const xmlChar*)"float64")) {
+        strncpy(data.m_type, (const char*)type, sizeof(data.m_type));
+        data.m_type[sizeof(data.m_type) - 1] = '\0';
+        data.m_width = 8;
+    } else {
+        ret = -1;
+    }
+
+    xmlFree(type);
+
+    return ret;
+}
+
+int MetaData_Handler::
+parsing_record(const xmlNodePtr curNode, MetaData_Record& metadataRecord, const MetaData_Width& metadataWidth) {
+    //parsing struct name
+    xmlChar* name = xmlGetProp(curNode, (const xmlChar*)"name");
+    if (name == NULL) return -1;
+    strncpy(metadataRecord.m_name, (const char*)name, sizeof(metadataRecord.m_name));
+    metadataRecord.m_name[sizeof(metadataRecord.m_name)-1] = '\0';
+    xmlFree(name);
+
+    xmlNodePtr childNode = curNode->xmlChildrenNode;
+
+    while (childNode != NULL) {
+        if (0 == xmlStrcmp(childNode->name, (const xmlChar *)"field")) {
+            MetaData_Field data;
+            int ret = parsing_field(childNode, data, metadataWidth);
+            if (ret != -1) {
+                metadataRecord.vField.push_back(data);
+            }
+        }
+
+        childNode = childNode->next;
+    }
+    return 0;
+}
+int MetaData_Handler::
+parsing_metadata_type(const xmlNodePtr curNode, MetaData_Width& metadataWidth) {
+    assert(curNode != NULL);
+    xmlNodePtr childNode = curNode->xmlChildrenNode;
+
+    while (childNode != NULL) {
+        if (0 == xmlStrcmp(childNode->name, (const xmlChar *)"type")) {
+            xmlChar* xmlname = xmlGetProp(childNode, (const xmlChar*)"name");
+            if (xmlname == NULL) continue;
+            xmlChar* xmlwidth = xmlGetProp(childNode, (const xmlChar*)"width");
+            if (xmlwidth == NULL) {
+                xmlFree(xmlname);
+                continue;
+            }
+
+            /*FIXME how to assume that the atoi will get the correct num*/
+            int width = atoi((const char*)xmlwidth);
+
+            if (0 == xmlStrcmp(xmlname, (const xmlChar*)"string_id")) {
+                metadataWidth.string_id_width = width;
+            }
+
+            xmlFree(xmlname);
+            xmlFree(xmlwidth);
+        }
+
+        childNode = childNode->next;
+    }
+    return 0;
+}
+void MetaData_Handler::
+parsing_metadata() {
+    xmlDocPtr doc;
+    xmlNodePtr curNode;
+
+    doc = xmlReadFile(file_name, NULL, 0);
+    if (doc == NULL) {
+        LOGE("Could not load file.\n");
+        return;
+    }
+
+    curNode = xmlDocGetRootElement(doc);
+    if (curNode == NULL) {
+        LOGE("empty document.\n");
+        xmlFreeDoc(doc);
+        return;
+    }
+    if (0 != xmlStrcmp(curNode->name, (const xmlChar*)"metadata"))
+    {
+        LOGE("root name %s error!\n", curNode->name);
+        xmlFreeDoc(doc);
+        return;
+    }
+
+    xmlChar* version = xmlGetProp(curNode, (const xmlChar*)"version");
+    if (version) {
+        strncpy(metadata.m_version, (const char*)version, sizeof(metadata.m_version));
+        metadata.m_version[sizeof(metadata.m_version)-1] = '\0';
+        xmlFree(version);
+    } else {
+        metadata.m_version[0] = '\0';
+    }
+
+    MetaData_Width metadataWidth;
+    curNode = curNode->xmlChildrenNode;
+    while (curNode) {
+        if (0 == xmlStrcmp(curNode->name, (const xmlChar*)"metadata_type")) {
+            parsing_metadata_type(curNode, metadataWidth);
+        } else if (0 == xmlStrcmp(curNode->name, (const xmlChar*)"record")) {
+            MetaData_Record metadataRecord;
+            int ret = parsing_record(curNode, metadataRecord, metadataWidth);
+            if (ret != -1) {
+                metadata.m_vec_metadata_record.push_back(metadataRecord);
+            }
+        }
+        curNode = curNode->next;
+    }
+    xmlFreeDoc(doc);
+}
+
+inline const MetaData* MetaData_Handler::
+get_metadata()const {
+    return &metadata;
+}
diff --git a/xml2binary/xml2dat.cpp b/xml2binary/xml2dat.cpp
new file mode 100644 (file)
index 0000000..c29eac9
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2012 - 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 <limits.h>
+#include <unistd.h>
+#include "string_encoder.h"
+#include "metadata_handler.h"
+#include "encode_layout.h"
+#include "encode_input_mode_configure.h"
+#include "encode_key_coordinate_frame.h"
+#include "encode_label_properties_frame.h"
+#include "encode_modifier_decoration.h"
+#include "encode_default_configure.h"
+#include "encode_magnifier_configure.h"
+#include "encode_autopopup_configure.h"
+#include "encode_nine_patch.h"
+#include "xmlresource.h"
+using namespace xmlresource;
+using namespace std;
+
+String_Encoder actual_string_encoder;
+IString_Encoder& string_encoder = actual_string_encoder;
+
+static inline void show_usage() {
+    static const char* message = {  "xml2binary: missing folder operand\n"
+                                    "-------------------------------------------------------\n"
+                                    "|  Usage: xml2binary operand1 operand2                |\n"
+                                    "|  operand1: the folder where xml text files located  |\n"
+                                    "|  operand2: the folder you want to place the bin file|\n"
+                                    "------------------------------------------------------- \n"};
+    printf("%s", message);
+}
+
+int main(const int argc, char* argv[]) {
+    if (argc < 2) {
+        show_usage();
+        return -1;
+    }
+
+    char* xml_text_dir = NULL;
+    if (argv[1])
+        xml_text_dir = strdup(argv[1]);
+
+    if (xml_text_dir) {
+        if (0 != access(xml_text_dir, R_OK)) {
+            perror(xml_text_dir);
+            free(xml_text_dir);
+            return -1;
+        } else {
+            free(xml_text_dir);
+            xml_text_dir = NULL;
+        }
+    }
+
+    char* xml_bin_dir = NULL;
+    if (argc < 3) {
+        if (argv[1])
+            xml_bin_dir = strdup(argv[1]);
+    } else {
+        if (argv[2])
+            xml_bin_dir = strdup(argv[2]);
+    }
+
+    if (xml_bin_dir) {
+        if (0 != access(xml_bin_dir, W_OK)) {
+            perror(xml_bin_dir);
+            free(xml_bin_dir);
+            return -1;
+        } else {
+            free(xml_bin_dir);
+            xml_bin_dir = NULL;
+            return -1;
+        }
+    } else {
+        return -1;
+    }
+
+    XMLResource *xmlresource = XMLResource::get_instance();
+    if (!xmlresource) {
+        printf("Failed build xmlresource instance.\n");
+        return -1;
+    }
+
+    xmlresource->set_resource_directory(xml_text_dir);
+    xmlresource->init("main_entry.xml");
+
+    static const char* metadata_path = "/usr/share/libscl-ui/metadata.xml";
+    if (0 != access(metadata_path, R_OK)) {
+        perror(metadata_path);
+        return -1;
+    }
+
+    MetaData_Handler md_handler(metadata_path);
+
+    char bin_file[_POSIX_PATH_MAX] = {0};
+    snprintf(bin_file, _POSIX_PATH_MAX, "%s/%s", xml_bin_dir, "sclresource.bin");
+
+    FILE *fp = fopen(bin_file, "wb");
+    if (!fp) {
+        perror(bin_file);
+        return -1;
+    }
+    fclose(fp);
+
+    enum{
+        ALLDATA = 0,
+        METADATA,
+        INPUT_MODE_CONFIGURE,
+        LAYOUT,
+        KEY_COORDINATE_FRAME,
+        LABEL_PROPERTIES_FRAME,
+        MODIFIER_DECORATION,
+        DEFAULT_CONFIGURE,
+        AUTOPOPUP_CONFIGURE,
+        MAGNIFIER_CONFIGURE,
+        NINE_PATCH,
+        STRING,
+        MAX_DATATYPE
+    };
+
+    int size_table[MAX_DATATYPE] = {0};
+    int offset_table[MAX_DATATYPE] = {0};
+    const int _SIZE_WIDTH = 8;
+    const int OFFSET_WIDTH = 8;
+    int offset = 0;
+    {
+        //Reserve for size_table
+        ResourceStorage rs;
+        rs.reserve(MAX_DATATYPE * (_SIZE_WIDTH + OFFSET_WIDTH));
+        int ret = rs.toFile(bin_file, offset);
+        if (ret < 0) {
+            printf("error\n");
+            return -1;
+        }
+    }
+
+    offset_table[METADATA] = offset;
+    size_table[METADATA] = md_handler.encode(bin_file, offset);
+    offset_table[INPUT_MODE_CONFIGURE] = offset;
+    size_table[INPUT_MODE_CONFIGURE] = encode_input_mode_configure_file(bin_file, offset, md_handler);
+
+    offset_table[LAYOUT] = offset;
+    size_table[LAYOUT] = encode_layout_file(bin_file, offset, md_handler);
+
+    offset_table[KEY_COORDINATE_FRAME] = offset;
+    size_table[KEY_COORDINATE_FRAME] = encode_key_coordinate_frame_file(bin_file, offset, md_handler);
+
+    offset_table[LABEL_PROPERTIES_FRAME] = offset;
+    size_table[LABEL_PROPERTIES_FRAME] = encode_label_properties_frame_file(bin_file, offset, md_handler);
+
+    offset_table[MODIFIER_DECORATION] = offset;
+    size_table[MODIFIER_DECORATION] = encode_modifier_decoration_file(bin_file, offset, md_handler);
+
+    offset_table[DEFAULT_CONFIGURE] = offset;
+    size_table[DEFAULT_CONFIGURE] = encode_default_configure_file(bin_file, offset, md_handler);
+
+    offset_table[AUTOPOPUP_CONFIGURE] = offset;
+    size_table[AUTOPOPUP_CONFIGURE] = encode_autopopup_configure_file(bin_file, offset, md_handler);
+
+    offset_table[MAGNIFIER_CONFIGURE] = offset;
+    size_table[MAGNIFIER_CONFIGURE] = encode_magnifier_configure_file(bin_file, offset, md_handler);
+
+    offset_table[NINE_PATCH] = offset;
+    size_table[NINE_PATCH] = encode_nine_patch_file(bin_file, offset, md_handler);
+
+    offset_table[STRING] = offset;
+    actual_string_encoder.set_path(bin_file);
+    size_table[STRING] = string_encoder.encode(offset);
+
+    offset_table[ALLDATA] = 0;
+    size_table[ALLDATA]= offset;
+
+    {
+        ResourceStorage rs;
+        for (int i = 0; i < MAX_DATATYPE; ++i) {
+            rs.put<sint_t>(size_table[i], _SIZE_WIDTH);
+            rs.put<sint_t>(offset_table[i], OFFSET_WIDTH);
+        }
+
+        int bin_offset = 0;
+        int ret = rs.toFile(bin_file, bin_offset);
+        if (ret < 0) {
+            printf("error\n");
+            return -1;
+        }
+    }
+
+    printf("xml2binary successfully.\n");
+
+    return 0;
+}