From: Jihoon Kim Date: Fri, 7 May 2021 02:22:58 +0000 (+0900) Subject: Upload libscl-ui original code X-Git-Tag: submit/tizen/20210803.031958~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F97%2F262097%2F1;p=platform%2Fcore%2Fuifw%2Flibscl-ui-nui.git Upload libscl-ui original code Change-Id: I16d13eec7a507ab4a84418b86eed5cda677c07f8 Signed-off-by: Jihoon Kim --- diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..e28dee6 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +Developer: + Ji-hoon Lee + Yanjie Hu diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..98b9ca2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,135 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(libscl-ui 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/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__EFL__") + +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/libscl-ui) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclconfig.h" DESTINATION include/libscl-ui) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclstructs.h" DESTINATION include/libscl-ui) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/scleventcallback.h" DESTINATION include/libscl-ui) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclutils.h" DESTINATION include/libscl-ui) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclfeedback.h" DESTINATION include/libscl-ui) + +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) +INSTALL(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIBDIR}/pkgconfig) diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..5737e30 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,4 @@ +2012-02-21 11:15 Ji-hoon Lee + + Initial version. + diff --git a/INSTALL b/INSTALL new file mode 100644 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 `' 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 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 index 0000000..e69de29 diff --git a/NOTICE b/NOTICE new file mode 100644 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 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/packaging/libscl-ui.changes b/packaging/libscl-ui.changes new file mode 100644 index 0000000..e69de29 diff --git a/packaging/libscl-ui.spec b/packaging/libscl-ui.spec new file mode 100644 index 0000000..4c15b59 --- /dev/null +++ b/packaging/libscl-ui.spec @@ -0,0 +1,89 @@ +%bcond_with x +%bcond_with wayland + +Name: libscl-ui +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(elementary) +BuildRequires: pkgconfig(eldbus) +%if %{with wayland} +BuildRequires: pkgconfig(ecore-wl2) +%else +BuildRequires: pkgconfig(ecore-x) +BuildRequires: pkgconfig(x11) +%endif +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 + +%if %{with wayland} +%cmake . -Dwith_wayland=TRUE +%else +%cmake . +%endif +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}/%{name}.so +%license LICENSE + +%files devel +%defattr(-,root,root,-) +%{_includedir}/* +%{_libdir}/pkgconfig/%{name}.pc diff --git a/res/put_record.h b/res/put_record.h new file mode 100644 index 0000000..9c0deef --- /dev/null +++ b/res/put_record.h @@ -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 +#include +#include +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 index 0000000..06c2b25 --- /dev/null +++ b/res/sclresource.cpp @@ -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 +#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 index 0000000..6dd8341 --- /dev/null +++ b/res/sclresource.h @@ -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 index 0000000..064cfd5 --- /dev/null +++ b/res/sclresourcekeys.h @@ -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 index 0000000..e1dbedb --- /dev/null +++ b/res/simple_debug.cpp @@ -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 +#include +#include +#include +#include +#include +#include + +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 index 0000000..4f9a9cc --- /dev/null +++ b/res/simple_debug.h @@ -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 + +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 index 0000000..9c662c9 --- /dev/null +++ b/res/simple_debug_test.cpp @@ -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 +#include + +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 index 0000000..0441ba5 --- /dev/null +++ b/scl/_auto_metadata.h @@ -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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 index 0000000..2584604 --- /dev/null +++ b/scl/autopopup_configure_bin_parser.cpp @@ -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 +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(width); + color.g = m_storage.get(width); + color.b = m_storage.get(width); + color.a = m_storage.get(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(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(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(record_width.sw_button_style); + + //button_width + cur->button_width = m_storage.get(record_width.button_width); + + //button_height + cur->button_height = m_storage.get(record_width.button_height); + + //button_spacing + cur->button_spacing = m_storage.get(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(record_width.decoration_size); + + //max_column + cur->max_column = m_storage.get(record_width.max_column); + + //add_grab_left + cur->add_grab_left = m_storage.get(record_width.add_grab_left); + + //add_grab_right + cur->add_grab_right = m_storage.get(record_width.add_grab_right); + + //add_grab_top + cur->add_grab_top = m_storage.get(record_width.add_grab_top); + + //add_grab_bottom + cur->add_grab_bottom = m_storage.get(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 index 0000000..a904708 --- /dev/null +++ b/scl/autopopup_configure_bin_parser.h @@ -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 index 0000000..2a0ee32 --- /dev/null +++ b/scl/autopopup_configure_parser.cpp @@ -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 +#include +#include + +#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 index 0000000..86bc848 --- /dev/null +++ b/scl/autopopup_configure_parser.h @@ -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 index 0000000..25b29e3 --- /dev/null +++ b/scl/binary_xmlresource.cpp @@ -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 +#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(_SIZE_WIDTH); + offset_table[i] = headerStorage.get(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 index 0000000..890111c --- /dev/null +++ b/scl/binary_xmlresource.h @@ -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 +#include +#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 index 0000000..5e89685 --- /dev/null +++ b/scl/default_configure_bin_parser.cpp @@ -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 +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(width); + color.g = m_storage.get(width); + color.b = m_storage.get(width); + color.a = m_storage.get(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(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(record_width.target_screen_width); + + //target_screen_height + cur->target_screen_height = m_storage.get(record_width.target_screen_height); + + //auto_detect_landscape + cur->auto_detect_landscape = m_storage.get(record_width.auto_detect_landscape); + + //use_magnifier_window + cur->use_magnifier_window = m_storage.get(record_width.use_magnifier_window); + + //use_auto_popup + cur->use_auto_popup = m_storage.get(record_width.use_auto_popup); + + //use_zoom_window + cur->use_zoom_window = m_storage.get(record_width.use_zoom_window); + + //on_error_noti_send + cur->on_error_noti_send = m_storage.get(record_width.on_error_noti_send); + + //use_word_deletion + cur->use_word_deletion = m_storage.get(record_width.use_word_deletion); + + //sw_button_style + cur->sw_button_style = m_storage.get(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(record_width.touch_offset_level); + } + + //touch_offset + for (int i = 0; i < DISPLAYMODE_MAX; ++i) { + cur->touch_offset[i].x = m_storage.get(record_width.touch_offset); + cur->touch_offset[i].y = m_storage.get(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(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 index 0000000..79944dc --- /dev/null +++ b/scl/default_configure_bin_parser.h @@ -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 index 0000000..ef5496c --- /dev/null +++ b/scl/default_configure_parser.cpp @@ -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 +#include +#include +#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 index 0000000..e977907 --- /dev/null +++ b/scl/default_configure_parser.h @@ -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 index 0000000..64d5702 --- /dev/null +++ b/scl/file_storage.cpp @@ -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(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(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 index 0000000..56a5a60 --- /dev/null +++ b/scl/file_storage.h @@ -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 +#include +#include +#include +#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 + 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 + 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 index 0000000..ff4641c --- /dev/null +++ b/scl/file_storage_impl.h @@ -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() { + return get_uint8(); +} +template <> +inline uint16 FileStorage:: +get_primitive_data() { + return get_uint16(); +} + +template <> +inline uint32 FileStorage:: +get_primitive_data() { + return get_uint32(); +} +template <> +inline uint64 FileStorage:: +get_primitive_data() { + return get_uint64(); +} +template <> +inline int8 FileStorage:: +get_primitive_data() { + return get_int8(); +} +template <> +inline int16 FileStorage:: +get_primitive_data() { + return get_int16(); +} + +template <> +inline int32 FileStorage:: +get_primitive_data() { + return get_int32(); +} +template <> +inline int64 FileStorage:: +get_primitive_data() { + return get_int64(); +} +template <> +inline float32 FileStorage:: +get_primitive_data() { + return get_float32(); +} +template <> +inline float64 FileStorage:: +get_primitive_data() { + return get_float64(); +} +//put sint_t value to storage +//width is assigned by para "width" +template <> +inline sint_t FileStorage:: +get(int width) { + switch (width) { + case 0: + /*Nothing to put*/ + break; + case 1: + return get_primitive_data(); + case 2: + return get_primitive_data(); + case 4: + return get_primitive_data(); + case 8: + return get_primitive_data(); + default: + break; + } + return -1; +} +template <> +inline uint_t FileStorage:: +get(int width) { + switch (width) { + case 0: + /*Nothing to put*/ + break; + case 1: + return get_primitive_data(); + case 2: + return get_primitive_data(); + case 4: + return get_primitive_data(); + case 8: + return get_primitive_data(); + default: + break; + } + return -1; +} + +template <> +inline float_t FileStorage:: +get(int width) { + switch (width) { + case 0: + return 0; + case 4: + return (float_t)get_primitive_data(); + case 8: + return (float_t)get_primitive_data(); + default: + break; + } + return -1; +} +#endif diff --git a/scl/imetadata_provider.h b/scl/imetadata_provider.h new file mode 100644 index 0000000..4f30d7b --- /dev/null +++ b/scl/imetadata_provider.h @@ -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 index 0000000..2635a46 --- /dev/null +++ b/scl/input_mode_configure_bin_parser.cpp @@ -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(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(record_width.use_virtual_window); + //use_dim_window + cur->use_dim_window = m_storage.get(record_width.use_dim_window); + + cur->timeout = m_storage.get(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 index 0000000..1c49988 --- /dev/null +++ b/scl/input_mode_configure_bin_parser.h @@ -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 +#include "sclres_type.h" +#include "iparserinfo_provider.h" +#include +#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 index 0000000..19014c0 --- /dev/null +++ b/scl/input_mode_configure_parser.cpp @@ -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 +#include + +#include "input_mode_configure_parser.h" +#include "xml_parser_utils.h" +#include "simple_debug.h" + +/** Example of input mode XML file : + * + * + * + * PORTRAIT_QTY_DEFAULT + * LANDSCAPE_QTY_DEFAULT + * + * + * PORTRAIT_PUNCTUATION_POPUP + * LANDSCAPE_PUNCTUATION_POPUP + * + * + */ + +#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 index 0000000..ad30dec --- /dev/null +++ b/scl/input_mode_configure_parser.h @@ -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 index 0000000..acabba2 --- /dev/null +++ b/scl/iparserinfo_provider.h @@ -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 + +/*** +* 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 index 0000000..7c3ae39 --- /dev/null +++ b/scl/istring_collector.h @@ -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 index 0000000..f1ebae1 --- /dev/null +++ b/scl/istring_provider.h @@ -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 + +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 index 0000000..f4d6f9e --- /dev/null +++ b/scl/key_coordinate_frame_bin_parser.cpp @@ -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 +#include "put_record.h" +#include +#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(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(KEY_NUM_BYTES); + } + + // key_coordinate_rec_data_size + int key_coordinate_rec_data_size = storage.get(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(record_width.x); + //y + cur->y = storage.get(record_width.y); + + //width + cur->width = storage.get(record_width.width); + //height + cur->height = storage.get(record_width.height); + + //add_hit_left + cur->add_hit_left = storage.get(record_width.add_hit_left); + //add_hit_right + cur->add_hit_right = storage.get(record_width.add_hit_right); + //add_hit_top + cur->add_hit_top = storage.get(record_width.add_hit_top); + //add_hit_bottom + cur->add_hit_bottom = storage.get(record_width.add_hit_bottom); + //popup_relative_x + cur->popup_relative_x = storage.get(record_width.popup_relative_x); + //popup_relative_y + cur->popup_relative_y = storage.get(record_width.popup_relative_y); + //extract_offset_x + cur->extract_offset_x = storage.get(record_width.extract_offset_x); + //extract_offset_y + cur->extract_offset_y = storage.get(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(record_width.magnifier_offset_x); + //magnifier_offset_y + cur->magnifier_offset_y = storage.get(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(record_width.button_type); + //key_type + cur->key_type = (SCLKeyType)storage.get(record_width.key_type); + //popup_type + cur->popup_type = (SCLPopupType)storage.get(record_width.popup_type); + + cur->use_magnifier = storage.get(record_width.use_magnifier); + cur->use_long_key_magnifier = storage.get(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(record_width.is_side_button); + + //label_count + cur->label_count = storage.get(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(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(record_width.key_event); + } + } + + //long_key_type + cur->long_key_type = (SCLKeyType)storage.get(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(record_width.long_key_event); + + cur->use_repeat_key = storage.get(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(record_width.autopopup_key_events); + } + } + + cur->dont_close_popup = storage.get(record_width.dont_close_popup); + + //extra_option + cur->extra_option = storage.get(record_width.extra_option); + + //multitouch_type + cur->multitouch_type = storage.get(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 index 0000000..2204995 --- /dev/null +++ b/scl/key_coordinate_frame_bin_parser.h @@ -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 +#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 index 0000000..9db7bb0 --- /dev/null +++ b/scl/label_properties_bin_parser.cpp @@ -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(4); + int maxj = m_storage.get(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(width); + color.g = m_storage.get(width); + color.b = m_storage.get(width); + color.a = m_storage.get(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(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(record_width.alignment); + + //padding_x + cur->padding_x = m_storage.get(record_width.padding_x); + + //padding_y + cur->padding_y = m_storage.get(record_width.padding_y); + + //inner_width + cur->inner_width = m_storage.get(record_width.inner_width); + + //inner_height + cur->inner_height = m_storage.get(record_width.inner_height); + + //shadow_distance + cur->shadow_distance = m_storage.get(record_width.shadow_distance); + + //shadow_direction + cur->shadow_direction = (SCLShadowDirection)m_storage.get(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 index 0000000..694d268 --- /dev/null +++ b/scl/label_properties_bin_parser.h @@ -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 +#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 index 0000000..e2c28c6 --- /dev/null +++ b/scl/label_properties_parser.cpp @@ -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 +#include +#include +#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 index 0000000..b6a7594 --- /dev/null +++ b/scl/label_properties_parser.h @@ -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 index 0000000..bb923f4 --- /dev/null +++ b/scl/layout_bin_parser.cpp @@ -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 +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(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(width); + color.g = m_storage.get(width); + color.b = m_storage.get(width); + color.a = m_storage.get(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(record_width.display_mode); + //style + cur.style = (SCLLayoutStyle)m_storage.get(record_width.style); + //width + cur.width = m_storage.get(record_width.width); + //height + cur.height = m_storage.get(record_width.height); + //use_sw_button + cur.use_sw_button = m_storage.get(record_width.use_sw_button); + + //use_magnifier_window + cur.use_magnifier_window = m_storage.get(record_width.use_magnifier_window); + + //extract_background + cur.extract_background = m_storage.get(record_width.extract_background); + + //key_width + cur.key_width = m_storage.get(record_width.key_width); + //key_height + cur.key_height = m_storage.get(record_width.key_height); + //key_spacing + cur.key_spacing = m_storage.get(record_width.key_spacing); + //row_spacing + cur.row_spacing = m_storage.get(record_width.row_spacing); + //use_sw_background + cur.use_sw_background = m_storage.get(record_width.use_sw_background); + + decode_color(cur.bg_color, record_width.bg_color); + //bg_line_width + cur.bg_line_width = m_storage.get(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(record_width.add_grab_left); + + //add_grab_right + cur.add_grab_right = m_storage.get(record_width.add_grab_right); + //add_grab_top + cur.add_grab_top = m_storage.get(record_width.add_grab_top); + //add_grab_bottom + cur.add_grab_bottom = m_storage.get(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 index 0000000..4903b8a --- /dev/null +++ b/scl/layout_bin_parser.h @@ -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 +#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 index 0000000..836e433 --- /dev/null +++ b/scl/layout_parser.cpp @@ -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 +#include +#include +#include +#include +#include + +#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 + +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 &layout_file_name); + int reload_layout_table(const vector &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 m_file_names; + SclLayoutKeyCoordinate* m_key_coordinate_pointer_frame[MAX_SCL_LAYOUT][MAX_KEY]; + + std::vector m_vec_layout_strings; + std::vector m_vec_key_strings; + std::vector 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::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 &vec_file) { + reset(); + return parsing_layout_table(vec_file); +} + +int +LayoutParserImpl::parsing_layout_table(const vector &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(key), -1); + xmlFree(key); + add_upper_string(upper); + upper_created = TRUE; + key = reinterpret_cast(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(key), -1); + xmlFree(key); + add_upper_string(upper); + upper_created = TRUE; + key = reinterpret_cast(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(key), -1); + xmlFree(key); + add_upper_string(upper); + upper_created = TRUE; + key = reinterpret_cast(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 &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 &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 index 0000000..7d067aa --- /dev/null +++ b/scl/layout_parser.h @@ -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 + +class LayoutParserImpl; + +class LayoutParser { + LayoutParserImpl *m_impl; + public: + ~LayoutParser(); + static LayoutParser *get_instance(); + int init(const char *dir, + const std::vector &vec_layout_file_name); + int reload(const char *dir, + const std::vector &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 index 0000000..4addf8d --- /dev/null +++ b/scl/layout_parser_helper.cpp @@ -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 +#include +#include +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 index 0000000..e928af3 --- /dev/null +++ b/scl/layout_parser_helper.h @@ -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 + +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 index 0000000..2000893 --- /dev/null +++ b/scl/magnifier_configure_bin_parser.cpp @@ -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 +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(record_width.style); + //width + cur->width = m_storage.get(record_width.width); + //height + cur->height = m_storage.get(record_width.height); + //label_area_record.left + cur->label_area_rect.left = m_storage.get(record_width.label_area_rect); + //label_area_rect.right + cur->label_area_rect.right = m_storage.get(record_width.label_area_rect); + + //label_area_record.top + cur->label_area_rect.top = m_storage.get(record_width.label_area_rect); + //label_area_rect.bottom + cur->label_area_rect.bottom = m_storage.get(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(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(record_width.padding_x); + //padding_y + cur->padding_y = m_storage.get(record_width.padding_y); + //show_shift_label + cur->show_shift_label = m_storage.get(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 index 0000000..db14108 --- /dev/null +++ b/scl/magnifier_configure_bin_parser.h @@ -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 index 0000000..7397086 --- /dev/null +++ b/scl/magnifier_configure_parser.cpp @@ -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 +#include + +#include "magnifier_configure_parser.h" +#include +#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 index 0000000..df00068 --- /dev/null +++ b/scl/magnifier_configure_parser.h @@ -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 index 0000000..fd712bc --- /dev/null +++ b/scl/main_entry_parser.cpp @@ -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 +#include +#include + +#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 index 0000000..80c11f5 --- /dev/null +++ b/scl/main_entry_parser.h @@ -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 + +#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 index 0000000..b5318af --- /dev/null +++ b/scl/metadata.h @@ -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 +#include +#include +#include +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 vField; +}; + +class MetaData{ + public: + MetaData():m_version(NULL) {} + const char* m_version; + std::vector m_vec_metadata_record; +}; + +#endif diff --git a/scl/metadata_bin_parser.cpp b/scl/metadata_bin_parser.cpp new file mode 100644 index 0000000..a1117f2 --- /dev/null +++ b/scl/metadata_bin_parser.cpp @@ -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(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(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(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 index 0000000..219c34e --- /dev/null +++ b/scl/metadata_bin_parser.h @@ -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 index 0000000..39c5e0a --- /dev/null +++ b/scl/metadata_provider.h @@ -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 + +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::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 index 0000000..ad97d58 --- /dev/null +++ b/scl/modifier_decoration_bin_parser.cpp @@ -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 +#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(4); + for (int i = 0; i < size; ++i) { + cur->valid = (sclboolean)true; + m_storage.get(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 index 0000000..318c169 --- /dev/null +++ b/scl/modifier_decoration_bin_parser.h @@ -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 +#include "sclres_type.h" +#include "iparserinfo_provider.h" +#include +#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 index 0000000..7710e95 --- /dev/null +++ b/scl/modifier_decoration_parser.cpp @@ -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 +#include + +#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 index 0000000..c9d9417 --- /dev/null +++ b/scl/modifier_decoration_parser.h @@ -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 index 0000000..530ce13 --- /dev/null +++ b/scl/nine_patch_file_list_bin_parser.cpp @@ -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 +#include +#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(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(record_width.left); + cur->right = m_storage.get(record_width.right); + cur->top = m_storage.get(record_width.top); + cur->bottom = m_storage.get(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 index 0000000..433ab26 --- /dev/null +++ b/scl/nine_patch_file_list_bin_parser.h @@ -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 index 0000000..f12a9b2 --- /dev/null +++ b/scl/nine_patch_file_list_parser.cpp @@ -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 +#include +#include + +#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 index 0000000..b99c625 --- /dev/null +++ b/scl/nine_patch_file_list_parser.h @@ -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 index 0000000..bd01ec5 --- /dev/null +++ b/scl/parserinfo_provider.h @@ -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 index 0000000..5b7a133 --- /dev/null +++ b/scl/sclactionstate.cpp @@ -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 +#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 index 0000000..bb19635 --- /dev/null +++ b/scl/sclactionstate.h @@ -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-efl.cpp b/scl/sclanimator-efl.cpp new file mode 100644 index 0000000..e969c85 --- /dev/null +++ b/scl/sclanimator-efl.cpp @@ -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-efl.h" +#include "scldebug.h" + +#include +#include + +#include "sclutils.h" +#include "sclwindows.h" + +using namespace scl; + +/** + * Constructor + */ +CSCLAnimatorImplEfl::CSCLAnimatorImplEfl() +{ + SCL_DEBUG(); + + m_highlight_ui_object = NULL; + m_highlight_ui_object_alternate = NULL; +} + +/** + * De-constructor + */ +CSCLAnimatorImplEfl::~CSCLAnimatorImplEfl() +{ + SCL_DEBUG(); +} + +void CSCLAnimatorImplEfl::init() +{ +} + +void CSCLAnimatorImplEfl::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 +CSCLAnimatorImplEfl::check_animation_supported() +{ + /* EFL Backend finished implementing animation support */ + return TRUE; +} + +void +CSCLAnimatorImplEfl::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(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(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-efl.h b/scl/sclanimator-efl.h new file mode 100644 index 0000000..1325c83 --- /dev/null +++ b/scl/sclanimator-efl.h @@ -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_EFL_H__ +#define __SCL_ANIMATOR_EFL_H__ + +#include + +namespace scl +{ +class CSCLAnimatorImplEfl : public CSCLAnimatorImpl +{ +public : + CSCLAnimatorImplEfl(); + ~CSCLAnimatorImplEfl(); + + 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_EFL_H__ diff --git a/scl/sclanimator.cpp b/scl/sclanimator.cpp new file mode 100644 index 0000000..6bb04ce --- /dev/null +++ b/scl/sclanimator.cpp @@ -0,0 +1,368 @@ +/* + * 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 __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 __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::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::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::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::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::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::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::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 index 0000000..3369770 --- /dev/null +++ b/scl/sclanimator.h @@ -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 + +#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 m_animators; +}; + + +} /* End of scl namespace */ + +#ifdef __cplusplus +//SCL_END_DECLS +#endif + +#endif //__SCL_ANIMATOR_H__ diff --git a/scl/sclconfig.h b/scl/sclconfig.h new file mode 100644 index 0000000..2b48208 --- /dev/null +++ b/scl/sclconfig.h @@ -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 index 0000000..aaf2345 --- /dev/null +++ b/scl/sclcontext.cpp @@ -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 +#include + +#include "sclcontext.h" +#include "scldebug.h" +#include "sclwindows.h" +#include "sclutils.h" +#include "sclresourcecache.h" +#include "sclres.h" +#include + +//#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::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::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::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::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::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 index 0000000..9f70bbd --- /dev/null +++ b/scl/sclcontext.h @@ -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 +#include "scltypes.h" +#include "sclconfig.h" +#include "sclstructs.h" +#include "scleventcallback.h" +#include +#include +#include + +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 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 m_multi_touch_context; + std::list 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 index 0000000..a6101b4 --- /dev/null +++ b/scl/sclcontroller.cpp @@ -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 +#include +#include +#include + +#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 + +//#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 +#include +#include +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 +#include + 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 g_ImageCache; +extern std::vector 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 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 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 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 index 0000000..0a97612 --- /dev/null +++ b/scl/sclcontroller.h @@ -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 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 index 0000000..3f947f6 --- /dev/null +++ b/scl/scldebug.cpp @@ -0,0 +1,86 @@ +/* + * 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 +#include + + +#ifdef SCL_DEBUG_ON + +/* Measure elapsed time */ +static float +_SCL_DEBUG_ELAPSED_TIME(const char* str, struct timeval t0, struct timeval t1); + +/* Measure elapsed 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(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" mc_normal " (%lu~%lu) \n", str, etime, (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 index 0000000..e32e2f0 --- /dev/null +++ b/scl/scldebug.h @@ -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 +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#if 0 +#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 index 0000000..f5202af --- /dev/null +++ b/scl/scleffect.cpp @@ -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 index 0000000..f5202af --- /dev/null +++ b/scl/scleffect.h @@ -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 index 0000000..e046e69 --- /dev/null +++ b/scl/sclerroradjustment.cpp @@ -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 +#include + +#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 index 0000000..343db68 --- /dev/null +++ b/scl/sclerroradjustment.h @@ -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 index 0000000..234d4e0 --- /dev/null +++ b/scl/scleventcallback.h @@ -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 index 0000000..0f280c7 --- /dev/null +++ b/scl/scleventhandler.cpp @@ -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::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(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 index 0000000..6823279 --- /dev/null +++ b/scl/scleventhandler.h @@ -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 m_input_mode_event_callbacks; +}; + +} + +//SCL_END_DECLS + +#endif //__SCL_EVENT_HANDLER_H__ diff --git a/scl/sclevents-efl.cpp b/scl/sclevents-efl.cpp new file mode 100644 index 0000000..4492bc8 --- /dev/null +++ b/scl/sclevents-efl.cpp @@ -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-efl.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 +#include +#include +#ifdef WAYLAND +#define EFL_BETA_API_SUPPORT +#include +#else +#include +#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 + */ +CSCLEventsImplEfl::CSCLEventsImplEfl() +{ + 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 + */ +CSCLEventsImplEfl::~CSCLEventsImplEfl() +{ + SCL_DEBUG(); + + fini(); +} + +void CSCLEventsImplEfl::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 CSCLEventsImplEfl::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(windows->get_base_window())); + wl_magnifier_window = (Ecore_Wl2_Window*)(elm_win_wl_window_get(static_cast(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(windows->get_base_window())) == ev->window) { + is_scl_window = TRUE; + } else if (elm_win_xwindow_get(static_cast(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(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(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(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(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(windows->get_base_window())); + Ecore_Wl2_Window *wl_magnifier_window = + (Ecore_Wl2_Window*)(elm_win_wl_window_get(static_cast(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; +} + +/** + * Registers 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 +CSCLEventsImplEfl::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(reinterpret_cast(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 +CSCLEventsImplEfl::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 +CSCLEventsImplEfl::destroy_timer(const scl32 id) +{ + SCL_DEBUG(); + //for ( std::map::iterator idx = idMap.begin(); idx != idMap.end(); ++idx) { + std::map::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 +CSCLEventsImplEfl::destroy_all_timer() +{ + SCL_DEBUG(); + for ( std::map::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 +CSCLEventsImplEfl::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(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(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(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(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(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(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-efl.h b/scl/sclevents-efl.h new file mode 100644 index 0000000..4bd7a2d --- /dev/null +++ b/scl/sclevents-efl.h @@ -0,0 +1,59 @@ +/* + * 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 +#include +#include + + +#ifndef __SCL_EVENTS_EFL_H__ +#define __SCL_EVENTS_EFL_H__ + +namespace scl +{ +class CSCLEventsImplEfl : public CSCLEventsImpl +{ +public : + CSCLEventsImplEfl(); + ~CSCLEventsImplEfl(); + + 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 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; + +#ifndef WAYLAND + Ecore_Event_Handler *m_xclient_msg_handler; +#endif +}; +} /* End of scl namespace */ +#endif diff --git a/scl/sclevents.cpp b/scl/sclevents.cpp new file mode 100644 index 0000000..2183f2b --- /dev/null +++ b/scl/sclevents.cpp @@ -0,0 +1,230 @@ +/* + * 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" +#else +#include "sclevents-gtk.h" +#endif +#include "scldebug.h" +#include "sclwindows.h" + +#include "sclcontroller.h" +#include "sclresourcecache.h" +#include "sclkeyfocushandler.h" +#include + +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; +#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 index 0000000..487a66c --- /dev/null +++ b/scl/sclevents.h @@ -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 +#include +#include + +#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 index 0000000..2829999 --- /dev/null +++ b/scl/sclfeedback.cpp @@ -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 +#include + +#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 index 0000000..426c870 --- /dev/null +++ b/scl/sclfeedback.h @@ -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 index 0000000..218f63a --- /dev/null +++ b/scl/sclfontproxy.cpp @@ -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 index 0000000..ecaeb96 --- /dev/null +++ b/scl/sclfontproxy.h @@ -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-efl.cpp b/scl/sclgraphics-efl.cpp new file mode 100644 index 0000000..da54147 --- /dev/null +++ b/scl/sclgraphics-efl.cpp @@ -0,0 +1,1076 @@ +/* + * 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-efl.h" +#include "sclimageproxy.h" +#include "sclfontproxy.h" +#include "scldebug.h" +#include "sclwindows.h" +#include "sclresourcecache.h" +#include "sclwindows-efl.h" +#include "sclutils.h" + +#include +#include +#include +//#include +#include +#include + +//#define EXTRACT_PARTIMAGE + +#ifdef TEST_NEWBACKEND +std::vector g_ImageCache; +std::vector 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 _nine_patch_map; + +/** + * Constructor + */ +CSCLGraphicsImplEfl::CSCLGraphicsImplEfl() +{ + SCL_DEBUG(); + /* Initializes all window resources */ + m_highlight_ui_object = NULL; +} + +/** + * De-constructor + */ +CSCLGraphicsImplEfl::~CSCLGraphicsImplEfl() +{ + SCL_DEBUG(); + + fini(); +} + +void CSCLGraphicsImplEfl::init() +{ + m_highlight_ui_object = NULL; +} + +void CSCLGraphicsImplEfl::fini() +{ + if (m_highlight_ui_object) { + evas_object_del(m_highlight_ui_object); + m_highlight_ui_object = 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; +} + +/** + * 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(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; +} + +/** + * Register drawing as atspi object + */ +void CSCLGraphicsImplEfl::register_atspi_object(sclwindow window, scldrawing drawing, const sclchar* name) +{ + SCL_DEBUG(); + + Evas_Object *window_object = get_evas_window_object(window); + Evas_Object *drawing_object = static_cast(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); +} + +extern sclint magnifierx, magnifiery; +scldrawing +CSCLGraphicsImplEfl::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); + + 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::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(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::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(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 +CSCLGraphicsImplEfl::load_image(const sclchar *image_path) +{ + SCL_DEBUG(); + return NULL; +} + +void +CSCLGraphicsImplEfl::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 +CSCLGraphicsImplEfl::begin_paint(const sclwindow window, const sclboolean force_draw /* = FALSE */) +{ + SCL_DEBUG(); + + scldrawctx drawctx = reinterpret_cast(window); + + return drawctx; +} + +/** + * Notices that drawing tasks have done. + */ +void +CSCLGraphicsImplEfl::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); +} + +sclfont +CSCLGraphicsImplEfl::create_font(const SclFontInfo& info) +{ + return NULL; +} + +void +CSCLGraphicsImplEfl::destroy_font(sclfont font) +{ +} + +/** + * Draws the given text on cairo-surface + */ +scldrawing +CSCLGraphicsImplEfl::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; + + 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::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(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); + 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; + } + + 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(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 + } + } + return NULL; +} + +/** + * Draws a rectangle on cairo-surface + */ +scldrawing +CSCLGraphicsImplEfl::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(); + + 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(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(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; +} + +SclSize +CSCLGraphicsImplEfl::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 +CSCLGraphicsImplEfl::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; +} diff --git a/scl/sclgraphics-efl.cpp.orig b/scl/sclgraphics-efl.cpp.orig new file mode 100644 index 0000000..e202043 --- /dev/null +++ b/scl/sclgraphics-efl.cpp.orig @@ -0,0 +1,1080 @@ +/* + * 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-efl.h" +#include "sclimageproxy.h" +#include "sclfontproxy.h" +#include "scldebug.h" +#include "sclwindows.h" +#include "sclresourcecache.h" +#include "sclwindows-efl.h" +#include "sclutils.h" + +#include +#include +#include +//#include +#include +#include + +//#define EXTRACT_PARTIMAGE + +#ifdef TEST_NEWBACKEND +std::vector g_ImageCache; +std::vector 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 _nine_patch_map; + +/** + * Constructor + */ +CSCLGraphicsImplEfl::CSCLGraphicsImplEfl() +{ + SCL_DEBUG(); + /* Initializes all window resources */ + m_highlight_ui_object = NULL; +} + +/** + * De-constructor + */ +CSCLGraphicsImplEfl::~CSCLGraphicsImplEfl() +{ + SCL_DEBUG(); + + fini(); +} + +void CSCLGraphicsImplEfl::init() +{ + m_highlight_ui_object = NULL; +} + +void CSCLGraphicsImplEfl::fini() +{ + if (m_highlight_ui_object) { + evas_object_del(m_highlight_ui_object); + m_highlight_ui_object = 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; +} + +/** + * 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(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; +} + +/** + * Register drawing as atspi object + */ +void CSCLGraphicsImplEfl::register_atspi_object(sclwindow window, scldrawing drawing, const sclchar* name) +{ + SCL_DEBUG(); + + Evas_Object *window_object = get_evas_window_object(window); + Evas_Object *drawing_object = static_cast(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); +} + +extern sclint magnifierx, magnifiery; +scldrawing +CSCLGraphicsImplEfl::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); + + LOGD("path(%s), x(%d), y(%d), w(%d), h(%d)", image_path, dest_x, dest_y, dest_width, dest_height); + + 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::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(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::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(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 +CSCLGraphicsImplEfl::load_image(const sclchar *image_path) +{ + SCL_DEBUG(); + return NULL; +} + +void +CSCLGraphicsImplEfl::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 +CSCLGraphicsImplEfl::begin_paint(const sclwindow window, const sclboolean force_draw /* = FALSE */) +{ + SCL_DEBUG(); + + scldrawctx drawctx = reinterpret_cast(window); + + return drawctx; +} + +/** + * Notices that drawing tasks have done. + */ +void +CSCLGraphicsImplEfl::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); +} + +sclfont +CSCLGraphicsImplEfl::create_font(const SclFontInfo& info) +{ + return NULL; +} + +void +CSCLGraphicsImplEfl::destroy_font(sclfont font) +{ +} + +/** + * Draws the given text on cairo-surface + */ +scldrawing +CSCLGraphicsImplEfl::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 (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::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(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); + 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; + } + + 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(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 + } + } + return NULL; +} + +/** + * Draws a rectangle on cairo-surface + */ +scldrawing +CSCLGraphicsImplEfl::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(); + + 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(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(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; +} + +SclSize +CSCLGraphicsImplEfl::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 +CSCLGraphicsImplEfl::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; +} diff --git a/scl/sclgraphics-efl.h b/scl/sclgraphics-efl.h new file mode 100644 index 0000000..8725a08 --- /dev/null +++ b/scl/sclgraphics-efl.h @@ -0,0 +1,116 @@ +/* + * 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_EFL_H__ +#define __SCL_GRAPHICS_EFL_H__ + +//#define DO_NOT_MOVE_MAGNIFIER_WINDOW +//#define FULL_SCREEN_TEST + +#include + +/* Still an experimental feature.. Will be refined after being stabilized */ +//#define TEST_NEWBACKEND +#ifdef TEST_NEWBACKEND +using namespace scl; + +#include +#include + +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 CSCLGraphicsImplEfl : public CSCLGraphicsImpl +{ +public : + CSCLGraphicsImplEfl(); + ~CSCLGraphicsImplEfl(); + + 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); + +private: + Evas_Object *m_highlight_ui_object; +}; +} /* End of scl namespace */ +#endif diff --git a/scl/sclgraphics.cpp b/scl/sclgraphics.cpp new file mode 100644 index 0000000..36856be --- /dev/null +++ b/scl/sclgraphics.cpp @@ -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. + * + */ + +#define __GTK__ 1 + +#include "sclgraphics.h" +#ifdef __WIN32__ +#include "sclgraphics-win32.h" +#elif defined(__EFL__) +#include "sclgraphics-efl.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 __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 index 0000000..1099dc7 --- /dev/null +++ b/scl/sclgraphics.h @@ -0,0 +1,186 @@ +/* + * 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 +#include +#include + +#include "scltypes.h" +#include "sclconfig.h" +#include "sclstructs.h" + +#ifndef __SCL_GRAPHICS_H__ +#define __SCL_GRAPHICS_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 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; + +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}; + +/** + * @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; +}; + +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); + } + +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/sclgwes.cpp b/scl/sclgwes.cpp new file mode 100644 index 0000000..00b352c --- /dev/null +++ b/scl/sclgwes.cpp @@ -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 index 0000000..6df9ceb --- /dev/null +++ b/scl/sclgwes.h @@ -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 +#include +#include + +#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 index 0000000..e9fcbcc --- /dev/null +++ b/scl/sclheaders.h @@ -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 index 0000000..a2ec3e5 --- /dev/null +++ b/scl/sclimageproxy.cpp @@ -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 index 0000000..3050b4d --- /dev/null +++ b/scl/sclimageproxy.h @@ -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 index 0000000..f5202af --- /dev/null +++ b/scl/sclintl.h @@ -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 index 0000000..ec7a182 --- /dev/null +++ b/scl/sclkeydefines.h @@ -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 index 0000000..9c892d7 --- /dev/null +++ b/scl/sclkeyfocushandler.cpp @@ -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 +#include +#include +#ifndef WAYLAND +#include +#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(window), !acceptable); +} + + +#endif + + diff --git a/scl/sclkeyfocushandler.h b/scl/sclkeyfocushandler.h new file mode 100644 index 0000000..9f0e81c --- /dev/null +++ b/scl/sclkeyfocushandler.h @@ -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 index 0000000..c6abfd0 --- /dev/null +++ b/scl/sclres.cpp @@ -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 index 0000000..dbbbf92 --- /dev/null +++ b/scl/sclres.h @@ -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 + +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 index 0000000..b0a3769 --- /dev/null +++ b/scl/sclres_manager.cpp @@ -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 +#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 index 0000000..4c4cb32 --- /dev/null +++ b/scl/sclres_manager.h @@ -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 index 0000000..506dcf0 --- /dev/null +++ b/scl/sclres_type.h @@ -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 index 0000000..21b49ea --- /dev/null +++ b/scl/sclresourcecache.cpp @@ -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 +#include +#include "sclresourcekeys.h" +#include "sclresourcecache.h" +#include "scldebug.h" +#include "sclcontext.h" + +//#include "sclresource.h" +#include "scluibuilder.h" +#include "sclres_manager.h" +#include +#include + +//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(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(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(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(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(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::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 index 0000000..df1af1a --- /dev/null +++ b/scl/sclresourcecache.h @@ -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 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 index 0000000..7058f09 --- /dev/null +++ b/scl/sclstructs.h @@ -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 +#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 index 0000000..c243563 --- /dev/null +++ b/scl/sclui.cpp @@ -0,0 +1,710 @@ +/* + * 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); + } +} + +/** + * 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 index 0000000..fdd00eb --- /dev/null +++ b/scl/sclui.h @@ -0,0 +1,461 @@ +/* + * 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" + +//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); +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 index 0000000..c104ca3 --- /dev/null +++ b/scl/scluibuilder.cpp @@ -0,0 +1,1305 @@ +/* + * 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 +#include +#include + +#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 +#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; +} diff --git a/scl/scluibuilder.h b/scl/scluibuilder.h new file mode 100644 index 0000000..4af8942 --- /dev/null +++ b/scl/scluibuilder.h @@ -0,0 +1,80 @@ +/* + * 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 +#include +#include "sclgwes.h" +#include "sclutils.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); + +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 index 0000000..7bb0715 --- /dev/null +++ b/scl/scluiimpl.cpp @@ -0,0 +1,1211 @@ +/* + * 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 +#include + +#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); + } + } +} + +/** + * 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 index 0000000..fd3b914 --- /dev/null +++ b/scl/scluiimpl.h @@ -0,0 +1,141 @@ +/* + * 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" + +//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); + + 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 index 0000000..e93690c --- /dev/null +++ b/scl/sclutils-linux.cpp @@ -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 "sclutils.h" +#include "scldebug.h" +#include "sclcontext.h" + +#include + +#include +#ifdef WAYLAND +#define EFL_BETA_API_SUPPORT +#include +#else +#include +#endif +#include +#include +#include + +#include + +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, ¤t_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(); + 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(); +} + +/* 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, ¤t_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 index 0000000..fb8fefb --- /dev/null +++ b/scl/sclutils.cpp @@ -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 +#include +#include +#include +#include + +#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(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(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 index 0000000..2f7aa1c --- /dev/null +++ b/scl/sclutils.h @@ -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 +#include +#include + +#include + +#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 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 index 0000000..a879b22 --- /dev/null +++ b/scl/sclversion.h @@ -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/sclwindows-efl.cpp b/scl/sclwindows-efl.cpp new file mode 100644 index 0000000..9871aa5 --- /dev/null +++ b/scl/sclwindows-efl.cpp @@ -0,0 +1,1224 @@ +/* + * 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-efl.h" +#include "scldebug.h" +#include "sclcontroller.h" +#include "sclcontext.h" +#include "sclresourcecache.h" +#include "scluibuilder.h" +#include "sclwindows.h" +#include "sclres_manager.h" + +#include +#include +#include +#ifdef WAYLAND +#define EFL_BETA_API_SUPPORT +#include +#else +#include +#include +#include +#include +#endif +#include +#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 +}; + +void release_all(Evas_Object *win); + +#include "sclgraphics-efl.h" +#ifdef TEST_NEWBACKEND +#include +#include +#include +extern std::vector g_ImageCache; +extern std::vector 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 + */ +CSCLWindowsImplEfl::CSCLWindowsImplEfl() +{ + SCL_DEBUG(); +#ifndef WAYLAND + /* Initializes all window resources */ + ATOM_WM_CLASS = ecore_x_atom_get("WM_CLASS"); +#endif +} + +/** + * De-constructor + */ +CSCLWindowsImplEfl::~CSCLWindowsImplEfl() +{ + 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 CSCLWindowsImplEfl::init() +{ +} + +void CSCLWindowsImplEfl::fini() +{ +} + +/** + * Create a content window and binds it into given parent window as a child + */ +sclwindow +CSCLWindowsImplEfl::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(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(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(parent), rots, 4); + + CSCLUtils *utils = CSCLUtils::get_instance(); + if (utils) { + utils->log("WinEfl_createbasewin %p, %d %d\n", + parent, width, height); + } + return ret; +} + +/** + * Creates a window + */ +sclwindow +CSCLWindowsImplEfl::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(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(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(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("WinEfl_createwin %p, %d %d\n", + win, width, height); + } + return win; +} + + +/** +* Creates a window +*/ +sclwindow +CSCLWindowsImplEfl::create_magnifier_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(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(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(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()); + + if (utils) { + utils->log("WinEfl_createmagwin %p, %d %d\n", + win, width, height); + } + + return win; +} + +/** + * Creates the dim window + */ +sclwindow +CSCLWindowsImplEfl::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(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(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(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("WinEfl_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 occur some crash. It needs to check X11 + */ +void +CSCLWindowsImplEfl::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(window)), + elm_win_xwindow_get(static_cast(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 +CSCLWindowsImplEfl::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("WinEfl_destroywin %p %p (basewin %p mag %p)\n", window, + (!(window_context->is_virtual)) ? elm_win_xwindow_get(static_cast(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("WinEfl_destroywin %p (basewin %p mag %p)\n", window, + windows->get_base_window(), windows->get_magnifier_window()); + } + } + + return TRUE; +} + +/** + * Shows the given window + */ +void +CSCLWindowsImplEfl::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(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(window)), app_window); +#endif + elm_win_raise((Evas_Object *)window); + } + } + + if (utils) { + utils->log("WinEfl_showwin %p (basewin %p mag %p)\n", + window, + windows->get_base_window(), windows->get_magnifier_window()); + } + } +} + +/** + * Hides the given window + */ +void +CSCLWindowsImplEfl::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("WinEfl_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 +CSCLWindowsImplEfl::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 == windonw_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("WinEfl_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 +CSCLWindowsImplEfl::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("WinEfl_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 +CSCLWindowsImplEfl::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("WinEfl_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 +CSCLWindowsImplEfl::update_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height) +{ + SCL_DEBUG(); + + 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 +CSCLWindowsImplEfl::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(window), &x, &y); + evas_object_geometry_get(static_cast(window), NULL, NULL, &width, &height); + + utils->log("WinEfl_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 +CSCLWindowsImplEfl::set_window_rotation(const sclwindow window, SCLRotation rotation) +{ + SCL_DEBUG(); + +#ifndef WAYLAND + CSCLWindows *windows = CSCLWindows::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 (window_context) { + if (window_context->is_virtual) { + return; + } + } + + XSizeHints hint; + long int mask; + Window win; + Display *dpy; + + dpy = (Display*)ecore_x_display_get(); + win = elm_win_xwindow_get((Evas_Object*)window); + + if (!XGetWMNormalHints(dpy, win, &hint, &mask)) + memset(&hint, 0, sizeof(XSizeHints)); + + hint.flags |= USPosition; + + XSetWMNormalHints(dpy, win, &hint); + /*if (window_context) { + windows->resize_window(window_context->window, window_context->width, winctx->height); + }*/ + } +#endif +} + +/** + * Shows a message box + */ +void +CSCLWindowsImplEfl::show_message_box(const sclwindow parent, scl8 msgType, sclchar* title, sclchar* msg) +{ + SCL_DEBUG(); +} + +void +CSCLWindowsImplEfl::set_keep_above(const sclwindow window, sclboolean keepabove) +{ + SCL_DEBUG(); +} + +void release_all(Evas_Object *win) +{ + SCL_DEBUG(); + //if (window == windows->get_magnifier_window()) { + //evas_object_move(win, -10000, -10000); + //Evas *evas = evas_object_evas_get(win); + //evas_render_idle_flush(evas); + /*} else { + evas_object_hide(win); + }*/ + //LOGD("HIDE_WINDOW : %p\n", window); + + CSCLWindows *windows = CSCLWindows::get_instance(); + if (!windows) return; + + SclWindowContext *window_context = windows->get_window_context(win); + if (window_context && win) { + 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*)win); + //evas_render_idle_flush(evas); + //} + /*evas_image_cache_flush(evas_object_evas_get((Evas_Object*)win)); + elm_cache_all_flush(); + malloc_trim(0);*/ +} + +void CSCLWindowsImplEfl::set_window_accepts_focus(const sclwindow window, sclboolean acceptable) +{ + elm_win_prop_focus_skip_set(static_cast(window), !acceptable); +} diff --git a/scl/sclwindows-efl.h b/scl/sclwindows-efl.h new file mode 100644 index 0000000..3a22325 --- /dev/null +++ b/scl/sclwindows-efl.h @@ -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. + * + */ + +#include "sclwindows.h" +#include +#include + +#ifndef __SCL_WINDOWS_EFL_H__ +#define __SCL_WINDOWS_EFL_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 CSCLWindowsImplEfl : public CSCLWindowsImpl +{ +public : + CSCLWindowsImplEfl(); + ~CSCLWindowsImplEfl(); + + 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); +}; +} /* End of scl namespace */ +#endif diff --git a/scl/sclwindows.cpp b/scl/sclwindows.cpp new file mode 100644 index 0000000..45730c6 --- /dev/null +++ b/scl/sclwindows.cpp @@ -0,0 +1,1131 @@ +/* + * 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" +#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 + +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; +#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(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_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 + 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; +} diff --git a/scl/sclwindows.h b/scl/sclwindows.h new file mode 100644 index 0000000..15d54eb --- /dev/null +++ b/scl/sclwindows.h @@ -0,0 +1,185 @@ +/* + * 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 +#include +#include + +#include "scltypes.h" +#include "sclconfig.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; +}; + +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(); + +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 index 0000000..a912cdb --- /dev/null +++ b/scl/string_bin_parser.cpp @@ -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 +#include +#include +#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(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 index 0000000..64c08d9 --- /dev/null +++ b/scl/string_bin_parser.h @@ -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 +#include +#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& get_string_depository()const { + return m_vec_str_depository; + } + private: + void parse(); + std::vector m_vec_str_depository; + FileStorage m_storage; +}; +#endif diff --git a/scl/string_collector.h b/scl/string_collector.h new file mode 100644 index 0000000..5473117 --- /dev/null +++ b/scl/string_collector.h @@ -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 +#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::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 m_vec_string_collection; +}; +#endif diff --git a/scl/string_provider.h b/scl/string_provider.h new file mode 100644 index 0000000..a29b7b7 --- /dev/null +++ b/scl/string_provider.h @@ -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 +#include +#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& 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 index 0000000..5ec17c0 --- /dev/null +++ b/scl/xml_parser_utils.cpp @@ -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 +#include +#include + +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 index 0000000..b72faf2 --- /dev/null +++ b/scl/xml_parser_utils.h @@ -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 +#include +#include +#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 +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 index 0000000..a3a917d --- /dev/null +++ b/scl/xmlresource.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#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 &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::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 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 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 index 0000000..7552999 --- /dev/null +++ b/scl/xmlresource.h @@ -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 index 0000000..d5dbcd3 --- /dev/null +++ b/xml2binary/CMakeLists.txt @@ -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 index 0000000..4319b89 --- /dev/null +++ b/xml2binary/data/auto_codes.py @@ -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 \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 \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 index 0000000..ad81a7c --- /dev/null +++ b/xml2binary/data/metadata.xml @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml2binary/encode_autopopup_configure.cpp b/xml2binary/encode_autopopup_configure.cpp new file mode 100644 index 0000000..c7ed81c --- /dev/null +++ b/xml2binary/encode_autopopup_configure.cpp @@ -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(color.r, width); + storage.put(color.g, width); + storage.put(color.b, width); + storage.put(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(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(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(cur->sw_button_style, record_width.sw_button_style); + + //button_width + storage.put(cur->button_width, record_width.button_width); + + //button_height + storage.put(cur->button_height, record_width.button_height); + + //button_spacing + storage.put(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(cur->decoration_size, record_width.decoration_size); + + //max_column + storage.put(cur->max_column, record_width.max_column); + + //add_grab_left + storage.put(cur->add_grab_left, record_width.add_grab_left); + + //add_grab_right + storage.put(cur->add_grab_right, record_width.add_grab_right); + + //add_grab_top + storage.put(cur->add_grab_top, record_width.add_grab_top); + + //add_grab_bottom + storage.put(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(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 index 0000000..55c45da --- /dev/null +++ b/xml2binary/encode_default_configure.cpp @@ -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(color.r, width); + storage.put(color.g, width); + storage.put(color.b, width); + storage.put(color.a, width); +} +static void +encode_default_configure_record(ResourceStorage& storage, const PSclDefaultConfigure cur, const Default_configure_width& record_width) { + //display_mode + storage.put((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(cur->target_screen_width, record_width.target_screen_width); + + //target_screen_height + storage.put(cur->target_screen_height, record_width.target_screen_height); + + //auto_detect_landscape + storage.put(cur->auto_detect_landscape, record_width.auto_detect_landscape); + + //use_magnifier_window + storage.put(cur->use_magnifier_window, record_width.use_magnifier_window); + + //use_auto_popup + storage.put(cur->use_auto_popup, record_width.use_auto_popup); + + //use_zoom_window + storage.put(cur->use_zoom_window, record_width.use_zoom_window); + + //on_error_noti_send + storage.put(cur->on_error_noti_send, record_width.on_error_noti_send); + + //use_word_deletion + storage.put(cur->use_word_deletion, record_width.use_word_deletion); + + //sw_button_style + storage.put(cur->sw_button_style, record_width.sw_button_style); + + //touch_offset_level + for (int i = 0; i < DISPLAYMODE_MAX; ++i) { + storage.put((int)cur->touch_offset_level[i], record_width.touch_offset_level); + } + + //touch_offset + for (int i = 0; i < DISPLAYMODE_MAX; ++i) { + storage.put((int)cur->touch_offset[i].x, record_width.touch_offset); + storage.put((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(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(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 index 0000000..da43390 --- /dev/null +++ b/xml2binary/encode_input_mode_configure.cpp @@ -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 +#include +#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(cur->use_virtual_window, record_width.use_virtual_window); + //use_dim_window + storage.put(cur->use_dim_window, record_width.use_dim_window); + //timeout + storage.put(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(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(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 index 0000000..87566c6 --- /dev/null +++ b/xml2binary/encode_key_coordinate_frame.cpp @@ -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 +#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(cur->x, record_width.x); + + //y + storage.put(cur->y, record_width.y); + + //width + storage.put(cur->width, record_width.width); + + //height + storage.put(cur->height, record_width.height); + + //add_hit_left + storage.put(cur->add_hit_left, record_width.add_hit_left); + + //add_hit_right + storage.put(cur->add_hit_right, record_width.add_hit_right); + + //add_hit_top + storage.put(cur->add_hit_top, record_width.add_hit_top); + + //add_hit_bottom + storage.put(cur->add_hit_bottom, record_width.add_hit_bottom); + + //popup_relative_x + storage.put(cur->popup_relative_x, record_width.popup_relative_x); + + //popup_relative_y + storage.put(cur->popup_relative_y, record_width.popup_relative_y); + + //extract_offset_x + storage.put(cur->extract_offset_x, record_width.extract_offset_x); + + //extract_offset_y + storage.put(cur->extract_offset_y, record_width.extract_offset_y); + + storage.encode_string(cur->sub_layout, record_width.sub_layout); + + //magnifier_offset_x + storage.put(cur->magnifier_offset_x, record_width.magnifier_offset_x); + + //magnifier_offset_y + storage.put(cur->magnifier_offset_y, record_width.magnifier_offset_y); + + storage.encode_string(cur->custom_id, record_width.custom_id); + + //button_type + storage.put(cur->button_type, record_width.button_type); + + //key_type + storage.put(cur->key_type, record_width.key_type); + + //popup_type + storage.put(cur->popup_type, record_width.popup_type); + + storage.put(cur->use_magnifier, record_width.use_magnifier); + storage.put(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(cur->is_side_button, record_width.is_side_button); + + //label_count + storage.put(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(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(cur->key_event[i][j], record_width.key_event); + } + } + + storage.put(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(cur->long_key_event, record_width.long_key_event); + + storage.put(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(cur->autopopup_key_events[i][j], record_width.autopopup_key_events); + } + } + + storage.put(cur->dont_close_popup, record_width.dont_close_popup); + + //extra_option + storage.put(cur->extra_option, record_width.extra_option); + + //multitouch_type + storage.put(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(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(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(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(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 index 0000000..580905e --- /dev/null +++ b/xml2binary/encode_label_properties_frame.cpp @@ -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 +#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(color.r, width); + storage.put(color.g, width); + storage.put(color.b, width); + storage.put(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(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(cur->alignment, record_width.alignment); + + //padding_x + storage.put(cur->padding_x, record_width.padding_x); + + //padding_y + storage.put(cur->padding_y, record_width.padding_y); + + //inner_width + storage.put(cur->inner_width, record_width.inner_width); + + //inner_height + storage.put(cur->inner_height, record_width.inner_height); + + //shadow_distance + storage.put(cur->shadow_distance, record_width.shadow_distance); + + //shadow_direction + storage.put(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(size, _SIZE_WIDTH); + storage.put(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(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 index 0000000..e557947 --- /dev/null +++ b/xml2binary/encode_layout.cpp @@ -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 +#include +#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(color.r, width); + storage.put(color.g, width); + storage.put(color.b, width); + storage.put(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(cur->display_mode, record_width.display_mode); + + //style + storage.put(cur->style, record_width.style); + + //width + storage.put(cur->width, record_width.width); + + //height + storage.put(cur->height, record_width.height); + + //use_sw_button + storage.put(cur->use_sw_button, record_width.use_sw_button); + + //use_magnifier_window + storage.put(cur->use_magnifier_window, record_width.use_magnifier_window); + + //extract_background + storage.put(cur->extract_background, record_width.extract_background); + + //key_width + storage.put(cur->key_width, record_width.key_width); + + //key_height + storage.put(cur->key_height, record_width.key_height); + //key_spacing + storage.put(cur->key_spacing, record_width.key_spacing); + //row_spacing + storage.put(cur->row_spacing, record_width.row_spacing); + + //use_sw_background + storage.put(cur->use_sw_background, record_width.use_sw_background); + + _encode_color(storage, cur->bg_color, record_width.bg_color); + + //bg_line_width + storage.put(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(cur->add_grab_left, record_width.add_grab_left); + + //add_grab_right + storage.put(cur->add_grab_right, record_width.add_grab_right); + + //add_grab_top + storage.put(cur->add_grab_top, record_width.add_grab_top); + + //add_grab_bottom + storage.put(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(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(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(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 index 0000000..779346b --- /dev/null +++ b/xml2binary/encode_magnifier_configure.cpp @@ -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(cur->style, record_width.style); + //width + storage.put(cur->width, record_width.width); + //height + storage.put(cur->height, record_width.height); + //label_area_record.left + storage.put(cur->label_area_rect.left, record_width.label_area_rect); + //label_area_rect.right + storage.put(cur->label_area_rect.right, record_width.label_area_rect); + + //label_area_record.top + storage.put(cur->label_area_rect.top, record_width.label_area_rect); + //label_area_rect.bottom + storage.put(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(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(cur->padding_x, record_width.padding_x); + //padding_y + storage.put(cur->padding_y, record_width.padding_y); + //show_shift_label + storage.put(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(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 index 0000000..d0262e6 --- /dev/null +++ b/xml2binary/encode_metadata.cpp @@ -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 +#include +#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(field_num, FIELD_NUM_WIDTH); + + std::vector::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(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(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(block_size, 8, init_size); +} + diff --git a/xml2binary/encode_modifier_decoration.cpp b/xml2binary/encode_modifier_decoration.cpp new file mode 100644 index 0000000..4e42ea7 --- /dev/null +++ b/xml2binary/encode_modifier_decoration.cpp @@ -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 + +using namespace xmlresource; +static void +encode_modifier_decoration_record(ResourceStorage& storage, const PSclModifierDecoration cur, const Modifier_decoration_width& record_width) { + storage.put(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(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(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 index 0000000..fc747a4 --- /dev/null +++ b/xml2binary/encode_nine_patch.cpp @@ -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 +#include "xmlresource.h" +#include "imetadata_helper.h" +#include "resource_storage_impl.h" +#include "put_record.h" +#include "_auto_metadata.h" +#include + +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(cur->left, record_width.left); + //right + storage.put(cur->right, record_width.right); + //top + storage.put(cur->top, record_width.top); + //bottom + storage.put(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(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(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 index 0000000..c766a95 --- /dev/null +++ b/xml2binary/include/_auto_metadata.h @@ -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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 index 0000000..3414dd9 --- /dev/null +++ b/xml2binary/include/encode_autopopup_configure.h @@ -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 index 0000000..6cf24ff --- /dev/null +++ b/xml2binary/include/encode_default_configure.h @@ -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 index 0000000..0575317 --- /dev/null +++ b/xml2binary/include/encode_input_mode_configure.h @@ -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 index 0000000..5f11ca0 --- /dev/null +++ b/xml2binary/include/encode_key_coordinate_frame.h @@ -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 index 0000000..a128526 --- /dev/null +++ b/xml2binary/include/encode_label_properties_frame.h @@ -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 index 0000000..5abff57 --- /dev/null +++ b/xml2binary/include/encode_layout.h @@ -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 index 0000000..d4e5730 --- /dev/null +++ b/xml2binary/include/encode_magnifier_configure.h @@ -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 index 0000000..592965d --- /dev/null +++ b/xml2binary/include/encode_metadata.h @@ -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 index 0000000..a6fd564 --- /dev/null +++ b/xml2binary/include/encode_modifier_decoration.h @@ -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 index 0000000..f0bfc38 --- /dev/null +++ b/xml2binary/include/encode_nine_patch.h @@ -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 index 0000000..d1aac65 --- /dev/null +++ b/xml2binary/include/imetadata_encoder.h @@ -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 index 0000000..698f98b --- /dev/null +++ b/xml2binary/include/imetadata_helper.h @@ -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 index 0000000..99bef9d --- /dev/null +++ b/xml2binary/include/imetadata_parser.h @@ -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 index 0000000..08711c3 --- /dev/null +++ b/xml2binary/include/istring_encoder.h @@ -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 index 0000000..ff24b3d --- /dev/null +++ b/xml2binary/include/metadata.h @@ -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 +#include +#include +#include +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 vField; +}; + +class MetaData{ + public: + char m_version[RECORD_NAME_WIDTH]; + std::vector m_vec_metadata_record; +}; + +#endif diff --git a/xml2binary/include/metadata_handler.h b/xml2binary/include/metadata_handler.h new file mode 100644 index 0000000..c2f9538 --- /dev/null +++ b/xml2binary/include/metadata_handler.h @@ -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 +#include +#include +#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 index 0000000..01c9b6e --- /dev/null +++ b/xml2binary/include/resource_storage.h @@ -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 +#include +#include +#include +#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 + 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 + 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 + 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 + 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 index 0000000..d4d10fc --- /dev/null +++ b/xml2binary/include/resource_storage_impl.h @@ -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 + +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 data) { + put_uint8(data); +} +template <> +inline void ResourceStorage:: +put_primitive_data(uint16 data) { + put_uint16(data); +} +template <> +inline void ResourceStorage:: +put_primitive_data(uint32 data) { + put_uint32(data); +} +template <> +inline void ResourceStorage:: +put_primitive_data(uint64 data) { + put_uint64(data); +} +template <> +inline void ResourceStorage:: +put_primitive_data(int8 data) { + put_int8(data); +} +template <> +inline void ResourceStorage:: +put_primitive_data(int16 data) { + put_int16(data); +} +template <> +inline void ResourceStorage:: +put_primitive_data(int32 data) { + put_int32(data); +} +template <> +inline void ResourceStorage:: +put_primitive_data(int64 data) { + put_int64(data); +} +template <> +inline void ResourceStorage:: +put_primitive_data(float32 data) { + put_float32(data); +} +template <> +inline void ResourceStorage:: +put_primitive_data(float64 data) { + put_float64(data); +} + +//put integer value to storage +//width is assigned by para "width" +template <> +inline int ResourceStorage:: +put(sint_t data, int width) { + switch (width) { + case 0: + /*Nothing to put*/ + break; + case 1: + put_primitive_data((int8)data); + break; + case 2: + put_primitive_data((int16)data); + break; + case 4: + put_primitive_data((int32)data); + break; + case 8: + put_primitive_data((int64)data); + break; + default: + return -1; + } + + return 0; +} +template <> +inline int ResourceStorage:: +put(uint_t data, int width) { + switch (width) { + case 0: + /*Nothing to put*/ + break; + case 1: + put_primitive_data((uint8)data); + break; + case 2: + put_primitive_data((uint16)data); + break; + case 4: + put_primitive_data((uint32)data); + break; + case 8: + put_primitive_data((uint64)data); + break; + default: + return -1; + } + + return 0; +} +template <> +inline int ResourceStorage:: +put(float_t data, int width) { + switch (width) { + case 0: + break; + case 4: + put_primitive_data((float32)data); + break; + case 8: + put_primitive_data((float64)data); + break; + default: + return -1; + } + return 0; +} +template<> +inline int ResourceStorage:: +random_put(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(data, width); + //reback to current_offset + m_size = current_offset; + + return ret; +} +template<> +inline int ResourceStorage:: +random_put(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(data, width); + //reback to current_offset + m_size = current_offset; + + return ret; +} +template <> +inline int ResourceStorage:: +random_put(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(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(id, width); +} + + +#endif diff --git a/xml2binary/include/string_encoder.h b/xml2binary/include/string_encoder.h new file mode 100644 index 0000000..9a7c0b7 --- /dev/null +++ b/xml2binary/include/string_encoder.h @@ -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 +#include +/* 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::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(m_vec_string.size(), MAX_NUM_WIDTH); + + /* record each string*/ + std::vector::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 m_vec_string; + std::string m_file; +}; +#endif diff --git a/xml2binary/metadata_handler.cpp b/xml2binary/metadata_handler.cpp new file mode 100644 index 0000000..f002323 --- /dev/null +++ b/xml2binary/metadata_handler.cpp @@ -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 index 0000000..c29eac9 --- /dev/null +++ b/xml2binary/xml2dat.cpp @@ -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 +#include +#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(size_table[i], _SIZE_WIDTH); + rs.put(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; +}