From aad53dd8e8c7315bbb7f709eb212f6dc04e11231 Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Mon, 14 Sep 2015 21:57:12 +0900 Subject: [PATCH 2/3] tizen 2.3.1 release --- CMakeLists.txt | 8 + LICENSE | 206 + packaging/libwidget_viewer.manifest | 5 + packaging/libwidget_viewer.spec | 151 + packaging/org.tizen.widget_viewer_sdk.manifest | 30 + widget_viewer/CMakeLists.txt | 103 + widget_viewer/LICENSE | 206 + widget_viewer/include/client.h | 24 + widget_viewer/include/conf.h | 48 + widget_viewer/include/debug.h | 28 + widget_viewer/include/desc_parser.h | 19 + widget_viewer/include/dlist.h | 43 + widget_viewer/include/fb.h | 35 + widget_viewer/include/file_service.h | 21 + widget_viewer/include/master_rpc.h | 24 + widget_viewer/include/util.h | 31 + widget_viewer/include/widget_viewer.h | 1643 ++++ widget_viewer/include/widget_viewer_internal.h | 278 + widget_viewer/src/client.c | 2359 ++++++ widget_viewer/src/conf.c | 82 + widget_viewer/src/desc_parser.c | 701 ++ widget_viewer/src/dlist.c | 189 + widget_viewer/src/fb.c | 682 ++ widget_viewer/src/fb_wayland.c | 639 ++ widget_viewer/src/file_service.c | 715 ++ widget_viewer/src/master_rpc.c | 319 + widget_viewer/src/util.c | 150 + widget_viewer/src/widget.c | 4228 ++++++++++ widget_viewer/src/widget_internal.c | 1061 +++ widget_viewer/widget_viewer.pc.in | 12 + widget_viewer_evas/CMakeLists.txt | 76 + widget_viewer_evas/LICENSE | 206 + widget_viewer_evas/doc/image/PD.png | Bin 0 -> 23224 bytes widget_viewer_evas/doc/image/download_folder.png | Bin 0 -> 34630 bytes widget_viewer_evas/doc/image/front.jpg | Bin 0 -> 61126 bytes widget_viewer_evas/doc/image/image_format.png | Bin 0 -> 82415 bytes widget_viewer_evas/doc/image/message.png | Bin 0 -> 28543 bytes widget_viewer_evas/doc/image/preload_folder.png | Bin 0 -> 39070 bytes widget_viewer_evas/doc/image/script_format.png | Bin 0 -> 82052 bytes widget_viewer_evas/doc/image/stock.png | Bin 0 -> 19879 bytes widget_viewer_evas/doc/image/text_format.png | Bin 0 -> 84551 bytes widget_viewer_evas/doc/image/twitter.png | Bin 0 -> 45791 bytes widget_viewer_evas/doc/image/weather.png | Bin 0 -> 58862 bytes widget_viewer_evas/doc/widget_viewer_evas_doc.h | 32 + widget_viewer_evas/include/util.h | 29 + widget_viewer_evas/include/widget_viewer_evas.h | 412 + .../include/widget_viewer_evas_internal.h | 276 + widget_viewer_evas/res/CMakeLists.txt | 13 + widget_viewer_evas/res/po/CMakeLists.txt | 84 + widget_viewer_evas/res/po/ar.po | 57 + widget_viewer_evas/res/po/az.po | 57 + widget_viewer_evas/res/po/bg.po | 57 + widget_viewer_evas/res/po/bn.po | 57 + widget_viewer_evas/res/po/ca.po | 57 + widget_viewer_evas/res/po/cs.po | 57 + widget_viewer_evas/res/po/da.po | 57 + widget_viewer_evas/res/po/de.po | 57 + widget_viewer_evas/res/po/el_GR.po | 57 + widget_viewer_evas/res/po/en.po | 57 + widget_viewer_evas/res/po/en_PH.po | 57 + widget_viewer_evas/res/po/en_US.po | 57 + widget_viewer_evas/res/po/es_ES.po | 57 + widget_viewer_evas/res/po/es_US.po | 57 + widget_viewer_evas/res/po/et.po | 57 + widget_viewer_evas/res/po/eu.po | 57 + widget_viewer_evas/res/po/fa.po | 57 + widget_viewer_evas/res/po/fi.po | 57 + widget_viewer_evas/res/po/fr.po | 57 + widget_viewer_evas/res/po/fr_CA.po | 57 + widget_viewer_evas/res/po/ga.po | 57 + widget_viewer_evas/res/po/gl.po | 57 + widget_viewer_evas/res/po/gu.po | 57 + widget_viewer_evas/res/po/he.po | 57 + widget_viewer_evas/res/po/hi.po | 57 + widget_viewer_evas/res/po/hr.po | 57 + widget_viewer_evas/res/po/hu.po | 57 + widget_viewer_evas/res/po/hy.po | 57 + widget_viewer_evas/res/po/is.po | 57 + widget_viewer_evas/res/po/it_IT.po | 57 + widget_viewer_evas/res/po/ja_JP.po | 57 + widget_viewer_evas/res/po/ka.po | 57 + widget_viewer_evas/res/po/kk.po | 57 + widget_viewer_evas/res/po/kn.po | 57 + widget_viewer_evas/res/po/ko_KR.po | 57 + widget_viewer_evas/res/po/lt.po | 57 + widget_viewer_evas/res/po/lv.po | 57 + widget_viewer_evas/res/po/mk.po | 57 + widget_viewer_evas/res/po/ml.po | 57 + widget_viewer_evas/res/po/nb.po | 57 + widget_viewer_evas/res/po/nl.po | 57 + widget_viewer_evas/res/po/pl.po | 57 + widget_viewer_evas/res/po/pt_BR.po | 57 + widget_viewer_evas/res/po/pt_PT.po | 57 + widget_viewer_evas/res/po/ro.po | 57 + widget_viewer_evas/res/po/ru_RU.po | 57 + widget_viewer_evas/res/po/si.po | 57 + widget_viewer_evas/res/po/sk.po | 57 + widget_viewer_evas/res/po/sl.po | 57 + widget_viewer_evas/res/po/sr.po | 57 + widget_viewer_evas/res/po/sv.po | 57 + widget_viewer_evas/res/po/ta.po | 57 + widget_viewer_evas/res/po/te.po | 57 + widget_viewer_evas/res/po/th.po | 57 + widget_viewer_evas/res/po/tr_TR.po | 57 + widget_viewer_evas/res/po/uk.po | 57 + widget_viewer_evas/res/po/ur.po | 57 + widget_viewer_evas/res/po/uz.po | 57 + widget_viewer_evas/res/po/zh_CN.po | 57 + widget_viewer_evas/res/po/zh_HK.po | 57 + widget_viewer_evas/res/po/zh_TW.po | 57 + widget_viewer_evas/res/unknown.png | Bin 0 -> 19568 bytes widget_viewer_evas/res/widget_viewer_evas.edc | 446 ++ widget_viewer_evas/src/util_wayland.c | 35 + widget_viewer_evas/src/util_x11.c | 107 + widget_viewer_evas/src/widget_viewer_evas.c | 8280 ++++++++++++++++++++ widget_viewer_evas/widget_viewer_evas.pc.in | 12 + widget_viewer_sdk/CMakeLists.txt | 69 + widget_viewer_sdk/LICENSE | 206 + widget_viewer_sdk/data/CMakeLists.txt | 11 + widget_viewer_sdk/data/images/unknown.png | Bin 0 -> 19568 bytes widget_viewer_sdk/data/widget_viewer_sdk.edc | 323 + widget_viewer_sdk/include/debug.h | 28 + widget_viewer_sdk/include/main.h | 28 + widget_viewer_sdk/org.tizen.widget_viewer_sdk.efl | 40 + widget_viewer_sdk/org.tizen.widget_viewer_sdk.xml | 18 + widget_viewer_sdk/src/main.c | 738 ++ 126 files changed, 28986 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 packaging/libwidget_viewer.manifest create mode 100644 packaging/libwidget_viewer.spec create mode 100644 packaging/org.tizen.widget_viewer_sdk.manifest create mode 100644 widget_viewer/CMakeLists.txt create mode 100644 widget_viewer/LICENSE create mode 100644 widget_viewer/include/client.h create mode 100644 widget_viewer/include/conf.h create mode 100644 widget_viewer/include/debug.h create mode 100644 widget_viewer/include/desc_parser.h create mode 100644 widget_viewer/include/dlist.h create mode 100644 widget_viewer/include/fb.h create mode 100644 widget_viewer/include/file_service.h create mode 100644 widget_viewer/include/master_rpc.h create mode 100644 widget_viewer/include/util.h create mode 100644 widget_viewer/include/widget_viewer.h create mode 100644 widget_viewer/include/widget_viewer_internal.h create mode 100644 widget_viewer/src/client.c create mode 100644 widget_viewer/src/conf.c create mode 100644 widget_viewer/src/desc_parser.c create mode 100644 widget_viewer/src/dlist.c create mode 100644 widget_viewer/src/fb.c create mode 100644 widget_viewer/src/fb_wayland.c create mode 100644 widget_viewer/src/file_service.c create mode 100644 widget_viewer/src/master_rpc.c create mode 100644 widget_viewer/src/util.c create mode 100644 widget_viewer/src/widget.c create mode 100644 widget_viewer/src/widget_internal.c create mode 100644 widget_viewer/widget_viewer.pc.in create mode 100644 widget_viewer_evas/CMakeLists.txt create mode 100644 widget_viewer_evas/LICENSE create mode 100644 widget_viewer_evas/doc/image/PD.png create mode 100644 widget_viewer_evas/doc/image/download_folder.png create mode 100644 widget_viewer_evas/doc/image/front.jpg create mode 100644 widget_viewer_evas/doc/image/image_format.png create mode 100644 widget_viewer_evas/doc/image/message.png create mode 100644 widget_viewer_evas/doc/image/preload_folder.png create mode 100644 widget_viewer_evas/doc/image/script_format.png create mode 100644 widget_viewer_evas/doc/image/stock.png create mode 100644 widget_viewer_evas/doc/image/text_format.png create mode 100644 widget_viewer_evas/doc/image/twitter.png create mode 100644 widget_viewer_evas/doc/image/weather.png create mode 100644 widget_viewer_evas/doc/widget_viewer_evas_doc.h create mode 100644 widget_viewer_evas/include/util.h create mode 100644 widget_viewer_evas/include/widget_viewer_evas.h create mode 100644 widget_viewer_evas/include/widget_viewer_evas_internal.h create mode 100644 widget_viewer_evas/res/CMakeLists.txt create mode 100644 widget_viewer_evas/res/po/CMakeLists.txt create mode 100644 widget_viewer_evas/res/po/ar.po create mode 100644 widget_viewer_evas/res/po/az.po create mode 100644 widget_viewer_evas/res/po/bg.po create mode 100644 widget_viewer_evas/res/po/bn.po create mode 100644 widget_viewer_evas/res/po/ca.po create mode 100644 widget_viewer_evas/res/po/cs.po create mode 100644 widget_viewer_evas/res/po/da.po create mode 100644 widget_viewer_evas/res/po/de.po create mode 100644 widget_viewer_evas/res/po/el_GR.po create mode 100644 widget_viewer_evas/res/po/en.po create mode 100644 widget_viewer_evas/res/po/en_PH.po create mode 100644 widget_viewer_evas/res/po/en_US.po create mode 100644 widget_viewer_evas/res/po/es_ES.po create mode 100644 widget_viewer_evas/res/po/es_US.po create mode 100644 widget_viewer_evas/res/po/et.po create mode 100644 widget_viewer_evas/res/po/eu.po create mode 100644 widget_viewer_evas/res/po/fa.po create mode 100644 widget_viewer_evas/res/po/fi.po create mode 100644 widget_viewer_evas/res/po/fr.po create mode 100644 widget_viewer_evas/res/po/fr_CA.po create mode 100644 widget_viewer_evas/res/po/ga.po create mode 100644 widget_viewer_evas/res/po/gl.po create mode 100644 widget_viewer_evas/res/po/gu.po create mode 100644 widget_viewer_evas/res/po/he.po create mode 100644 widget_viewer_evas/res/po/hi.po create mode 100644 widget_viewer_evas/res/po/hr.po create mode 100644 widget_viewer_evas/res/po/hu.po create mode 100644 widget_viewer_evas/res/po/hy.po create mode 100644 widget_viewer_evas/res/po/is.po create mode 100644 widget_viewer_evas/res/po/it_IT.po create mode 100644 widget_viewer_evas/res/po/ja_JP.po create mode 100644 widget_viewer_evas/res/po/ka.po create mode 100644 widget_viewer_evas/res/po/kk.po create mode 100644 widget_viewer_evas/res/po/kn.po create mode 100644 widget_viewer_evas/res/po/ko_KR.po create mode 100644 widget_viewer_evas/res/po/lt.po create mode 100644 widget_viewer_evas/res/po/lv.po create mode 100644 widget_viewer_evas/res/po/mk.po create mode 100644 widget_viewer_evas/res/po/ml.po create mode 100644 widget_viewer_evas/res/po/nb.po create mode 100644 widget_viewer_evas/res/po/nl.po create mode 100644 widget_viewer_evas/res/po/pl.po create mode 100644 widget_viewer_evas/res/po/pt_BR.po create mode 100644 widget_viewer_evas/res/po/pt_PT.po create mode 100644 widget_viewer_evas/res/po/ro.po create mode 100644 widget_viewer_evas/res/po/ru_RU.po create mode 100644 widget_viewer_evas/res/po/si.po create mode 100644 widget_viewer_evas/res/po/sk.po create mode 100644 widget_viewer_evas/res/po/sl.po create mode 100644 widget_viewer_evas/res/po/sr.po create mode 100644 widget_viewer_evas/res/po/sv.po create mode 100644 widget_viewer_evas/res/po/ta.po create mode 100644 widget_viewer_evas/res/po/te.po create mode 100644 widget_viewer_evas/res/po/th.po create mode 100644 widget_viewer_evas/res/po/tr_TR.po create mode 100644 widget_viewer_evas/res/po/uk.po create mode 100644 widget_viewer_evas/res/po/ur.po create mode 100644 widget_viewer_evas/res/po/uz.po create mode 100644 widget_viewer_evas/res/po/zh_CN.po create mode 100644 widget_viewer_evas/res/po/zh_HK.po create mode 100644 widget_viewer_evas/res/po/zh_TW.po create mode 100644 widget_viewer_evas/res/unknown.png create mode 100644 widget_viewer_evas/res/widget_viewer_evas.edc create mode 100644 widget_viewer_evas/src/util_wayland.c create mode 100644 widget_viewer_evas/src/util_x11.c create mode 100644 widget_viewer_evas/src/widget_viewer_evas.c create mode 100644 widget_viewer_evas/widget_viewer_evas.pc.in create mode 100644 widget_viewer_sdk/CMakeLists.txt create mode 100644 widget_viewer_sdk/LICENSE create mode 100644 widget_viewer_sdk/data/CMakeLists.txt create mode 100644 widget_viewer_sdk/data/images/unknown.png create mode 100644 widget_viewer_sdk/data/widget_viewer_sdk.edc create mode 100644 widget_viewer_sdk/include/debug.h create mode 100644 widget_viewer_sdk/include/main.h create mode 100644 widget_viewer_sdk/org.tizen.widget_viewer_sdk.efl create mode 100644 widget_viewer_sdk/org.tizen.widget_viewer_sdk.xml create mode 100644 widget_viewer_sdk/src/main.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b289f6d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +ADD_SUBDIRECTORY(widget_viewer) +ADD_SUBDIRECTORY(widget_viewer_evas) +ADD_SUBDIRECTORY(widget_viewer_sdk) + +ADD_DEPENDENCIES(widget_viewer_evas widget_viewer) +ADD_DEPENDENCIES(widget_viewer_sdk widget_viewer_evas) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..571fe79 --- /dev/null +++ b/LICENSE @@ -0,0 +1,206 @@ +Flora License + +Version 1.1, April, 2013 + +http://floralicense.org/license/ + +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. + +"Tizen Certified Platform" shall mean a software platform that complies +with the standards set forth in the Tizen Compliance Specification +and passes the Tizen Compliance Tests as defined from time to time +by the Tizen Technical Steering Group and certified by the Tizen +Association or its designated agent. + +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 +solely as incorporated into a Tizen Certified Platform, 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 solely +as incorporated into a Tizen Certified Platform 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 pursuant to the copyright license +above, in any medium, with or without modifications, and in Source or +Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works + a copy of this License; and + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + 3. 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 + 4. 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 + and your own copyright statement or terms and conditions do not conflict + the conditions stated in the License including section 3. + +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 Flora License to your work + +To apply the Flora 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 Flora License, Version 1.1 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://floralicense.org/license/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT 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/packaging/libwidget_viewer.manifest b/packaging/libwidget_viewer.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/packaging/libwidget_viewer.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/libwidget_viewer.spec b/packaging/libwidget_viewer.spec new file mode 100644 index 0000000..d1273d0 --- /dev/null +++ b/packaging/libwidget_viewer.spec @@ -0,0 +1,151 @@ +%bcond_with wayland + +Name: libwidget_viewer +Summary: Library for developing the application +Version: 1.2.1 +Release: 1 +Group: Applications/Core Applications +License: Flora-1.1 +Source0: %{name}-%{version}.tar.gz +Source1001: %{name}.manifest +Source1002: org.tizen.widget_viewer_sdk.manifest +BuildRequires: cmake, gettext-tools, coreutils, edje-bin +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(aul) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(com-core) +BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(db-util) +BuildRequires: pkgconfig(widget_service) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(appcore-efl) +BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(efl-extension) + +%if %{with wayland} +BuildRequires: pkgconfig(wayland-client) +BuildRequires: pkgconfig(libtbm) +%else +BuildRequires: pkgconfig(x11) +BuildRequires: pkgconfig(xext) +%endif + +%description +API for creating a new instance of the widget and managing its life-cycle. + +%package devel +Summary: Development Library for widget Viewer Application (dev) +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Header and package configuration files for the widget viewer development + +%prep +%setup -q +cp %{SOURCE1001} . +cp %{SOURCE1002} . + +%build +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" + +export CFLAGS="${CFLAGS} -DTIZEN_ENGINEER_MODE" +export CXXFLAGS="${CXXFLAGS} -DTIZEN_ENGINEER_MODE" +export FFLAGS="${FFLAGS} -DTIZEN_ENGINEER_MODE" + +%if %{with wayland} +export WAYLAND_SUPPORT=On +export X11_SUPPORT=Off +%else +export WAYLAND_SUPPORT=Off +export X11_SUPPORT=On +%endif + +%cmake . -DWAYLAND_SUPPORT=${WAYLAND_SUPPORT} -DX11_SUPPORT=${X11_SUPPORT} -DWIDGET_ENABLED=On +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +%post -n %{name} -p /sbin/ldconfig +%postun -n %{name} -p /sbin/ldconfig + +%files -n %{name} +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_libdir}/%{name}.so* +%{_datarootdir}/license/%{name} + +%files devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_includedir}/widget_viewer/widget_viewer.h +%{_libdir}/pkgconfig/widget_viewer.pc + +################################################# +# libwidget_viewer_evas +%package -n %{name}_evas +Summary: Library for developing the widget viewer evas +Group: Applications/Core Applications +License: Flora-1.1 + +%description -n %{name}_evas +Provider APIs to develop the widget viewer EFL application. + +%package -n %{name}_evas-devel +Summary: Widget provider application development library (dev) (EFL version) +Group: Development/Libraries +Requires: %{name}_evas + +%description -n %{name}_evas-devel +Header & package configuration files to support development of the widget viewer applications. (for EFL app) + +%post -n %{name}_evas -p /sbin/ldconfig +%postun -n %{name}_evas -p /sbin/ldconfig + +################################################# +# org.tizen.widget_viewer_sdk +%package -n org.tizen.widget_viewer_sdk +Summary: The widget viewer for development using SDK(IDE) +Version: 0.0.1 +Group: Development/Tools +License: Flora-1.1 +Requires: %{name}_evas + +%description -n org.tizen.widget_viewer_sdk +While developing the widget applications, this viewer will load it and execute it to help you to see it on the screen. + +%post -n org.tizen.widget_viewer_sdk -p /sbin/ldconfig +%postun -n org.tizen.widget_viewer_sdk -p /sbin/ldconfig + +%files -n %{name}_evas +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_libdir}/%{name}_evas.so* +%{_datadir}/widget_viewer_evas/* +%{_datarootdir}/license/%{name}_evas + +%files -n %{name}_evas-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_includedir}/widget_viewer_evas/widget_viewer_evas.h +%{_includedir}/widget_viewer_evas/widget_viewer_evas_internal.h +%{_libdir}/pkgconfig/widget_viewer_evas.pc + +%files -n org.tizen.widget_viewer_sdk +%manifest org.tizen.widget_viewer_sdk.manifest +%defattr(-,root,root,-) +%attr(-,app,app) %dir /opt/usr/apps/org.tizen.widget_viewer_sdk/data +%{_datarootdir}/packages/org.tizen.widget_viewer_sdk.xml +%{_sysconfdir}/smack/accesses.d +%{_datarootdir}/license/org.tizen.widget_viewer_sdk +%{_prefix}/apps/org.tizen.widget_viewer_sdk/* + +# End of a file diff --git a/packaging/org.tizen.widget_viewer_sdk.manifest b/packaging/org.tizen.widget_viewer_sdk.manifest new file mode 100644 index 0000000..04def52 --- /dev/null +++ b/packaging/org.tizen.widget_viewer_sdk.manifest @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widget_viewer/CMakeLists.txt b/widget_viewer/CMakeLists.txt new file mode 100644 index 0000000..1cda0b1 --- /dev/null +++ b/widget_viewer/CMakeLists.txt @@ -0,0 +1,103 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(widget_viewer C) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(PROJECT_NAME "${PROJECT_NAME}") +SET(LIBDIR ${LIB_INSTALL_DIR}) +SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}") +SET(VERSION_MAJOR 1) +SET(VERSION "${VERSION_MAJOR}.0.0") + +SET(CMAKE_SKIP_BUILD_RPATH true) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED + dlog + aul + glib-2.0 + gio-2.0 + com-core + sqlite3 + db-util + widget_service + vconf +) + +SET(BUILD_SOURCE + src/client.c + src/conf.c + src/desc_parser.c + src/dlist.c + src/widget.c + src/widget_internal.c + src/file_service.c + src/master_rpc.c + src/util.c +) + +IF (X11_SUPPORT) +pkg_check_modules(pkgs_extra REQUIRED + x11 + xext +) + +SET(BUILD_SOURCE + ${BUILD_SOURCE} + src/fb.c +) +ADD_DEFINITIONS("-DHAVE_X11") +ENDIF (X11_SUPPORT) + +IF (WAYLAND_SUPPORT) +pkg_check_modules(pkgs_extra REQUIRED + libtbm +) + +SET(BUILD_SOURCE + ${BUILD_SOURCE} + src/fb_wayland.c +) +ADD_DEFINITIONS("-DHAVE_WAYLAND") +ENDIF (WAYLAND_SUPPORT) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +FOREACH(flag ${pkgs_extra_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline -g") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") +ADD_DEFINITIONS("-DLOG_TAG=\"WIDGET_VIEWER\"") +ADD_DEFINITIONS("-DNDEBUG") +ADD_DEFINITIONS("-D_USE_ECORE_TIME_GET") +#ADD_DEFINITIONS("-DFLOG") +ADD_DEFINITIONS("-DMASTER_PKGNAME=\"data-provider-master\"") +ADD_DEFINITIONS("-DINFO_SOCKET=\"/opt/usr/share/live_magazine/.live.socket\"") +ADD_DEFINITIONS("-DCLIENT_SOCKET=\"/tmp/.data-provider-master-client.socket\"") +ADD_DEFINITIONS("-DSLAVE_SOCKET=\"/tmp/.data-provider-master-slave.socket\"") +ADD_DEFINITIONS("-DSHARED_SOCKET=\"/tmp/.data-provider-master-fd.socket\"") +ADD_DEFINITIONS("-DSERVICE_SOCKET=\"/tmp/.data-provider-master-service.socket\"") +ADD_LIBRARY(${PROJECT_NAME} SHARED ${BUILD_SOURCE}) + +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${pkgs_extra_LDFLAGS} "-lpthread") + +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) +SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PROJECT_NAME}.pc") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/widget_viewer.h DESTINATION include/${PROJECT_NAME}) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME "lib${PROJECT_NAME}") diff --git a/widget_viewer/LICENSE b/widget_viewer/LICENSE new file mode 100644 index 0000000..571fe79 --- /dev/null +++ b/widget_viewer/LICENSE @@ -0,0 +1,206 @@ +Flora License + +Version 1.1, April, 2013 + +http://floralicense.org/license/ + +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. + +"Tizen Certified Platform" shall mean a software platform that complies +with the standards set forth in the Tizen Compliance Specification +and passes the Tizen Compliance Tests as defined from time to time +by the Tizen Technical Steering Group and certified by the Tizen +Association or its designated agent. + +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 +solely as incorporated into a Tizen Certified Platform, 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 solely +as incorporated into a Tizen Certified Platform 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 pursuant to the copyright license +above, in any medium, with or without modifications, and in Source or +Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works + a copy of this License; and + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + 3. 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 + 4. 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 + and your own copyright statement or terms and conditions do not conflict + the conditions stated in the License including section 3. + +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 Flora License to your work + +To apply the Flora 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 Flora License, Version 1.1 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://floralicense.org/license/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT 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/widget_viewer/include/client.h b/widget_viewer/include/client.h new file mode 100644 index 0000000..dc7a744 --- /dev/null +++ b/widget_viewer/include/client.h @@ -0,0 +1,24 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +extern int client_init(int use_thread); +extern int client_fd(void); +extern const char *client_addr(void); +extern const char *client_direct_addr(void); +extern int client_direct_fd(void); +extern int client_fini(void); + +/* End of a file */ diff --git a/widget_viewer/include/conf.h b/widget_viewer/include/conf.h new file mode 100644 index 0000000..1e96f47 --- /dev/null +++ b/widget_viewer/include/conf.h @@ -0,0 +1,48 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! + * \note + * milli seconds + */ +#define MAX_LOG_FILE 3 +#define MAX_LOG_LINE 1000 +#define SLAVE_LOG_PATH "/tmp/.widget.service/log/" + +#if !defined(VCONFKEY_MASTER_STARTED) +#define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started" +#endif + +#if !defined(VCONFKEY_MASTER_CLIENT_ADDR) +#define VCONFKEY_MASTER_CLIENT_ADDR "db/data-provider-master/serveraddr" +#endif + +extern void conf_set_manual_sync(int flag); +extern int conf_manual_sync(void); +extern void conf_set_frame_drop_for_resizing(int flag); +extern int conf_frame_drop_for_resizing(void); +extern void conf_set_shared_content(int flag); +extern int conf_shared_content(void); +extern double conf_event_filter(void); +extern void conf_set_event_filter(double filter); +extern void conf_set_direct_update(int flag); +extern int conf_direct_update(void); +extern int conf_extra_buffer_count(void); +extern void conf_set_extra_buffer_count(int buffer_count); +extern widget_status_e conf_last_status(void); +extern void conf_set_last_status(widget_status_e status); + +/* End of a file */ diff --git a/widget_viewer/include/debug.h b/widget_viewer/include/debug.h new file mode 100644 index 0000000..a6563ee --- /dev/null +++ b/widget_viewer/include/debug.h @@ -0,0 +1,28 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if !defined(FLOG) +#define DbgPrint(format, arg...) SECURE_LOGD(format, ##arg) +#define ErrPrint(format, arg...) SECURE_LOGE(format, ##arg) +#else +extern FILE *__file_log_fp; +#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) + +#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) +#endif + + +/* End of a file */ diff --git a/widget_viewer/include/desc_parser.h b/widget_viewer/include/desc_parser.h new file mode 100644 index 0000000..72c3dda --- /dev/null +++ b/widget_viewer/include/desc_parser.h @@ -0,0 +1,19 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +extern int parse_desc(struct widget_common *common, const char *filename, int is_pd); + +/* End of a file */ diff --git a/widget_viewer/include/dlist.h b/widget_viewer/include/dlist.h new file mode 100644 index 0000000..3f19827 --- /dev/null +++ b/widget_viewer/include/dlist.h @@ -0,0 +1,43 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 dlist_remove_data(list, data) do { \ + struct dlist *l; \ + l = dlist_find_data(list, data); \ + list = dlist_remove(list, l); \ +} while (0) + +#define dlist_foreach(list, l, data) \ + for ((l) = (list); (l) && ((data) = dlist_data(l)); (l) = dlist_next(l)) + +#define dlist_foreach_safe(list, l, n, data) \ + for ((l) = (list), (n) = dlist_next(l); \ + (l) && ((data) = dlist_data(l)); \ + (l) = (n), (n) = dlist_next(l)) + +struct dlist; + +extern struct dlist *dlist_append(struct dlist *list, void *data); +extern struct dlist *dlist_prepend(struct dlist *list, void *data); +extern struct dlist *dlist_remove(struct dlist *list, struct dlist *l); +extern struct dlist *dlist_find_data(struct dlist *list, void *data); +extern void *dlist_data(struct dlist *l); +extern struct dlist *dlist_next(struct dlist *l); +extern struct dlist *dlist_prev(struct dlist *l); +extern int dlist_count(struct dlist *l); +extern struct dlist *dlist_nth(struct dlist *l, int nth); + +/* End of a file */ diff --git a/widget_viewer/include/fb.h b/widget_viewer/include/fb.h new file mode 100644 index 0000000..e7b8543 --- /dev/null +++ b/widget_viewer/include/fb.h @@ -0,0 +1,35 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +struct fb_info; + +extern int fb_init(void *disp); +extern int fb_fini(void); +extern const char *fb_id(struct fb_info *info); +extern int fb_get_size(struct fb_info *info, int *w, int *h); +extern int fb_sync(struct fb_info *info, int x, int y, int w, int h); +extern int fb_size(struct fb_info *info); +extern int fb_refcnt(void *data); +extern int fb_is_created(struct fb_info *info); +extern int fb_type(struct fb_info *info); + +extern struct fb_info *fb_create(const char *filename, int w, int h); +extern int fb_destroy(struct fb_info *info); + +extern void *fb_acquire_buffer(struct fb_info *info); +extern int fb_release_buffer(void *data); + +/* End of a file */ diff --git a/widget_viewer/include/file_service.h b/widget_viewer/include/file_service.h new file mode 100644 index 0000000..9212d03 --- /dev/null +++ b/widget_viewer/include/file_service.h @@ -0,0 +1,21 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +extern int file_service_send_request(const char *filename, const char *save_to, void (*result_cb)(const char *filename, const char *save_to, int ret, void *data), void *data); +extern int file_service_fini(void); +extern int file_service_init(void); + +/* End of a file */ diff --git a/widget_viewer/include/master_rpc.h b/widget_viewer/include/master_rpc.h new file mode 100644 index 0000000..e07306d --- /dev/null +++ b/widget_viewer/include/master_rpc.h @@ -0,0 +1,24 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +extern int master_rpc_async_request(struct widget *handler, struct packet *packet, int urgent, void (*ret_cb)(struct widget *handler, const struct packet *result, void *data), void *data); +extern int master_rpc_sync_request(struct packet *packet); +extern void master_rpc_check_and_fire_consumer(void); +extern int master_rpc_request_only(struct widget *handler, struct packet *packet); +extern int master_rpc_clear_fault_package(const char *pkgname); +extern int master_rpc_clear_all_request(void); + +/* End of a file */ diff --git a/widget_viewer/include/util.h b/widget_viewer/include/util.h new file mode 100644 index 0000000..498a249 --- /dev/null +++ b/widget_viewer/include/util.h @@ -0,0 +1,31 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +extern int util_check_extension(const char *filename, const char *check_ptr); +extern double util_timestamp(void); +extern const char *util_basename(const char *name); +extern const char *util_uri_to_path(const char *uri); +extern int util_unlink(const char *filename); + +#define SCHEMA_FILE "file://" +#define SCHEMA_PIXMAP "pixmap://" +#define SCHEMA_SHM "shm://" + +#define container_of(ptr, type, member) \ + ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +/* End of a file */ diff --git a/widget_viewer/include/widget_viewer.h b/widget_viewer/include/widget_viewer.h new file mode 100644 index 0000000..6c7a81c --- /dev/null +++ b/widget_viewer/include/widget_viewer.h @@ -0,0 +1,1643 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 + +#ifndef __WIDGET_VIEWER_H +#define __WIDGET_VIEWER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file widget_viewer.h + * @brief This file declares API of libwidget-viewer library + * @since_tizen 2.3.1 + */ + +/** + * @addtogroup CAPI_WIDGET_VIEWER_MODULE + * @{ + */ + +/** + * @brief Structure definition for a widget instance. + * @since_tizen 2.3.1 + */ +typedef struct widget *widget_h; + +/** + * @internal + * @brief Definition for a default update period for widget (defined in the package manifest file). + * @since_tizen 2.3.1 + */ +#define WIDGET_DEFAULT_PERIOD -1.0f + +/** + * @internal + * @brief Enumeration for Mouse & Key event for buffer type widget or Glance Bar. + * @details Viewer should send these events to widget. + * @since_tizen 2.3.1 + */ +typedef enum widget_mouse_event_type { + WIDGET_MOUSE_EVENT_MASK = 0x20000000, /**< Mask value for mouse event */ + WIDGET_MOUSE_EVENT_GBAR_MASK = 0x10000000, /**< Mask value for Glance Bar event */ + WIDGET_MOUSE_EVENT_WIDGET_MASK = 0x40000000, /**< Mask value for widget event */ + + WIDGET_MOUSE_EVENT_DOWN = 0x00000001, /**< widget mouse down event for widget */ + WIDGET_MOUSE_EVENT_UP = 0x00000002, /**< widget mouse up event for widget */ + WIDGET_MOUSE_EVENT_MOVE = 0x00000004, /**< widget mouse move event for widget */ + WIDGET_MOUSE_EVENT_ENTER = 0x00000008, /**< widget mouse enter event for widget */ + WIDGET_MOUSE_EVENT_LEAVE = 0x00000010, /**< widget mouse leave event for widget */ + WIDGET_MOUSE_EVENT_SET = 0x00000020, /**< widget mouse set auto event for widget */ + WIDGET_MOUSE_EVENT_UNSET = 0x00000040, /**< widget mouse unset auto event for widget */ + + WIDGET_MOUSE_EVENT_ON_SCROLL = 0x00000080, /**< widget On scrolling */ + WIDGET_MOUSE_EVENT_ON_HOLD = 0x00000100, /**< widget On holding */ + WIDGET_MOUSE_EVENT_OFF_SCROLL = 0x00000200, /**< widget Stop scrolling */ + WIDGET_MOUSE_EVENT_OFF_HOLD = 0x00000400, /**< widget Stop holding */ + + WIDGET_MOUSE_ON_SCROLL = WIDGET_MOUSE_EVENT_WIDGET_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_ON_SCROLL, /**< Mouse event occurs while scrolling */ + WIDGET_MOUSE_ON_HOLD = WIDGET_MOUSE_EVENT_WIDGET_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_ON_HOLD, /**< Mouse event occurs on holding */ + WIDGET_MOUSE_OFF_SCROLL = WIDGET_MOUSE_EVENT_WIDGET_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_OFF_SCROLL, /**< Scrolling stopped */ + WIDGET_MOUSE_OFF_HOLD = WIDGET_MOUSE_EVENT_WIDGET_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_OFF_HOLD, /**< Holding stopped */ + + WIDGET_MOUSE_DOWN = WIDGET_MOUSE_EVENT_WIDGET_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_DOWN, /**< Mouse down on the widget */ + WIDGET_MOUSE_UP = WIDGET_MOUSE_EVENT_WIDGET_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_UP, /**< Mouse up on the widget */ + WIDGET_MOUSE_MOVE = WIDGET_MOUSE_EVENT_WIDGET_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_MOVE, /**< Move move on the widget */ + WIDGET_MOUSE_ENTER = WIDGET_MOUSE_EVENT_WIDGET_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_ENTER, /**< Mouse enter to the widget */ + WIDGET_MOUSE_LEAVE = WIDGET_MOUSE_EVENT_WIDGET_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_LEAVE, /**< Mouse leave from the widget */ + WIDGET_MOUSE_SET = WIDGET_MOUSE_EVENT_WIDGET_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_SET, /**< Mouse event, start feeding event by master */ + WIDGET_MOUSE_UNSET = WIDGET_MOUSE_EVENT_WIDGET_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_UNSET, /**< Mouse event, stop feeding event by master */ + + WIDGET_GBAR_MOUSE_ON_SCROLL = WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_ON_SCROLL, /**< Mouse event occurs while scrolling */ + WIDGET_GBAR_MOUSE_ON_HOLD = WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_ON_HOLD, /**< Mouse event occurs on holding */ + WIDGET_GBAR_MOUSE_OFF_SCROLL = WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_OFF_SCROLL, /**< Scrolling stopped */ + WIDGET_GBAR_MOUSE_OFF_HOLD = WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_OFF_HOLD, /**< Holding stopped */ + + WIDGET_GBAR_MOUSE_DOWN = WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_DOWN, /**< Mouse down on the Glance Bar */ + WIDGET_GBAR_MOUSE_UP = WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_UP, /**< Mouse up on the Glance Bar */ + WIDGET_GBAR_MOUSE_MOVE = WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_MOVE, /**< Mouse move on the Glance Bar */ + WIDGET_GBAR_MOUSE_ENTER = WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_ENTER, /**< Mouse enter to the Glance Bar */ + WIDGET_GBAR_MOUSE_LEAVE = WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_LEAVE, /**< Mouse leave from the Glance Bar */ + WIDGET_GBAR_MOUSE_SET = WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_SET, /**< Mouse event, start feeding event by master */ + WIDGET_GBAR_MOUSE_UNSET = WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_MASK | WIDGET_MOUSE_EVENT_UNSET, /**< Mouse event, stop feeding event by master */ + + WIDGET_MOUSE_EVENT_MAX = 0xFFFFFFFF /**< Unknown event */ +} widget_mouse_event_type_e; + +typedef enum widget_key_event_type { + WIDGET_KEY_EVENT_MASK = 0x80000000, /**< Mask value for key event */ + WIDGET_KEY_EVENT_GBAR_MASK = 0x10000000, /**< Mask value for Glance Bar event */ + WIDGET_KEY_EVENT_WIDGET_MASK = 0x40000000, /**< Mask value for widget event */ + + WIDGET_KEY_EVENT_DOWN = 0x00000001, /**< widget key press */ + WIDGET_KEY_EVENT_UP = 0x00000002, /**< widget key release */ + WIDGET_KEY_EVENT_FOCUS_IN = 0x00000008, /**< widget key focused in */ + WIDGET_KEY_EVENT_FOCUS_OUT = 0x00000010, /**< widget key focused out */ + WIDGET_KEY_EVENT_SET = 0x00000020, /**< widget Key, start feeding event by master */ + WIDGET_KEY_EVENT_UNSET = 0x00000040, /**< widget key, stop feeding event by master */ + + WIDGET_KEY_DOWN = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_WIDGET_MASK | WIDGET_KEY_EVENT_DOWN, /**< Key down on the widget */ + WIDGET_KEY_UP = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_WIDGET_MASK | WIDGET_KEY_EVENT_UP, /**< Key up on the widget */ + WIDGET_KEY_SET = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_WIDGET_MASK | WIDGET_KEY_EVENT_SET, /**< Key event, start feeding event by master */ + WIDGET_KEY_UNSET = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_WIDGET_MASK | WIDGET_KEY_EVENT_UNSET, /**< Key event, stop feeding event by master */ + WIDGET_KEY_FOCUS_IN = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_WIDGET_MASK | WIDGET_KEY_EVENT_FOCUS_IN, /**< Key event, focus in */ + WIDGET_KEY_FOCUS_OUT = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_WIDGET_MASK | WIDGET_KEY_EVENT_FOCUS_OUT, /**< Key event, foucs out */ + + WIDGET_GBAR_KEY_DOWN = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_GBAR_MASK | WIDGET_KEY_EVENT_DOWN, /**< Key down on the widget */ + WIDGET_GBAR_KEY_UP = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_GBAR_MASK | WIDGET_KEY_EVENT_UP, /**< Key up on the widget */ + WIDGET_GBAR_KEY_SET = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_GBAR_MASK | WIDGET_KEY_EVENT_SET, /**< Key event, start feeding event by master */ + WIDGET_GBAR_KEY_UNSET = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_GBAR_MASK | WIDGET_KEY_EVENT_UNSET, /**< Key event, stop feeding event by master */ + WIDGET_GBAR_KEY_FOCUS_IN = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_GBAR_MASK | WIDGET_KEY_EVENT_FOCUS_IN, /**< Key event, focus in */ + WIDGET_GBAR_KEY_FOCUS_OUT = WIDGET_KEY_EVENT_MASK | WIDGET_KEY_EVENT_GBAR_MASK | WIDGET_KEY_EVENT_FOCUS_OUT, /**< Key event, focus out */ + + WIDGET_KEY_EVENT_MAX = 0xFFFFFFFF /**< Unknown event */ +} widget_key_event_type_e; + +/** + * @internal + * @brief Enumeration for Accessibility event for buffer type widget or Glance Bar. + * @details These events are sync'd with Tizen accessibility event set. + * @since_tizen 2.3.1 + */ +typedef enum widget_access_event_type { + WIDGET_ACCESS_EVENT_GBAR_MASK = 0x10000000, /**< Glance Bar Accessibilivent mask */ + WIDGET_ACCESS_EVENT_WIDGET_MASK = 0x20000000, /**< widget Accessibility event mask */ + + WIDGET_ACCESS_EVENT_HIGHLIGHT = 0x00000100, /**< widget accessibility: Hightlight a object, Next, Prev,Unhighlight */ + WIDGET_ACCESS_EVENT_ACTIVATE = 0x00000200, /**< widget accessibility activate */ + WIDGET_ACCESS_EVENT_ACTION = 0x00000400, /**< widget accessibility value changed, Up, Down */ + WIDGET_ACCESS_EVENT_SCROLL = 0x00000800, /**< widget accessibility scroll down, move, up */ + WIDGET_ACCESS_EVENT_VALUE_CHANGE = 0x00001000, /**< LB accessibility value change */ + WIDGET_ACCESS_EVENT_MOUSE = 0x00002000, /**< Give mouse event to highlight object, down, move, up */ + WIDGET_ACCESS_EVENT_BACK = 0x00004000, /**< Go back to a previous view ex: pop naviframe item */ + WIDGET_ACCESS_EVENT_OVER = 0x00008000, /**< Mouse over an object */ + WIDGET_ACCESS_EVENT_READ = 0x00010000, /**< Highlight an object */ + WIDGET_ACCESS_EVENT_ENABLE = 0x00020000, /**< Disable highlight and read ability, disable, enable */ + + WIDGET_ACCESS_HIGHLIGHT = WIDGET_ACCESS_EVENT_WIDGET_MASK | WIDGET_ACCESS_EVENT_HIGHLIGHT, /**< Access event - Highlight an object in the widget */ + WIDGET_ACCESS_ACTIVATE = WIDGET_ACCESS_EVENT_WIDGET_MASK | WIDGET_ACCESS_EVENT_ACTIVATE, /**< Access event - Launch or activate the highlighted object */ + WIDGET_ACCESS_ACTION = WIDGET_ACCESS_EVENT_WIDGET_MASK | WIDGET_ACCESS_EVENT_ACTION, /**< Access event - down */ + WIDGET_ACCESS_SCROLL = WIDGET_ACCESS_EVENT_WIDGET_MASK | WIDGET_ACCESS_EVENT_SCROLL, /**< Access event - scroll down */ + WIDGET_ACCESS_VALUE_CHANGE = WIDGET_ACCESS_EVENT_WIDGET_MASK | WIDGET_ACCESS_EVENT_VALUE_CHANGE, /**< LB accessibility value change */ + WIDGET_ACCESS_MOUSE = WIDGET_ACCESS_EVENT_WIDGET_MASK | WIDGET_ACCESS_EVENT_MOUSE, /**< Give mouse event to highlight object */ + WIDGET_ACCESS_BACK = WIDGET_ACCESS_EVENT_WIDGET_MASK | WIDGET_ACCESS_EVENT_BACK, /**< Go back to a previous view ex: pop naviframe item */ + WIDGET_ACCESS_OVER = WIDGET_ACCESS_EVENT_WIDGET_MASK | WIDGET_ACCESS_EVENT_OVER, /**< Mouse over an object */ + WIDGET_ACCESS_READ = WIDGET_ACCESS_EVENT_WIDGET_MASK | WIDGET_ACCESS_EVENT_READ, /**< Highlight an object */ + WIDGET_ACCESS_ENABLE = WIDGET_ACCESS_EVENT_WIDGET_MASK | WIDGET_ACCESS_EVENT_ENABLE, /**< Enable highlight and read ability */ + + WIDGET_GBAR_ACCESS_HIGHLIGHT = WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_HIGHLIGHT, /**< Access event - Highlight an object in the Glance Bar */ + WIDGET_GBAR_ACCESS_ACTIVATE = WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_ACTIVATE, /**< Access event - Launch or activate the highlighted object */ + WIDGET_GBAR_ACCESS_ACTION = WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_ACTION, /**< Access event - down */ + WIDGET_GBAR_ACCESS_SCROLL = WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_SCROLL, /**< Access event - scroll down */ + WIDGET_GBAR_ACCESS_VALUE_CHANGE = WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_VALUE_CHANGE, /**< LB accessibility value change */ + WIDGET_GBAR_ACCESS_MOUSE = WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_MOUSE, /**< Give mouse event to highlight object */ + WIDGET_GBAR_ACCESS_BACK = WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_BACK, /**< Go back to a previous view ex: pop naviframe item */ + WIDGET_GBAR_ACCESS_OVER = WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_OVER, /**< Mouse over an object */ + WIDGET_GBAR_ACCESS_READ = WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_READ, /**< Highlight an object */ + WIDGET_GBAR_ACCESS_ENABLE = WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_ENABLE, /**< Enable highlight and read ability */ + WIDGET_GBAR_ACCESS_EVENT_MAX = 0xFFFFFFFF +} widget_access_event_type_e; + +/** + * @internal + * @brief Enumeration for widget content type. + * @since_tizen 2.3.1 + */ +typedef enum widget_type { + WIDGET_CONTENT_TYPE_IMAGE = 0x01, /**< Contents of a widget is based on the image file */ + WIDGET_CONTENT_TYPE_BUFFER = 0x02, /**< Contents of a widget is based on canvas buffer(shared) */ + WIDGET_CONTENT_TYPE_TEXT = 0x04, /**< Contents of a widget is based on formatted text file */ + WIDGET_CONTENT_TYPE_RESOURCE_ID = 0x08, /**< Contens of a widget is shared by the resource id(depends on window system) */ + WIDGET_CONTENT_TYPE_UIFW = 0x10, /**< Using UI F/W resource for sharing content & event */ + WIDGET_CONTENT_TYPE_INVALID = 0xFF /**< Unknown widget type */ +} widget_type_e; + +/** + * @brief Enumeration for widget option types. + * @since_tizen 2.3.1 + */ +typedef enum widget_option_type { + WIDGET_OPTION_MANUAL_SYNC, /**< Sync frame manually */ + WIDGET_OPTION_FRAME_DROP_FOR_RESIZE, /**< Drop frames while resizing */ + WIDGET_OPTION_SHARED_CONTENT, /**< Use only one real instance for multiple fake instances if user creates widget for same content */ + WIDGET_OPTION_DIRECT_UPDATE, /**< Use the private socket for receiving updated event */ + WIDGET_OPTION_EXTRA_BUFFER_CNT, /**< Extra buffer count, ReadOnly value */ + + WIDGET_OPTION_ERROR = 0xFFFFFFFF /**< To specify the size of this enumeration type */ +} widget_option_type_e; + +/** + * @internal + * @brief Reason of faults + * @since_tizen 2.3.1 + */ +typedef enum widget_fault_type { + WIDGET_FAULT_DEACTIVATED, /**< widget is deactivated by its fault operation */ + WIDGET_FAULT_PROVIDER_DISCONNECTED, /**< Provider is disconnected */ + WIDGET_FAULT_MAX = 0xFF /**< To specify the size of this enumeration type, some compiler enjoy of this kind of notation */ +} widget_fault_type_e; + +/** + * @brief Enumeration for widget visible states. + * @details Must be sync'd with a provider. + * @since_tizen 2.3.1 + */ +typedef enum widget_visible_state { + WIDGET_SHOW = 0x00, /**< widget is shown. Default state */ + WIDGET_HIDE = 0x01, /**< widget is hidden, Update timer will not be freezed. but you cannot receive any updates events. */ + + WIDGET_HIDE_WITH_PAUSE = 0x02, /**< widget is hidden, it will pause the update timer, but if a widget updates its contents, update event will be triggered */ + + WIDGET_VISIBLE_ERROR = 0xFF /**< To specify the size of this enumeration type */ +} widget_visible_state_e; + +/** + * @internal + * @brief Accessibility Event type + * @since_tizen 2.3.1 + * @see widget_feed_access_event() + */ +typedef enum widget_access_info_type { + WIDGET_ACCESS_TYPE_NONE = 0x00, /**< Initialized */ + + WIDGET_ACCESS_TYPE_DOWN = 0x00, /**< Mouse down */ + WIDGET_ACCESS_TYPE_MOVE = 0x01, /**< Mouse move */ + WIDGET_ACCESS_TYPE_UP = 0x02, /**< Mouse up */ + + WIDGET_ACCESS_TYPE_HIGHLIGHT = 0x00, /**< Highlight */ + WIDGET_ACCESS_TYPE_HIGHLIGHT_NEXT = 0x01, /**< Highlight next */ + WIDGET_ACCESS_TYPE_HIGHLIGHT_PREV = 0x02, /**< Highlight prev */ + WIDGET_ACCESS_TYPE_UNHIGHLIGHT = 0x03, /**< Unhighlight */ + + WIDGET_ACCESS_TYPE_DISABLE = 0x00, /**< Disable */ + WIDGET_ACCESS_TYPE_ENABLE = 0x01 /**< Enable */ +} widget_access_info_type_e; + +/** + * @internal + * @brief Accessibility Event Information + * @since_tizen 2.3.1 + */ +typedef struct widget_access_event_info { + double x; /**< X Coordinates that the event occurred */ + double y; /**< Y Coordinates that the event occurred */ + widget_access_info_type_e type; /**< Accessibility event type */ + int info; /**< Extra information for this event */ +} *widget_access_event_info_s; + +/** + * @internal + * @brief Damaged Region representation + * @since_tizen 2.3.1 + */ +typedef struct widget_damage_region { + int x; /**< Coordinates X of Left-Top corner */ + int y; /**< Coordinates Y of Left-Top corner */ + int w; /**< Damage'd Width */ + int h; /**< Damage'd Height */ +} widget_damage_region_s; + +/** + * @internal + * @brief Mouse Event Information + * @since_tizen 2.3.1 + */ +typedef struct widget_mouse_event_info { + double x; /**< X coordinates of Mouse Event */ + double y; /**< Y coordinates of Mouse Event */ + double ratio_w; + double ratio_h; + int device; +} *widget_mouse_event_info_s; + +/** + * @internal + * @brief Key Event Information + * @since_tizen 2.3.1 + */ +typedef struct widget_key_event_info { + unsigned int keycode; /**< Key code */ + int device; +} *widget_key_event_info_s; + +/** + * @internal + * @brief Structure for TEXT type widget contents handling opertators. + * @since_tizen 2.3.1 + */ +typedef struct widget_script_operators { + int (*update_begin)(widget_h handle); /**< Content parser is started */ + int (*update_end)(widget_h handle); /**< Content parser is finished */ + + /* Listed functions will be called when parser meets each typed content */ + int (*update_text)(widget_h handle, const char *id, const char *part, const char *data); /**< Update text content */ + int (*update_image)(widget_h handle, const char *id, const char *part, const char *data, const char *option); /**< Update image content */ + int (*update_script)(widget_h handle, const char *id, const char *new_id, const char *part, const char *file, const char *group); /**< Update script content */ + int (*update_signal)(widget_h handle, const char *id, const char *signal_name, const char *signal); /**< Update signal */ + int (*update_drag)(widget_h handle, const char *id, const char *part, double dx, double dy); /**< Update drag info */ + int (*update_info_size)(widget_h handle, const char *id, int w, int h); /**< Update content size */ + int (*update_info_category)(widget_h handle, const char *id, const char *category); /**< Update content category info */ + int (*update_access)(widget_h handle, const char *id, const char *part, const char *text, const char *option); /**< Update access information */ + int (*operate_access)(widget_h handle, const char *id, const char *part, const char *operation, const char *option); /**< Update access operation */ + int (*update_color)(widget_h handle, const char *id, const char *part, const char *data); /**< Update color */ +} *widget_script_operator_s; + +/** + * @internal + * @brief Called for every async function. + * @details Prototype of the return callback of every async functions. + * @since_tizen 2.3.1 + * @param[in] handle Handle of the widget instance + * @param[in] ret Result status of operation (WIDGET_STATUS_XXX defined from libwidget-service) + * @param[in] data Data for result callback + * @see widget_add() + * @see widget_del() + * @see widget_activate() + * @see widget_resize() + * @see widget_set_group() + * @see widget_set_period() + * @see widget_access_event() + * @see widget_set_pinup() + * @see widget_create_glance_bar() + * @see widget_destroy_glance_bar() + * @see widget_emit_text_signal() + * @see widget_acquire_resource_id() + * @see widget_set_update_mode() + */ +typedef void (*widget_ret_cb)(widget_h handle, int ret, void *data); + +/** + * @internal + * @brief Fault event handle + * @param[in] type Type of fault event. + * @param[in] widget_id Faulted widget Id + * @param[in] file faulted filename (implementation file if it is supported) + * @param[in] func faulted function name (if it is supported) + * @param[in] data Callback data + * @return 0 on success, otherwise a negative error value + * @retval @c EXIT_FAILURE delete this event callback from the event callback list + * @retval @c EXIT_SUCCESS successfully handled, keep this callback in the event callback list + */ +typedef int (*widget_fault_handler_cb)(enum widget_fault_type type, const char *widget_id, const char *file, const char *func, void *data); + +/** + * @brief Event handle + * @since_tizen 2.3.1 + * @param[in] handle widget Event handle + * @param[in] event Event type for widget + * @param[in] data Callback Data + * @return 0 on success, otherwise a negative error value + * @return @c EXIT_FAILURE delete this event callback from the event callback list + * @return @c EXIT_SUCCESS successfully handled, keep this callback in the event callback list + */ +typedef int (*widget_event_handler_cb)(widget_h handle, widget_event_type_e event, void *data); + +/** + * @brief Auto launch handle + * @since_tizen 2.3.1 + * @param[in] handle widget Handle + * @param[in] appid UI Application Id, which should be launched + * @param[in] data callback data + */ +typedef int (*widget_auto_launch_handler_cb)(widget_h handle, const char *appid, void *data); + +/** + * @internal + * @brief Initializes the widget system with some options. + * @details widget_init function uses environment value to initiate some configurable values. + * But some applications do not want to use the env value. + * For them, this API will give a chance to set default options using given arguments. + * @a disp is a Display object which is used to hold a connection with a display server (eg, Xorg) + * @since_tizen 2.3.1 + * @param[in] disp Display, If @a disp is @c NULL, the library will try to acquire a new connection to display server + * @param[in] prevent_overwrite Overwrite flag (when the content of an image type widget is updated, it will be overwriten (0) or not (1)) + * @param[in] event_filter If the widget_feed_mouse_event() is called again in this secs, it will be ignored and the widget_feed_mouse_event() will returns WIDGET_STATUS_ERROR_BUSY status code + * @param[in] use_thread If this value has true, the viewer library will create a new thread to communicate with master service + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_OUT_OF_MEMORY If a memory is not enough to do this operation. + * @retval #WIDGET_STATUS_ERROR_IO_ERROR If fails to access widget database. + * @see widget_fini() + * @see widget_feed_mouse_event() + */ +extern int widget_viewer_init(void *disp, int prevent_overwrite, double event_filter, int use_thread); + +/** + * @internal + * @brief Finalizes the widget system. + * @since_tizen 2.3.1 + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_SUCCES if success + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER if widget_init is not called + * @see widget_init() + */ +extern int widget_viewer_fini(void); + +/** + * @brief Notifies the status of a client ("it is paused") to the provider. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_FAULT if it failed to send state (paused) info + * @see widget_client_set_resumed() + */ +extern int widget_viewer_notify_paused_status_of_viewer(void); + +/** + * @brief Notifies the status of client ("it is resumed") to the provider. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_FAULT if it failed to send state (resumed) info + * @see widget_client_set_paused() + */ +extern int widget_viewer_notify_resumed_status_of_viewer(void); + +/** + * @internal + * @brief Adds a new widget. + * @details If the screen size is "1280x720", the below size lists are used for default. + * Or you can find the default sizes in pixel from /usr/share/data-provider-master/resolution.ini. + * Size types are defined from the libwidget-service package (widget-service.h). + * + * Normal mode widget + * 1x1=175x175, #WIDGET_SIZE_TYPE_1x1 + * 2x1=354x175, #WIDGET_SIZE_TYPE_2x1 + * 2x2=354x354, #WIDGET_SIZE_TYPE_2x2 + * 4x1=712x175, #WIDGET_SIZE_TYPE_4x1 + * 4x2=712x354, #WIDGET_SIZE_TYPE_4x2 + * 4x4=712x712, #WIDGET_SIZE_TYPE_4x4 + * + * Extended sizes + * 4x3=712x533, #WIDGET_SIZE_TYPE_4x3 + * 4x5=712x891, #WIDGET_SIZE_TYPE_4x5 + * 4x6=712x1070, #WIDGET_SIZE_TYPE_4x6 + * + * Easy mode widget + * 21x21=224x215, #WIDGET_SIZE_TYPE_EASY_1x1 + * 23x21=680x215, #WIDGET_SIZE_TYPE_EASY_3x1 + * 23x23=680x653, #WIDGET_SIZE_TYPE_EASY_3x3 + * + * Special widget + * 0x0=720x1280, #WIDGET_SIZE_TYPE_FULL + * @since_tizen 2.3.1 + * @remarks + * This is an ASYNCHRONOUS API. + * Even if you get a handle from the return value of this function, it is not a created instance. + * So you have to consider it as a not initialized handle. + * It can be initialized only after getting the return callback with "ret == #WIDGET_STATUS_ERROR_NONE" + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new widget, + * This function will returns proper error code + * If this returns @c NULL, you can get the reason of failure using get_last_result() + * @param[in] widget_id widget Id + * @param[in] content Contents that will be given to the widget instance + * @param[in] cluster Identifier to group widgets which will be decided in runtime. + * @param[in] category Identifier to group widgets declared in the manifest file by the widget application. + * @param[in] period Update period (@c WIDGET_DEFAULT_PERIOD can be used for this; this argument will be used to specify the period of updating contents of a widget) + * @param[in] type Size type (defined from libwidget-service package) + * @param[in] cb After the request is sent to the master provider, this callback will be called + * @param[in] data This data will be passed to the callback + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return handle + * @retval Handle widget handle but not yet initialized + * @retval @c NULL if it fails to create a handle + * @see widget_ret_cb + */ +extern widget_h widget_viewer_add_widget(const char *widget_id, const char *content, const char *cluster, const char *category, double period, widget_size_type_e type, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Deletes a widget (will replace widget_del). + * @since_tizen 2.3.1 + * @remarks + * This is an ASYNCHRONOUS API. + * If you call this with an uninitialized handle, the return callback will be called synchronously. + * So before returning from this function, the return callback will be called first. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new widget, + * This function will returns proper error code + * @param[in] handle Handle of a widget instance + * @param[in] type Deletion type (WIDGET_DELETE_PERMANENTLY or WIDGET_DELETE_TEMPORARY) + * @param[in] cb Return callback + * @param[in] data User data for return callback + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_BUSY Already in process + * @retval #WIDGET_STATUS_ERROR_FAULT Failed to create a request packet + * @retval #WIDGET_STATUS_ERROR_NONE Successfully sent, return callack will be called + * @see widget_ret_cb + */ +extern int widget_viewer_delete_widget(widget_h handle, widget_delete_type_e type, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Sets a widget events callback. + * @details To get the event which is pushed from the provider, Register the event callback using this API. + * The registered callback will be invoked if there are any events from the provider. + * @since_tizen 2.3.1 + * @param[in] cb Event handle + * @param[in] data User data for the event handle + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_NONE If succeed to set event handle + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_OUT_OF_MEMORY Not enough memory + * @see widget_unset_event_handler() + */ +extern int widget_viewer_add_event_handler(widget_event_handler_cb cb, void *data); + +/** + * @brief Unsets the widget event handle. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] cb Event handle + * @retval pointer Pointer of 'data' which is used with the widget_set_event_handler + * @see widget_set_event_handler() + */ +extern void *widget_viewer_remove_event_handler(widget_event_handler_cb cb); + +/** + * @internal + * @brief Registers the widget fault event handle. + * @details Argument list: event, pkgname, filename, funcname. + * @since_tizen 2.3.1 + * @param[in] cb Event handle + * @param[in] data Event handle data + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_NONE If succeed to set fault event handle + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_OUT_OF_MEMORY Not enough memory + * @see widget_unset_fault_handler() + */ +extern int widget_viewer_add_fault_handler(widget_fault_handler_cb cb, void *data); + +/** + * @brief Unsets the widget fault event handle. + * @since_tizen 2.3.1 + * * @param[in] cb Event handle + * @retval pointer Pointer of 'data' which is used with the widget_set_fault_handler + * @see widget_set_fault_handler() + */ +extern void *widget_viewer_remove_fault_handler(widget_fault_handler_cb cb); + +/** + * @internal + * @brief Activates the faulted widget. + * @details Request result will be returned via return callback. + * @since_tizen 2.3.1 + * @remarks + * This is an ASYNCHRONOUS API. + * Even though this function returns ERROR_NONE, it means that it just successfully sent a request to the provider. + * So you have to check the return callback and its "ret" argument. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new widget, + * This function will returns proper error code + * @param[in] widget_id Package name which should be activated + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_NONE Successfully sent a request + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_FAULT Failed to make a request + * @see widget_ret_cb + */ +extern int widget_viewer_activate_faulted_widget(const char *widget_id, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Resizes the widget. + * @details + * Normal mode widget size + * 1x1=175x175, WIDGET_SIZE_TYPE_1x1 + * 2x1=354x175, WIDGET_SIZE_TYPE_2x1 + * 2x2=354x354, WIDGET_SIZE_TYPE_2x2 + * 4x1=712x175, WIDGET_SIZE_TYPE_4x1 + * 4x2=712x354, WIDGET_SIZE_TYPE_4x2 + * 4x4=712x712, WIDGET_SIZE_TYPE_4x4 + * + * Extended widget size + * 4x3=712x533, WIDGET_SIZE_TYPE_4x3 + * 4x5=712x891, WIDGET_SIZE_TYPE_4x5 + * 4x6=712x1070, WIDGET_SIZE_TYPE_4x6 + * + * Easy mode widget size + * 21x21=224x215, WIDGET_SIZE_TYPE_EASY_1x1 + * 23x21=680x215, WIDGET_SIZE_TYPE_EASY_3x1 + * 23x23=680x653, WIDGET_SIZE_TYPE_EASY_3x3 + * + * Special mode widget size + * 0x0=720x1280, WIDGET_SIZE_TYPE_FULL + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @remarks + * This is an ASYNCHRONOUS API. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new widget, + * This function will returns proper error code + * @param[in] handle Handle of a widget instance + * @param[in] type Type of a widget size (e.g., WIDGET_SIZE_TYPE_1x1, ...) + * @param[in] cb Result callback of the resize operation + * @param[in] data User data for return callback + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_BUSY Previous request of resize is in progress + * @retval #WIDGET_STATUS_ERROR_ALREADY Already resized, there is no differences between current size and requested size + * @retval #WIDGET_STATUS_ERROR_PERMISSION_DENIED Permission denied, you only have view the content of this box + * @retval #WIDGET_STATUS_ERROR_FAULT Failed to make a request + * @see widget_ret_cb + */ +extern int widget_viewer_resize_widget(widget_h handle, widget_size_type_e type, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Sends the click event to a widget, This is not related with mouse_event, viewer can send "clicked" event directly. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] x Rational X of the content width + * @param[in] y Rational Y of the content height + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + */ +extern int widget_viewer_send_click_event(widget_h handle, double x, double y); + +/** + * @internal + * @brief Changes the cluster/sub-cluster name of the given widget handle. + * @since_tizen 2.3.1 + * @remarks + * This is an ASYNCHRONOUS API. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new widget, + * This function will returns proper error code + * @param[in] handle Handle of a widget instance + * @param[in] cluster New cluster of a widget + * @param[in] category New category of a widget + * @param[in] cb Result callback for changing the cluster/category of a widget + * @param[in] data User data for the result callback + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_NONE Request is successfully sent. the return callback will be called + * @retval #WIDGET_STATUS_ERROR_BUSY Previous request is not finished yet + * @retval #WIDGET_STATUS_ERROR_ALREADY Group name is same with current one + * @retval #WIDGET_STATUS_ERROR_PERMISSION_DENIED You have no permission to change property of this widget instance + * @retval #WIDGET_STATUS_ERROR_FAULT Failed to make a request + * @see widget_ret_cb + */ +extern int widget_viewer_set_group(widget_h handle, const char *cluster, const char *category, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Gets the cluster and category (sub-cluster) name of the given widget (it is not I18N format, only English). + * @since_tizen 2.3.1 + * @remarks You have to do not release the cluster & category. + * It is allocated inside of a given widget instance, so you can only read it. + * @param[in] handle Handle of a widget instance + * @param[out] cluster Storage(memory) for containing the cluster name + * @param[out] category Storage(memory) for containing the category name + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + */ +extern int widget_viewer_get_group(widget_h handle, const char **cluster, const char **category); + +/** + * @brief Gets the update period of the widget. + * @since_tizen 2.3.1 + * * @param[in] handle Handle of a widget instance + * @param[out] period Update period of the widget. + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid parameters + */ +extern int widget_viewer_get_period(widget_h handle, double *period); + +/** + * @internal + * @brief Changes the update period. + * @since_tizen 2.3.1 + * @remarks + * This is an ASYNCHRONOUS API. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new widget, + * This function will returns proper error code + * @param[in] handle Handle of a widget instance + * @param[in] period New update period of a widget + * @param[in] cb Result callback of changing the update period of this widget + * @param[in] data User data for the result callback + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_BUSY + * @retval #WIDGET_STATUS_ERROR_ALREADY + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @see widget_ret_cb + */ +extern int widget_viewer_set_period(widget_h handle, double period, widget_ret_cb cb, void *data); + +/** + * @brief Checks whether the given widget is a text type or not. + * @remarks + * If this returns WIDGET_CONTENT_TYPE_INVALID, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @return widget_type + * @retval #WIDGET_CONTENT_TYPE_IMAGE Contents of a widget is based on the image file + * @retval #WIDGET_CONTENT_TYPE_BUFFER Contents of a widget is based on canvas buffer(shared) + * @retval #WIDGET_CONTENT_TYPE_TEXT Contents of a widget is based on formatted text file + * @retval #WIDGET_CONTENT_TYPE_RESOURCE_ID Contens of a widget is shared by the resource id (depends on the Window system, eg, Xorg) + * @retval #WIDGET_CONTENT_TYPE_UIFW UI F/W supported content type for widget + * @retval #WIDGET_CONTENT_TYPE_INVALID Invalid type + * @see widget_type() + */ +extern int widget_viewer_get_type(widget_h handle, int gbar, widget_type_e *widget_type); + +/** + * @brief Checks if the given widget is created by user or not. + * @remarks if this returns negative value, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @details If the widget instance is created by a system this will return 0. + * @param[in] handle Handle of a widget instance + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval 0 Automatically created widget by the provider + * @retval 1 Created by user via widget_add() + * @see widget_add() + * @see widget_set_event_handler() + */ +extern int widget_viewer_is_created_by_user(widget_h handle); + +/** + * @internal + * @brief Gets content information string of the given widget. + * @remarks if this returns @c NULL, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @return const char * + * @retval content_info widget content info that can be used again via content_info argument of widget_add() + * @see widget_add() + */ +extern const char *widget_viewer_get_content_string(widget_h handle); + +/** + * @brief Gets the sub cluster title string of the given widget. + * @details This API is now used for accessibility. + * Each box should set their content as a string to be read by TTS. + * So if the box has focused on the homescreen, the homescreen will read text using this API. + * @since_tizen 2.3.1 + * * @remarks The title returned by this API can be read by TTS. + * But it is just recomendation for the homescreen. + * So, to read it or not depends on its implementation. + * if this returns @c NULL, you can get the reason of failure using get_last_result() + * @param[in] handle Handle of a widget instance + * @return const char * + * @retval sub Cluster name + * @retval @c NULL + */ +extern const char *widget_viewer_get_title_string(widget_h handle); + +/** + * @internal + * @brief Gets the filename of the given widget, if it is an IMAGE type widget. + * @details If the box is developed as an image format to represent its contents, the homescreen should know its image file name. + * @remarks if this returns @c NULL, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @return const char * + * @retval filename If the widget type is image this function will give you a abs-path of an image file (content is rendered) + * @retval @c NULL If this has no image file or type is not image file. + */ +extern const char *widget_viewer_get_filename(widget_h handle); + +/** + * @brief Gets the package name of the given widget handle. + * @remarks if this returns @c NULL, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * * @param[in] handle Handle of a widget instance + * @return const char * + * @retval pkgname Package name + * @retval @c NULL If the handle is not valid + */ +extern const char *widget_viewer_get_pkgname(widget_h handle); + +/** + * @brief Gets the priority of a current content. + * @remarks if this returns negative value, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * * @param[in] handle Handle of a widget instance + * @param[out] priority priority of the widget + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid parameters + */ +extern int widget_viewer_get_priority(widget_h handle, double *priority); + +/** + * @internal + * @brief Acquires the buffer of a given widget (only for the buffer type). + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @retval address Address of a Frame Buffer + * @retval @c NULL If it fails to get buffer address + */ +extern void *widget_viewer_acquire_buffer(widget_h handle, int gbar); + +/** + * @brief Releases the buffer of a widget (only for the buffer type). + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] buffer Buffer + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + * @see widget_acquire_buffer() + */ +extern int widget_viewer_release_buffer(void *buffer); + +/** + * @internal + * @brief Gets the reference count of widget buffer (only for the buffer type). + * @since_tizen 2.3.1 + * @param[in] buffer Buffer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval refcnt Positive integer value including ZERO + */ +extern int widget_viewer_get_buffer_reference_count(void *buffer); + +/** + * @brief Gets the size of the widget. + * @remarks + * If this returns WIDGET_SIZE_TYPE_UNKNOWN, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] handle Handle of a widget instance + * @return widget_size_type_e + * @retval #WIDGET_SIZE_TYPE_NxM N by M size + * @retval #WIDGET_SIZE_TYPE_UNKNOWN Invalid handle or size type is not defined yet + */ +extern int widget_viewer_get_size_type(widget_h handle, widget_size_type_e *size_type); + +/** + * @internal + * @brief Gets the size of the Glance Bar. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[out] w Width of glance bar in pixels + * @param[out] h Height of glance bar in pixels + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid parameters are used + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + */ +extern int widget_viewer_get_glance_bar_size(widget_h handle, int *w, int *h); + +/** + * @internal + * @brief Gets a list of the supported sizes of a given handle. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] size_list Array buffer for getting the size types + * @param[in] cnt size of array + * @param[out] cnt Count of returned size types + * @param[out] size_list Array of size types + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + */ +extern int widget_viewer_get_supported_sizes(widget_h handle, int *cnt, widget_size_type_e *size_list); + +/** + * @internal + * @brief Gets BUFFER SIZE of the widget if it is a buffer type. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval size Size in bytes of the widget buffer + */ +extern int widget_viewer_get_buffer_size(widget_h handle, int gbar); + +/** + * @internal + * @brief Sends a content event (for buffer type) to the provider (widget). + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] type Event type + * @param[in] x Coordinates of X axis + * @param[in] y Coordinates of Y axis + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully sent + * @see widget_feed_access_event() + * @see widget_feed_key_event() + */ +extern int widget_viewer_feed_mouse_event(widget_h handle, widget_mouse_event_type_e type, widget_mouse_event_info_s info); + +/** + * @internal + * @brief Sends an access event (for buffer type) to the provider (widget). + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] type Event type + * @param[in] x Coordinates of X axsis + * @param[in] y Coordinates of Y axsis + * @param[in] cb Result callback function + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully sent + * @see widget_feed_mouse_event() + * @see widget_feed_key_event() + */ +extern int widget_viewer_feed_access_event(widget_h handle, widget_access_event_type_e type, widget_access_event_info_s info, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Sends a key event (for buffer type) to the provider (widget). + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] type Key event type + * @param[in] keycode Code of key + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully sent + * @see widget_feed_mouse_event() + * @see widget_feed_access_event() + */ +extern int widget_viewer_feed_key_event(widget_h handle, widget_key_event_type_e type, widget_key_event_info_s info, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Sets pin-up status of the given handle. + * @details If the widget supports the pinup feature, + * you can freeze the update of the given widget. + * But it is different from pause. + * The box will be updated and it will decide wheter update its content or not when the pinup is on. + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] flag Pinup value + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid parameters + * @see widget_ret_cb + * @see widget_set_visibility() + * @see widget_is_pinned_up() + */ +extern int widget_viewer_set_pinup(widget_h handle, int flag, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Checks the PIN-UP status of the given handle. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid parameters + * @retval 1 Box is pinned up + * @retval 0 Box is not pinned up + * @see widget_set_pinup() + */ +extern int widget_viewer_is_pinned_up(widget_h handle); + +/** + * @internal + * @brief Checks the availability of the PIN-UP feature for the given handle. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval 1 If the box support Pinup feature + * @retval 0 If the box does not support the Pinup feature + * @see widget_is_pinned_up() + * @see widget_set_pinup() + */ +extern int widget_viewer_has_pinup(widget_h handle); + +/** + * @internal + * @brief Checks the existence of Glance Bar for the given handle. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval 1 If the box support the Glance Bar + * @retval 0 If the box has no Glance Bar + */ +extern int widget_viewer_has_glance_bar(widget_h handle); + +/** + * @internal + * @brief Creates Glance Bar of the given handle with the relative position from widget. + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] x 0.0 ~ 1.0 + * @param[in] y 0.0 ~ 1.0 + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @see widget_create_glance_bar() + * @see widget_destroy_glance_bar() + * @see widget_move_glance_bar() + */ +extern int widget_viewer_create_glance_bar(widget_h handle, double x, double y, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Updates a position of the given Glance Bar. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] x 0.0 ~ 1.0, 0.0 indicates the coordinate X of left of widget + * @param[in] y 0.0 ~ 1.0, 0.0 indicates the coordinate Y of top of widget + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_NONE If sending a request for updating position of the Glance Bar has been done successfully + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + */ +extern int widget_viewer_move_glance_bar(widget_h handle, double x, double y); + +/** + * @internal + * @brief Destroys the Glance Bar of the given handle if it is created. + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] cb Callback function + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + * @see widget_ret_cb + */ +extern int widget_viewer_destroy_glance_bar(widget_h handle, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Checks the create status of the given widget handle. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval 0 Glance Bar is not created + * @retval 1 Glance Bar is created + */ +extern int widget_viewer_glance_bar_is_created(widget_h handle); + +/** + * @internal + * @brief Sets a function table for parsing the text content of a widget. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @param[in] ops + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @see widget_set_gbar_text_handler() + */ +extern int widget_viewer_set_text_handler(widget_h handle, int gbar, widget_script_operator_s ops); + +/** + * @internal + * @brief Emits a text signal to the given widget only if it is a text type. + * @since_tizen 2.3.1 + * @remarks + * This is an ASYNCHRONOUS API. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new widget, + * This function will returns proper error code + * @param[in] handle Handle of a widget instance + * @param[in] signal_name Emission string + * @param[in] source Source string + * @param[in] sx Start X + * @param[in] sy Start Y + * @param[in] ex End X + * @param[in] ey End Y + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid parameters + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully emitted + * @see widget_ret_cb + */ +extern int widget_viewer_emit_text_signal(widget_h handle, widget_text_signal_s event_info, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Sets a private data pointer to carry it using the given handle. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] data Data pointer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_NONE Successfully registered + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @see widget_data() + */ +extern int widget_viewer_set_data(widget_h handle, void *data); + +/** + * @internal + * @brief Gets a private data pointer which is carried by a given handle. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @retval data Data pointer + * @retval @c NULL If there is no data + * @see widget_set_data() + */ +extern void *widget_viewer_get_data(widget_h handle); + +/** + * @internal + * @brief Subscribes an event for widgetes only in a given cluster and sub-cluster. + * @details If you wrote a view-only client, + * you can receive the event of specific widgetes which belong to a given cluster/category. + * But you cannot modify their attributes (such as size, ...). + * @since_tizen 2.3.1 + * @param[in] cluster Cluster ("*" can be used for subscribe all cluster's widgetes event; If you use the "*", value in the category will be ignored) + * @param[in] category Category ("*" can be used for subscribe widgetes events of all category(sub-cluster) in a given "cluster") + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully requested + * @see widget_unsubscribe_group() + */ +extern int widget_viewer_subscribe_group(const char *cluster, const char *sub_cluster); + +/** + * @internal + * @brief Unsubscribes an event for the widgetes, but you will receive already added widgetes events. + * @since_tizen 2.3.1 + * @param[in] cluster Cluster("*" can be used for subscribe all cluster's widgetes event; If you use the "*", value in the category will be ignored) + * @param[in] category Category ("*" can be used for subscribe all sub-cluster's widgetes event in a given "cluster") + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully requested + * @see widget_subscribe_group() + */ +extern int widget_viewer_unsubscribe_group(const char *cluster, const char *sub_cluster); + +/** + * @internal + * @brief Subscribe events of widgetes which is categorized by given "category" string. + * "category" is written in the XML file of each widget manifest file. + * After subscribe the category, the master will send created event for all created widgetes, + * Also it will notify client when a new widget is created. + * @since_tizen 2.3.1 + * @param[in] category Category name + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully requested + * @see widget_unsubscribe_category() + */ +extern int widget_viewer_subscribe_category(const char *category); + +/** + * @internal + * @brief Unsubscribe events of widgetes. + * @since_tizen 2.3.1 + * @param[in] category Category name + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully requested + * @see widget_subscribe_category() + */ +extern int widget_viewer_unsubscribe_category(const char *category); + +/** + * @internal + * @brief Refreshes the group (cluster/sub-cluser (aka. category)). + * @details This function will trigger the update of all widgetes in a given cluster/category group. + * @since_tizen 2.3.1 + * @remarks Basically, a default widget system doesn't use the cluster/category concept. + * But you can use it. So if you decide to use it, then you can trigger the update of all widgetes in the given group. + * @param[in] cluster Cluster ID + * @param[in] category Sub-cluster ID + * @param[in] force 1 if the boxes should be updated even if they are paused + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully requested + * @see widget_refresh() + */ +extern int widget_viewer_refresh_group(const char *cluster, const char *category, int force); + +/** + * @brief Refreshes a widget. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] handle Handle of a widget instance + * @param[in] force 1 if the box should be updated even if it is paused + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully requested + * @see widget_refresh_group() + */ +extern int widget_viewer_refresh(widget_h handle, int force); + +/** + * @brief Gets Resource id of a widget content. + * @details This function doesn't guarantee the life-cycle of the resource id. + * If the service provider destroyed the resource id, you will not know about it. + * So you should validate it before accessing it. + * @since_tizen 2.3.1 + * * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @param[out] resouce_id result resource id of the widget + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @see widget_get_resource_id() + */ +extern int widget_viewer_get_resource_id(const widget_h handle, int gbar, unsigned int *resouce_id); + +/** + * @internal + * @brief Gets the Resource Id of a widget. + * @details Even if a render process releases the Resource Id, the Resource Id will be kept before being released by widget_release_resource_id. + * You should release the resource id manually. + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @param[in] cb Callback function which will be called with result of acquiring widget resource id + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully requested + * @pre widget service system should support the ResourceId type buffer. + * The widget should be designed to use the buffer (or script). + * @see widget_release_resource_id() + * @see widget_ret_cb + */ +extern int widget_viewer_acquire_resource_id(widget_h handle, int gbar, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Get the Resource Id of a widget for Extra buffer + * @details Even if a render process(provider) released the Resource Id, it will be kept while release it by viewer.\n + * This will prevent from unexpected resource releasing for viewer.\n + * You should release this using widget_release_resource_id() + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @param[in] idx Index of extra buffer, it is limited to widget configuration + * @param[in] cb Callback function which will be called with result of acquiring widget resource id + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully requested + * @pre widget service system should support the resource id type buffer. + * The widget should be designed to use the buffer (or script) + * @see widget_release_resource_id() + * @see widget_ret_cb + */ +extern int widget_viewer_acquire_extra_resource_id(widget_h handle, int gbar, int idx, widget_ret_cb cb, void *data); + +/** + * @brief Releases the Resource Id of a widget. + * @details After a client gets a new Resource Id or does not need to keep the current Resource Id anymore, use this function to release it. + * If there is no user for a given Resource Id, the Resource Id will be destroyed. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @param[in] resource_id Resource Id of given widget handle + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + * @pre The Resource Id should be acquired by widget_acquire_resource_id + * @see widget_acquire_resource_id() + */ +extern int widget_viewer_release_resource_id(widget_h handle, int gbar, unsigned int resource_id); + +/** + * @brief Updates a visible state of the widget. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] handle Handle of a widget instance + * @param[in] state Configure the current visible state of a widget + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_PERMISSION_DENIED Permission denied + * @retval #WIDGET_STATUS_ERROR_ALREADY Input state is same to existing state + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + */ +extern int widget_viewer_set_visibility(widget_h handle, widget_visible_state_e state); + +/** + * @internal + * @brief Gets the current visible state of a widget. + * @remarks + * If this returns WIDGET_VISIBLE_ERROR, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @return widget_visible_state + * @retval #WIDGET_SHOW widget is shown (Default state) + * @retval #WIDGET_HIDE widget is hidden, Update timer is not frozen (but a user cannot receive any updated events; a user should refresh(reload) the content of a widget when a user make this show again) + * @retval #WIDGET_HIDE_WITH_PAUSE widget is hidden, it will pause the update timer, but if a widget updates its contents, update event will occur + * @retval #WIDGET_VISIBLE_ERROR To enlarge the size of this enumeration type + */ +extern widget_visible_state_e widget_viewer_get_visibility(widget_h handle); + +/** + * @internal + * @brief Sets an update mode of the current widget. + * @details If you set 1 for active update mode, you should get a buffer without updated event from provider. + * But if it is passive mode, you have to update content of a box when you get updated events. + * Default is Passive mode. + * @since_tizen 2.3.1 + * @remarks + * This is an ASYNCHRONOUS API. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new widget, + * This function will returns proper error code + * @param[in] handle Handle of a widget instance + * @param[in] active_update 1 means active update, 0 means passive update (default) + * @param[in] cb Result callback function + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_BUSY + * @retval #WIDGET_STATUS_ERROR_PERMISSION_DENIED + * @retval #WIDGET_STATUS_ERROR_ALREADY + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + * @see widget_ret_cb + */ +extern int widget_viewer_set_update_mode(widget_h handle, int active_update, widget_ret_cb cb, void *data); + +/** + * @internal + * @brief Checks the active update mode of the given widget. + * @remarks + * If this returns negative value, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @return 0 on success, otherwise a negative error value + * @retval 0 If passive mode + * @retval 1 If active mode or error code + */ +extern int widget_viewer_is_active_update(widget_h handle); + +/** + * @internal + * @brief Syncs manually + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_NONE If success + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid handle + * @see widget_set_manual_sync() + * @see widget_manual_sync() + */ +extern int widget_viewer_sync_buffer(widget_h handle, int gbar); + +/** + * @internal + * @brief Getting the damaged region info + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @param[out] region Readonly information for damaged area + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_NONE if success + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid handle + */ +extern int widget_viewer_get_damaged_region(widget_h handle, int gbar, const widget_damage_region_s *region); + +/** + * @internal + * @brief Gets an alternative icon of the given widget instance. + * @details If the box should be represented as a shortcut icon, this function will get the alternative icon. + * @remarks + * If this returns @c NULL, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @return const char * + * @retval address Absolute path of an alternative icon file + * @retval @c NULL widget has no alternative icon file + * @see widget_alt_name() + */ +extern const char *widget_viewer_get_alternative_icon(widget_h handle); + +/** + * @internal + * @brief Gets an alternative name of the given widget instance. + * @details If the box should be represented as a shortcut name, this function will get the alternative name. + * @remarks + * If this returns @c NULL, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @return const char * + * @retval name Alternative name of a widget + * @retval @c NULL widget has no alternative name + * @see widget_alt_icon() + */ +extern const char *widget_viewer_get_alternative_name(widget_h handle); + +/** + * @internal + * @brief Gets a lock for a frame buffer. + * @details This function should be used to prevent from rendering to the frame buffer while reading it. + * And the locking area should be short and must be released ASAP, or the render thread will be hanged. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + * @see widget_release_buffer_lock() + */ +extern int widget_viewer_acquire_buffer_lock(widget_h handle, int gbar); + +/** + * @internal + * @brief Releases a lock of the frame buffer. + * @details This function should be called ASAP after acquiring a lock of FB, or the render process will be blocked. + * @since_tizen 2.3.1 + * @param[in] handle Handle of a widget instance + * @param[in] gbar 1 for Glance Bar or 0 + * @privlevel platform + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_STATUS_ERROR_NONE Successfully done + * @see widget_acquire_buffer_lock() + */ +extern int widget_viewer_release_buffer_lock(widget_h handle, int gbar); + +/** + * @brief Sets options for controlling a widget sub-system. + * @details + * #WIDGET_OPTION_FRAME_DROP_FOR_RESIZE + * While resizing the box, viewer doesn't want to know the updated frames of an old size content anymore. + * In that case, turn this on, the provider will not send the updated event to the viewer about an old content. + * So the viewer can reduce its burden to update unnecessary frames. + * #WIDGET_OPTION_MANUAL_SYNC + * If you don't want to update frames automatically, or you want only reload the frames by your hands, (manually) + * Turn this on. + * After turnning it on, you should sync it using widget_sync_buffer(). + * #WIDGET_OPTION_SHARED_CONTENT + * If this option is turnned on, even though you create a new widget, + * if there are already added same instances that have same contents, the instance will not be created again. + * Instead of creating a new instance, a viewer will provide an old instance with a new handle. + * @since_tizen 2.3.1 + * * @param[in] option Option which will be affected by this call + * @param[in] state New value for given option + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Unknown option + * @retval #WIDGET_STATUS_ERROR_FAULT Failed to change the state of option + * @retval #WIDGET_STATUS_ERROR_NONE Successfully changed + * @see widget_get_option() + * @see widget_sync_buffer() + */ +extern int widget_viewer_set_option(widget_option_type_e option, int state); + +/** + * @internal + * @brief Gets options of a widget sub-system. + * @remarks + * If this returns negative value, you can get the reason of failure using get_last_result() + * @since_tizen 2.3.1 + * @param[in] option Type of option + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid option + * @retval #WIDGET_STATUS_ERROR_FAULT Failed to get option + * @retval >=0 Value of given option (must be >=0) + * @see widget_set_option() + */ +extern int widget_viewer_get_option(widget_option_type_e option); + +/** + * @internal + * @brief Set a handle for launching an app by auto-launch feature + * @details If a user clicks a box, which box enabled auto-launch option, the launcher_handler will be called. + * From that callback, you should launch an app using given ui-app id. + * @since_tizen 2.3.1 + * @param[in] launch_handler Handle for launching an app manually + * @param[in] data Callback data which will be given a data for launch_handler + * @return #WIDGET_STATUS_ERROR_NONE on success, + * otherwise an error code (see #WIDGET_STATUS_ERROR_XXX) on failure + * @retval #WIDGET_STATUS_ERROR_NONE Succeed to set new handle. there is no other cases + */ +extern int widget_viewer_set_auto_launch_handler(widget_auto_launch_handler_cb cb, void *data); + +/** + * @internal + * @brief Get the last extra buffer index and its id. + * @details + * If there is an event of #WIDGET_EVENT_WIDGET_EXTRA_BUFFER_CREATED or #WIDGET_EVENT_GBAR_EXTRA_BUFFER_CREATED, + * #WIDGET_EVENT_WIDGET_EXTRA_BUFFER_DESTROYED or #WIDGET_EVENT_GBAR_EXTRA_BUFFER_DESTROYED + * you can use this to get the last created buffer info + * @since_tizen 2.3.1 + * @param[in] handle widget handle + * @param[in] gbar 1 if you want get the glance bar's info or 0 + * @param[out] idx Index of buffer + * @param[out] resource_id Resource Id + * @return status + * @retval #WIDGET_STATUS_ERROR_NONE Successfully get + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Handle is not valid + * @retval #WIDGET_STATUS_ERROR_NOT_EXIST There is no extra buffer + */ +extern int widget_viewer_get_affected_extra_buffer(widget_h handle, int gbar, int *idx, unsigned int *resource_id); + +extern int widget_viewer_get_instance_id(widget_h handle, char **instance_id); + +extern int widget_viewer_notify_orientation_of_viewer(int orientation); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/widget_viewer/include/widget_viewer_internal.h b/widget_viewer/include/widget_viewer_internal.h new file mode 100644 index 0000000..379cdf7 --- /dev/null +++ b/widget_viewer/include/widget_viewer_internal.h @@ -0,0 +1,278 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 __WIDGET_VIEWER_INTERNAL_H +#define __WIDGET_VIEWER_INTERNAL_H + +#include "widget_viewer.h" +#include "widget_buffer.h" + +struct cb_info { + widget_ret_cb cb; + void *data; +}; + +extern void _widget_invoke_event_handler(struct widget *handler, widget_event_type_e event); +extern void _widget_invoke_fault_handler(widget_fault_type_e type, const char *pkgname, const char *filename, const char *function); + +extern struct widget_common *_widget_find_common_handle(const char *pkgname, const char *filename); +extern struct widget *_widget_new_widget(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category); +extern struct widget_common *_widget_find_common_handle_by_timestamp(double timestamp); + +extern int _widget_set_group(struct widget_common *common, const char *cluster, const char *category); +extern void _widget_set_size(struct widget_common *common, int w, int h); +extern void _widget_set_gbarsize(struct widget_common *common, int w, int h); +extern void _widget_set_default_gbarsize(struct widget_common *common, int w, int h); +extern int _widget_set_content(struct widget_common *common, const char *content); +extern int _widget_set_title(struct widget_common *handler, const char *title); +extern void _widget_set_auto_launch(struct widget_common *handler, const char *auto_launch); +extern void _widget_set_id(struct widget_common *handler, const char *id); +extern void _widget_set_size_list(struct widget_common *handler, int size_list); +extern void _widget_set_priority(struct widget_common *handler, double priority); +extern int _widget_set_widget_fb(struct widget_common *handler, const char *filename); +extern int _widget_set_gbar_fb(struct widget_common *handler, const char *filename); +extern struct fb_info *_widget_get_gbar_fb(struct widget_common *handler); +extern struct fb_info *_widget_get_widget_fb(struct widget_common *handler); +extern void _widget_set_user(struct widget_common *handler, int user); +extern void _widget_set_pinup(struct widget_common *handler, int pinup); +extern void _widget_set_text_widget(struct widget_common *handler); +extern void _widget_set_text_gbar(struct widget_common *handler); +extern int _widget_text_widget(struct widget_common *handler); +extern int _widget_text_gbar(struct widget_common *handler); +extern void _widget_set_period(struct widget_common *handler, double period); +extern void _widget_set_update_mode(struct widget_common *handler, int active_mode); +extern void _widget_set_filename(struct widget_common *handler, const char *filename); +extern void _widget_unlink_filename(struct widget_common *common); +extern void _widget_set_alt_icon(struct widget_common *handler, const char *icon); +extern void _widget_set_alt_name(struct widget_common *handle, const char *name); +extern int _widget_destroy_common_handle(struct widget_common *common); +extern struct widget_common *_widget_create_common_handle(struct widget *handle, const char *pkgname, const char *cluster, const char *category); +extern int _widget_sync_gbar_fb(struct widget_common *common); +extern int _widget_sync_widget_fb(struct widget_common *common); +extern int _widget_common_unref(struct widget_common *common, struct widget *handle); +extern int _widget_common_ref(struct widget_common *common, struct widget *handle); +extern struct widget_common *_widget_find_sharable_common_handle(const char *pkgname, const char *content, int w, int h, const char *cluster, const char *category); +extern struct widget *_widget_find_widget_in_show(struct widget_common *common); +extern struct widget *_widget_get_widget_nth(struct widget_common *common, int nth); +extern void *_widget_remove_event_handler(widget_event_handler_cb widget_cb); +extern int _widget_add_event_handler(widget_event_handler_cb widget_cb, void *data); +extern int _widget_add_fault_handler(widget_fault_handler_cb widget_cb, void *data); +extern void *_widget_remove_fault_handler(widget_fault_handler_cb widget_cb); +extern struct cb_info *_widget_create_cb_info(widget_ret_cb cb, void *data); +extern void _widget_destroy_cb_info(struct cb_info *info); + +extern struct widget *_widget_ref(struct widget *handler); +extern struct widget *_widget_unref(struct widget *handler, int destroy_common); +extern int _widget_send_delete(struct widget *handler, int type, widget_ret_cb cb, void *data); +extern int _widget_delete_all(void); + +typedef enum widget_state { + WIDGET_STATE_CREATE = 0xBEEFbeef, + WIDGET_STATE_DELETE = 0xDEADdead, /* Delete only for this client */ + WIDGET_STATE_DESTROYED = 0x00DEAD00 +} widget_state_e; + +struct widget_common { + widget_state_e state; + + struct dlist *widget_list; + int refcnt; + + char *cluster; + char *category; + + char *pkgname; + char *id; + + char *content; + char *title; + char *filename; + + double timestamp; + + struct alt_info { + char *icon; + char *name; + } alt; + + widget_delete_type_e delete_type; + + int is_user; + int is_gbar_created; + int is_pinned_up; + int is_active_update; + widget_visible_state_e visible; + + struct { + widget_widget_type_e type; + struct fb_info *fb; + + int size_list; + + int width; + int height; + double priority; + + char *auto_launch; + double period; + int pinup_supported; + bool mouse_event; + + /* For the filtering event */ + double x; + double y; + + /* For the extra buffer */ + unsigned int *extra_buffer; + int last_extra_buffer_idx; + + /* Lock */ + widget_lock_info_t lock; + + /* For damaged region */ + struct widget_damage_region last_damage; + } widget; + + struct { + widget_gbar_type_e type; + struct fb_info *fb; + + int width; + int height; + + int default_width; + int default_height; + + /* For the filtering event */ + double x; + double y; + + /* For the extra buffer */ + unsigned int *extra_buffer; + int last_extra_buffer_idx; + + /* Lock */ + widget_lock_info_t lock; + + /* For damaged region */ + struct widget_damage_region last_damage; + } gbar; + + int nr_of_sizes; + + struct requested_flag { + unsigned int created:1; + unsigned int deleted:1; + unsigned int pinup:1; + unsigned int group_changed:1; + unsigned int period_changed:1; + unsigned int size_changed:1; + unsigned int gbar_created:1; + unsigned int gbar_destroyed:1; + unsigned int update_mode:1; + unsigned int access_event:1; + unsigned int key_event:1; + + /*! + * \note + * Reserved + */ + unsigned int reserved:21; + } request; +}; + +struct job_item { + struct widget *handle; + widget_ret_cb cb; + int ret; + void *data; +}; + +struct widget { + widget_state_e state; + + int refcnt; + int paused_updating; + + widget_visible_state_e visible; + struct widget_common *common; + + void *data; + + struct callback_table { + struct widget_script_operators widget_ops; + struct widget_script_operators gbar_ops; + + struct created { + widget_ret_cb cb; + void *data; + } created; + + struct deleted { + widget_ret_cb cb; + void *data; + } deleted; + + struct pinup { + widget_ret_cb cb; + void *data; + } pinup; + + struct group_changed { + widget_ret_cb cb; + void *data; + } group_changed; + + struct period_changed { + widget_ret_cb cb; + void *data; + } period_changed; + + struct size_changed { + widget_ret_cb cb; + void *data; + } size_changed; + + struct gbar_created { + widget_ret_cb cb; + void *data; + } gbar_created; + + struct gbar_destroyed { + widget_ret_cb cb; + void *data; + } gbar_destroyed; + + struct update_mode { + widget_ret_cb cb; + void *data; + } update_mode; + + struct access_event { + widget_ret_cb cb; + void *data; + } access_event; + + struct key_event { + widget_ret_cb cb; + void *data; + } key_event; + } cbs; +}; + +#endif /* __WIDGET_VIEWER_INTERNAL_H */ + +/* End of a file */ diff --git a/widget_viewer/src/client.c b/widget_viewer/src/client.c new file mode 100644 index 0000000..70e7eac --- /dev/null +++ b/widget_viewer/src/client.c @@ -0,0 +1,2359 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "client.h" +#include "widget_viewer.h" +#include "widget_viewer_internal.h" +#include "desc_parser.h" +#include "fb.h" +#include "util.h" +#include "master_rpc.h" +#include "conf.h" +#include "file_service.h" +#include "dlist.h" + +int errno; + +#define MAX_DIRECT_ADDR 256 + +static struct info { + int fd; + int direct_fd; + int master_direct_fd; + guint timer_id; + char *client_addr; + char *direct_addr; +} s_info = { + .fd = -1, + .direct_fd = -1, + .master_direct_fd = -1, + .timer_id = 0, + .client_addr = NULL, + .direct_addr = NULL, +}; + +static struct packet *master_fault_package(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + const char *function; + + if (packet_get(packet, "sss", &pkgname, &id, &function) != 3) { + ErrPrint("Invalid arguments\n"); + return NULL; + } + + DbgPrint("[%s]\n", pkgname); + master_rpc_clear_fault_package(pkgname); + _widget_invoke_fault_handler(WIDGET_FAULT_DEACTIVATED, pkgname, id, function); + return NULL; +} + +static struct packet *master_hold_scroll(pid_t pid, int handle, const struct packet *packet) +{ + struct widget_common *common; + widget_h widget; + const char *pkgname; + const char *id; + int seize; + int ret; + struct dlist *l; + + ret = packet_get(packet, "ssi", &pkgname, &id, &seize); + if (ret != 3) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance(%s) is not exists\n", id); + goto out; + } + + DbgPrint("HOLD: [%s] seize(%d)\n", id, seize); + seize = seize ? WIDGET_EVENT_HOLD_SCROLL : WIDGET_EVENT_RELEASE_SCROLL; + dlist_foreach(common->widget_list, l, widget) { + _widget_invoke_event_handler(widget, seize); + } + +out: + return NULL; +} + +static struct packet *master_pinup(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + const char *content; + widget_h handler; + struct dlist *l; + struct dlist *n; + struct widget_common *common; + char *new_content; + int ret; + int status; + int pinup; + + ret = packet_get(packet, "iisss", &status, &pinup, &pkgname, &id, &content); + if (ret != 5) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance (%s) is not exists\n", id); + goto out; + } + + if (status == (int)WIDGET_ERROR_NONE) { + new_content = strdup(content); + if (new_content) { + free(common->content); + common->content = new_content; + common->is_pinned_up = pinup; + } else { + ErrPrint("Heap: %d\n", errno); + status = WIDGET_ERROR_OUT_OF_MEMORY; + } + } + + common->request.pinup = 0; + + dlist_foreach_safe(common->widget_list, l, n, handler) { + if (handler->cbs.pinup.cb) { + widget_ret_cb cb; + void *cbdata; + + /* Make sure that user can call pinup API in its result callback */ + cb = handler->cbs.pinup.cb; + cbdata = handler->cbs.pinup.data; + + handler->cbs.pinup.cb = NULL; + handler->cbs.pinup.data = NULL; + + cb(handler, status, cbdata); + } else if (status == (int)WIDGET_ERROR_NONE) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_PINUP_CHANGED); + } + } + +out: + return NULL; +} + +static struct packet *master_deleted(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + double timestamp; + widget_h handler; + struct widget_common *common; + struct dlist *l; + struct dlist *n; + int reason; + + if (packet_get(packet, "ssdi", &pkgname, &id, ×tamp, &reason) != 4) { + ErrPrint("Invalid arguemnt\n"); + goto out; + } + + DbgPrint("[%s]\n", pkgname); + common = _widget_find_common_handle_by_timestamp(timestamp); + if (!common) { + /*! + * \note + * This can be happens only if the user delete a widget + * right after create it before receive created event. + */ + goto out; + } + + /*!< Check validity of this "handler" */ + if (common->state != WIDGET_STATE_CREATE) { + if (common->state != WIDGET_STATE_DELETE) { + /*! + * \note + * This is not possible + */ + ErrPrint("Already deleted handler (%s - %s)\n", pkgname, id); + return NULL; + } + } + + common->request.deleted = 0; + /*! + * We should change the state of "common handler' before handling the callbacks. + * Because if user tries to create a new handle in the callbacks, + * find_sharable_common_handle will returns destroying object. + * Then we will get panic. + * To prevent it, we should change its state first. + */ + common->state = WIDGET_STATE_DELETE; + + dlist_foreach_safe(common->widget_list, l, n, handler) { + if (handler->cbs.created.cb) { + widget_ret_cb cb; + void *cbdata; + /*! + * \note + * + * "if (handler->id == NULL) {" + * + * The instance is not created yet. + * But the master forcely destroy it and send destroyed event to this + * without the created event. + * + * It could be destroyed when a slave has critical error(fault) + * before creating an instance successfully. + */ + if (handler->cbs.created.cb == handler->cbs.deleted.cb) { + if (handler->cbs.created.data != handler->cbs.deleted.data) { + DbgPrint("cb is same but cbdata is different (%s - %s)\n", pkgname, id); + } + + handler->cbs.deleted.cb = NULL; + handler->cbs.deleted.data = NULL; + } + + cb = handler->cbs.created.cb; + cbdata = handler->cbs.created.data; + + handler->cbs.created.cb = NULL; + handler->cbs.created.data = NULL; + + if (reason == (int)WIDGET_ERROR_NONE) { + reason = WIDGET_ERROR_CANCELED; + } + + cb(handler, reason, cbdata); + } else if (common->id) { + if (handler->cbs.deleted.cb) { + widget_ret_cb cb; + void *cbdata; + + cb = handler->cbs.deleted.cb; + cbdata = handler->cbs.deleted.data; + + handler->cbs.deleted.cb = NULL; + handler->cbs.deleted.data = NULL; + + cb(handler, reason, cbdata); + } else { + _widget_invoke_event_handler(handler, WIDGET_EVENT_DELETED); + } + } + + /* Just try to delete it, if a user didn't remove it from the live box list */ + _widget_unref(handler, 1); + } + +out: + return NULL; +} + +static struct packet *master_widget_update_begin(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + const char *pkgname; + const char *id; + const char *content; + const char *title; + const char *fbfile; + double priority; + int ret; + + ret = packet_get(packet, "ssdsss", &pkgname, &id, &priority, &content, &title, &fbfile); + if (ret != 6) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("(%s) is not created\n", id); + goto out; + } + + _widget_set_priority(common, priority); + _widget_set_content(common, content); + _widget_set_title(common, title); + + /*! + * \NOTE + * Width & Height is not changed in this case. + * If the active update is began, the size should not be changed, + * And if the size is changed, the provider should finish the updating first. + * And then begin updating again after change its size. + */ + if (_widget_get_widget_fb(common)) { + (void)_widget_set_widget_fb(common, fbfile); + + ret = _widget_sync_widget_fb(common); + + if (ret != (int)WIDGET_ERROR_NONE) { + ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret); + } else { + struct dlist *l; + dlist_foreach(common->widget_list, l, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_WIDGET_UPDATE_BEGIN); + } + } + } else { + ErrPrint("Invalid request[%s], %s\n", id, fbfile); + } + +out: + return NULL; +} + +static struct packet *master_gbar_update_begin(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + const char *pkgname; + const char *id; + const char *fbfile; + int ret; + + ret = packet_get(packet, "sss", &pkgname, &id, &fbfile); + if (ret != 2) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + if (_widget_get_gbar_fb(common)) { + (void)_widget_set_gbar_fb(common, fbfile); + + ret = _widget_sync_gbar_fb(common); + if (ret != (int)WIDGET_ERROR_NONE) { + ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret); + } else { + struct dlist *l; + dlist_foreach(common->widget_list, l, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_GBAR_UPDATE_BEGIN); + } + } + } else { + ErrPrint("Invalid request[%s], %s\n", id, fbfile); + } + +out: + return NULL; +} + +static struct packet *master_widget_update_end(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + const char *pkgname; + const char *id; + int ret; + + ret = packet_get(packet, "ss", &pkgname, &id); + if (ret != 2) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + if (_widget_get_widget_fb(common)) { + struct dlist *l; + dlist_foreach(common->widget_list, l, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_WIDGET_UPDATE_END); + } + } else { + ErrPrint("Invalid request[%s]\n", id); + } + +out: + return NULL; +} + +static struct packet *master_key_status(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + struct dlist *l; + const char *pkgname; + const char *id; + int ret; + int status; + + ret = packet_get(packet, "ssi", &pkgname, &id, &status); + if (ret != 3) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + common->request.key_event = 0; + dlist_foreach(common->widget_list, l, handler) { + if (handler->cbs.key_event.cb) { + widget_ret_cb cb; + void *cbdata; + + cb = handler->cbs.key_event.cb; + cbdata = handler->cbs.key_event.data; + + handler->cbs.key_event.cb = NULL; + handler->cbs.key_event.data = NULL; + + cb(handler, status, cbdata); + } else { + ErrPrint("Invalid event[%s]\n", id); + } + } + +out: + return NULL; +} + +static struct packet *master_request_close_gbar(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + struct dlist *l; + const char *pkgname; + const char *id; + int ret; + int reason; + + ret = packet_get(packet, "ssi", &pkgname, &id, &reason); + if (ret != 3) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + if (!common->is_gbar_created) { + DbgPrint("GBAR is not created, closing what?(%s)\n", id); + goto out; + } + + DbgPrint("Reason: %d\n", reason); + + dlist_foreach(common->widget_list, l, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_REQUEST_CLOSE_GBAR); + } +out: + return NULL; +} + +static struct packet *master_access_status(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + struct dlist *l; + const char *pkgname; + const char *id; + int ret; + int status; + + ret = packet_get(packet, "ssi", &pkgname, &id, &status); + if (ret != 3) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + common->request.access_event = 0; + dlist_foreach(common->widget_list, l, handler) { + if (handler->cbs.access_event.cb) { + widget_ret_cb cb; + void *cbdata; + + cb = handler->cbs.access_event.cb; + cbdata = handler->cbs.access_event.data; + + handler->cbs.access_event.cb = NULL; + handler->cbs.access_event.data = NULL; + + cb(handler, status, cbdata); + } + } +out: + return NULL; +} + +static struct packet *master_gbar_update_end(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + const char *pkgname; + const char *id; + int ret; + + ret = packet_get(packet, "ss", &pkgname, &id); + if (ret != 2) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + if (_widget_get_widget_fb(common)) { + struct dlist *l; + + dlist_foreach(common->widget_list, l, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_GBAR_UPDATE_END); + } + } else { + ErrPrint("Invalid request[%s]", id); + } + +out: + return NULL; +} + +static struct packet *master_extra_info(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + const char *content; + const char *title; + const char *icon; + const char *name; + double priority; + int ret; + widget_h handler; + struct widget_common *common; + struct dlist *l; + struct dlist *n; + + ret = packet_get(packet, "ssssssd", &pkgname, &id, + &content, &title, + &icon, &name, + &priority); + if (ret != 7) { + ErrPrint("Invalid parameters\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("instance(%s) is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + /*! + * \note + * Already deleted by the user. + * Don't try to notice anything with this, Just ignore all events + * Beacuse the user doesn't wants know about this anymore + */ + ErrPrint("(%s) is not exists, but updated\n", id); + goto out; + } + + _widget_set_priority(common, priority); + _widget_set_content(common, content); + _widget_set_title(common, title); + _widget_set_alt_icon(common, icon); + _widget_set_alt_name(common, name); + + dlist_foreach_safe(common->widget_list, l, n, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_EXTRA_INFO_UPDATED); + } +out: + return NULL; +} + +static struct packet *master_extra_updated(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + widget_h handler; + struct widget_common *common; + int ret; + int x; + int y; + int w; + int h; + int is_gbar; + int event_type; + int idx; + + ret = packet_get(packet, "ssiiiiii", &pkgname, &id, &is_gbar, &idx, &x, &y, &w, &h); + if (ret != 8) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("instance(%s) is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + /*! + * \note + * Already deleted by the user. + * Don't try to notice anything with this, Just ignore all events + * Beacuse the user doesn't wants know about this anymore + */ + ErrPrint("(%s) is not exists, but updated\n", id); + goto out; + } + + if (is_gbar) { + common->gbar.last_damage.x = x; + common->gbar.last_damage.y = y; + common->gbar.last_damage.w = w; + common->gbar.last_damage.h = h; + common->gbar.last_extra_buffer_idx = idx; + + event_type = WIDGET_EVENT_GBAR_EXTRA_UPDATED; + } else { + common->widget.last_damage.x = x; + common->widget.last_damage.y = y; + common->widget.last_damage.w = w; + common->widget.last_damage.h = h; + common->widget.last_extra_buffer_idx = idx; + + event_type = WIDGET_EVENT_WIDGET_EXTRA_UPDATED; + + if (conf_frame_drop_for_resizing() && common->request.size_changed) { + /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */ + DbgPrint("Discards obsoloted update event\n"); + ret = WIDGET_ERROR_RESOURCE_BUSY; + } else { + if (!conf_manual_sync()) { + ret = _widget_sync_widget_fb(common); + if (ret != (int)WIDGET_ERROR_NONE) { + ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, util_basename(util_uri_to_path(id)), ret); + } + } else { + ret = WIDGET_ERROR_NONE; + } + } + } + + if (!common->request.created && ret == (int)WIDGET_ERROR_NONE) { + struct dlist *l; + struct dlist *n; + + dlist_foreach_safe(common->widget_list, l, n, handler) { + _widget_invoke_event_handler(handler, event_type); + } + } + +out: + return NULL; +} + +static struct packet *master_widget_updated(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + const char *fbfile; + const char *safe_file; + widget_h handler; + struct widget_common *common; + int ret; + int x; + int y; + int w; + int h; + + ret = packet_get(packet, "ssssiiii", &pkgname, &id, &fbfile, &safe_file, &x, &y, &w, &h); + if (ret != 8) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("instance(%s) is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + /*! + * \note + * Already deleted by the user. + * Don't try to notice anything with this, Just ignore all events + * Beacuse the user doesn't wants know about this anymore + */ + ErrPrint("(%s) is not exists, but updated\n", id); + goto out; + } + + common->widget.last_damage.x = x; + common->widget.last_damage.y = y; + common->widget.last_damage.w = w; + common->widget.last_damage.h = h; + common->widget.last_extra_buffer_idx = WIDGET_PRIMARY_BUFFER; + _widget_set_filename(common, safe_file); + + if (_widget_text_widget(common)) { + const char *common_filename; + + common_filename = common->filename ? common->filename : util_uri_to_path(common->id); + + (void)parse_desc(common, common_filename, 0); + /*! + * \note + * DESC parser will call the "text event callback". + * Don't need to call global event callback in this case. + */ + _widget_unlink_filename(common); + goto out; + } else if (_widget_get_widget_fb(common)) { + /*! + * \todo + * replace this with "flag" instead of "callback address" + */ + if (conf_frame_drop_for_resizing() && common->request.size_changed) { + /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */ + DbgPrint("Discards obsoloted update event\n"); + ret = WIDGET_ERROR_RESOURCE_BUSY; + } else { + (void)_widget_set_widget_fb(common, fbfile); + + if (!conf_manual_sync()) { + ret = _widget_sync_widget_fb(common); + if (ret != (int)WIDGET_ERROR_NONE) { + ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, util_basename(util_uri_to_path(id)), ret); + } + } else { + ret = WIDGET_ERROR_NONE; + } + } + } else { + ret = WIDGET_ERROR_NONE; + } + + if (ret == (int)WIDGET_ERROR_NONE && !common->request.created) { + struct dlist *l; + struct dlist *n; + + dlist_foreach_safe(common->widget_list, l, n, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_WIDGET_UPDATED); + } + } + _widget_unlink_filename(common); + +out: + return NULL; +} + +static struct packet *master_gbar_created(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + const char *pkgname; + const char *id; + const char *buf_id; + struct dlist *l; + struct dlist *n; + int width; + int height; + int ret; + int status; + + ret = packet_get(packet, "sssiii", &pkgname, &id, &buf_id, &width, &height, &status); + if (ret != 6) { + ErrPrint("Invalid argument\n"); + goto out; + } + + DbgPrint("[%s]\n", pkgname); + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance(%s) is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("Instance(%s) is not created\n", id); + goto out; + } + + if (!common->request.gbar_created) { + ErrPrint("GBAR create request is canceled\n"); + goto out; + } + + common->is_gbar_created = (status == (int)WIDGET_ERROR_NONE); + common->request.gbar_created = 0; + + if (common->is_gbar_created) { + _widget_set_gbarsize(common, width, height); + if (_widget_text_gbar(common)) { + DbgPrint("Text TYPE does not need to handle this\n"); + } else { + (void)_widget_set_gbar_fb(common, buf_id); + + switch (common->gbar.type) { + case GBAR_TYPE_SCRIPT: + case GBAR_TYPE_BUFFER: + switch (fb_type(_widget_get_gbar_fb(common))) { + case WIDGET_FB_TYPE_FILE: + case WIDGET_FB_TYPE_SHM: + common->gbar.lock = widget_service_create_lock(common->id, WIDGET_TYPE_GBAR, WIDGET_LOCK_READ); + break; + case WIDGET_FB_TYPE_PIXMAP: + case WIDGET_FB_TYPE_ERROR: + default: + break; + } + break; + case GBAR_TYPE_UIFW: + case GBAR_TYPE_TEXT: + default: + break; + } + + ret = _widget_sync_gbar_fb(common); + if (ret < 0) { + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + } + } + } + + DbgPrint("PERF_WIDGET\n"); + dlist_foreach_safe(common->widget_list, l, n, handler) { + if (handler->cbs.gbar_created.cb) { + widget_ret_cb cb; + void *cbdata; + + cb = handler->cbs.gbar_created.cb; + cbdata = handler->cbs.gbar_created.data; + + handler->cbs.gbar_created.cb = NULL; + handler->cbs.gbar_created.data = NULL; + + /*! + * Before call the Callback function, + * gbar_create_cb must be reset. + * Because, in the create callback, user can call create_gbar function again. + */ + cb(handler, status, cbdata); + } else if (status == (int)WIDGET_ERROR_NONE) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_GBAR_CREATED); + } + } + +out: + return NULL; +} + +static struct packet *master_gbar_destroyed(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct dlist *l; + struct widget_common *common; + const char *pkgname; + const char *id; + int ret; + int status; + + ret = packet_get(packet, "ssi", &pkgname, &id, &status); + if (ret != 3) { + ErrPrint("Invalid argument\n"); + goto out; + } + + DbgPrint("[%s]\n", pkgname); + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance(%s) is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("Instance(%s) is not created\n", id); + goto out; + } + + if (common->is_gbar_created == 0) { + ErrPrint("GBAR is not created, event is ignored\n"); + goto out; + } + + common->is_gbar_created = 0; + common->request.gbar_destroyed = 0; + + dlist_foreach(common->widget_list, l, handler) { + if (handler->cbs.gbar_destroyed.cb) { + widget_ret_cb cb; + void *cbdata; + + cb = handler->cbs.gbar_destroyed.cb; + cbdata = handler->cbs.gbar_destroyed.data; + + handler->cbs.gbar_destroyed.cb = NULL; + handler->cbs.gbar_destroyed.data = NULL; + + /*! + * Before call the Callback function, + * gbar_destroyed_cb must be reset. + * Because, in the create callback, user can call destroy_gbar function again. + */ + cb(handler, status, cbdata); + } else if (status == (int)WIDGET_ERROR_NONE) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_GBAR_DESTROYED); + } + } + + /*! + * \note + * Lock file should be deleted after all callbacks are processed. + */ + switch (common->gbar.type) { + case GBAR_TYPE_SCRIPT: + case GBAR_TYPE_BUFFER: + switch (fb_type(_widget_get_gbar_fb(common))) { + case WIDGET_FB_TYPE_FILE: + case WIDGET_FB_TYPE_SHM: + widget_service_destroy_lock(common->gbar.lock); + common->gbar.lock = NULL; + break; + case WIDGET_FB_TYPE_PIXMAP: + case WIDGET_FB_TYPE_ERROR: + default: + break; + } + break; + case GBAR_TYPE_UIFW: + case GBAR_TYPE_TEXT: + default: + break; + } + +out: + return NULL; +} + +static struct packet *master_gbar_updated(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + const char *descfile; + const char *fbfile; + int ret; + widget_h handler; + struct widget_common *common; + struct dlist *l; + int x; + int y; + int w; + int h; + + ret = packet_get(packet, "ssssiiii", &pkgname, &id, &fbfile, &descfile, &x, &y, &w, &h); + if (ret != 8) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance(%s) is not exists\n", id); + goto out; + } + + common->gbar.last_damage.x = x; + common->gbar.last_damage.y = y; + common->gbar.last_damage.w = w; + common->gbar.last_damage.h = h; + + if (common->state != WIDGET_STATE_CREATE) { + /*! + * \note + * This handler is already deleted by the user. + * So don't try to notice anything about this anymore. + * Just ignore all events. + */ + ErrPrint("Instance(%s) is not created\n", id); + goto out; + } + + if (_widget_text_gbar(common)) { + (void)parse_desc(common, descfile, 1); + } else { + if (conf_frame_drop_for_resizing() && common->request.size_changed) { + /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */ + DbgPrint("Discards obsoloted update event\n"); + } else { + (void)_widget_set_gbar_fb(common, fbfile); + + if (!conf_manual_sync()) { + ret = _widget_sync_gbar_fb(common); + if (ret < 0) { + ErrPrint("Failed to do sync FB (%s - %s), %d\n", pkgname, util_basename(util_uri_to_path(id)), ret); + } else { + dlist_foreach(common->widget_list, l, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_GBAR_UPDATED); + } + } + } else { + dlist_foreach(common->widget_list, l, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_GBAR_UPDATED); + } + } + } + } + +out: + return NULL; +} + +static struct packet *master_gbar_extra_buffer_destroyed(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + const char *pkgname; + struct dlist *l; + struct dlist *n; + const char *id; + int pixmap; + int idx; + int ret; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "ssii", &pkgname, &id, &pixmap, &idx); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + if (idx < 0 || idx >= conf_extra_buffer_count()) { + ErrPrint("Extra buffer count is not matched\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("WIDGET(%s) is not found\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("WIDGET(%s) is not created yet\n", id); + goto out; + } + + if (!common->gbar.extra_buffer && conf_extra_buffer_count()) { + common->gbar.extra_buffer = calloc(conf_extra_buffer_count(), sizeof(*common->gbar.extra_buffer)); + if (!common->gbar.extra_buffer) { + ErrPrint("WIDGET(%s) calloc: %d\n", id, errno); + goto out; + } + } + + common->gbar.last_extra_buffer_idx = idx; + if (common->gbar.extra_buffer[idx] != pixmap) { + DbgPrint("Extra buffer Pixmap is not matched %u <> %u\n", common->widget.extra_buffer[idx], pixmap); + } + + dlist_foreach_safe(common->widget_list, l, n, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_GBAR_EXTRA_BUFFER_DESTROYED); + } +out: + return NULL; +} + +static struct packet *master_widget_extra_buffer_destroyed(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + const char *pkgname; + struct dlist *l; + struct dlist *n; + const char *id; + int idx; + int pixmap; + int ret; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "ssii", &pkgname, &id, &pixmap, &idx); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + if (idx < 0 || idx >= conf_extra_buffer_count()) { + ErrPrint("Extra buffer count is not matched\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("WIDGET(%s) is not found\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("WIDGET(%s) is not created yet\n", id); + goto out; + } + + if (!common->widget.extra_buffer && conf_extra_buffer_count()) { + common->widget.extra_buffer = calloc(conf_extra_buffer_count(), sizeof(*common->widget.extra_buffer)); + if (!common->widget.extra_buffer) { + ErrPrint("WIDGET(%s) calloc: %d\n", id, errno); + goto out; + } + } + + common->widget.last_extra_buffer_idx = idx; + if (common->widget.extra_buffer[idx] != pixmap) { + DbgPrint("Extra buffer Pixmap is not matched %u <> %u\n", common->widget.extra_buffer[idx], pixmap); + } + + dlist_foreach_safe(common->widget_list, l, n, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_WIDGET_EXTRA_BUFFER_DESTROYED); + } +out: + return NULL; +} + +static struct packet *master_widget_extra_buffer_created(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + const char *pkgname; + struct dlist *l; + struct dlist *n; + const char *id; + int idx; + int pixmap; + int ret; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "ssii", &pkgname, &id, &pixmap, &idx); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + if (idx < 0 || idx >= conf_extra_buffer_count()) { + ErrPrint("Extra buffer count is not matched\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("WIDGET(%s) is not found\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("WIDGET(%s) is not created yet\n", id); + goto out; + } + + if (!common->widget.extra_buffer && conf_extra_buffer_count()) { + common->widget.extra_buffer = calloc(conf_extra_buffer_count(), sizeof(*common->widget.extra_buffer)); + if (!common->widget.extra_buffer) { + ErrPrint("WIDGET(%s) calloc: %d\n", id, errno); + goto out; + } + } + + common->widget.last_extra_buffer_idx = idx; + common->widget.extra_buffer[idx] = pixmap; + + dlist_foreach_safe(common->widget_list, l, n, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_WIDGET_EXTRA_BUFFER_CREATED); + } +out: + return NULL; +} + +static struct packet *master_gbar_extra_buffer_created(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + const char *pkgname; + struct dlist *l; + struct dlist *n; + const char *id; + int pixmap; + int idx; + int ret; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "ssii", &pkgname, &id, &pixmap, &idx); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + if (idx < 0 || idx >= conf_extra_buffer_count()) { + ErrPrint("Extra buffer count is not matched\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("WIDGET(%s) is not found\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("WIDGET(%s) is not created yet\n", id); + goto out; + } + + if (!common->gbar.extra_buffer && conf_extra_buffer_count()) { + common->gbar.extra_buffer = calloc(conf_extra_buffer_count(), sizeof(*common->gbar.extra_buffer)); + if (!common->gbar.extra_buffer) { + ErrPrint("WIDGET(%s) calloc: %d\n", id, errno); + goto out; + } + } + + common->gbar.last_extra_buffer_idx = idx; + common->gbar.extra_buffer[idx] = pixmap; + + dlist_foreach_safe(common->widget_list, l, n, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_GBAR_EXTRA_BUFFER_CREATED); + } +out: + return NULL; +} + +static struct packet *master_update_mode(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + struct dlist *l; + struct dlist *n; + const char *pkgname; + const char *id; + int active_mode; + int status; + int ret; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "ssii", &pkgname, &id, &status, &active_mode); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("WIDGET(%s) is not found\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("WIDGET(%s) is not created yet\n", id); + goto out; + } + + if (status == (int)WIDGET_ERROR_NONE) { + _widget_set_update_mode(common, active_mode); + } + + common->request.update_mode = 0; + dlist_foreach_safe(common->widget_list, l, n, handler) { + if (handler->cbs.update_mode.cb) { + widget_ret_cb cb; + void *cbdata; + + cb = handler->cbs.update_mode.cb; + cbdata = handler->cbs.update_mode.data; + + handler->cbs.update_mode.cb = NULL; + handler->cbs.update_mode.data = NULL; + + cb(handler, status, cbdata); + } else if (status == (int)WIDGET_ERROR_NONE) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_UPDATE_MODE_CHANGED); + } + } + +out: + return NULL; +} + +static struct packet *master_size_changed(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + const char *pkgname; + const char *id; + const char *fbfile; + int status; + int ret; + int w; + int h; + int is_gbar; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "sssiiii", &pkgname, &id, &fbfile, &is_gbar, &w, &h, &status); + if (ret != 7) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("WIDGET(%s) is not found\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("WIDGET(%s) is not created yet\n", id); + goto out; + } + + common->request.size_changed = 0; + if (is_gbar) { + /*! + * \NOTE + * GBAR is not able to resized by the client. + * GBAR is only can be managed by the provider. + * So the GBAR has no private resized event handler. + * Notify it via global event handler only. + */ + if (status == (int)WIDGET_ERROR_NONE) { + struct dlist *l; + + _widget_set_gbarsize(common, w, h); + dlist_foreach(common->widget_list, l, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_GBAR_SIZE_CHANGED); + } + } else { + ErrPrint("This is not possible. GBAR Size is changed but the return value is not ZERO (%d)\n", status); + } + } else { + struct dlist *l; + struct dlist *n; + + if (status == (int)WIDGET_ERROR_NONE) { + _widget_set_size(common, w, h); + + /*! + * \NOTE + * If there is a created WIDGET FB, + * Update it too. + */ + if (_widget_get_widget_fb(common)) { + (void)_widget_set_widget_fb(common, fbfile); + + ret = _widget_sync_widget_fb(common); + if (ret < 0) { + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + } + + /* Just update the size info only. */ + } + } + + /*! + * \NOTE + * I cannot believe client. + * So I added some log before & after call the user callback. + */ + dlist_foreach_safe(common->widget_list, l, n, handler) { + if (handler->cbs.size_changed.cb) { + widget_ret_cb cb; + void *cbdata; + + cb = handler->cbs.size_changed.cb; + cbdata = handler->cbs.size_changed.data; + + handler->cbs.size_changed.cb = NULL; + handler->cbs.size_changed.data = NULL; + + cb(handler, status, cbdata); + } else if (status == (int)WIDGET_ERROR_NONE) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_WIDGET_SIZE_CHANGED); + } + } + } + +out: + return NULL; +} + +static struct packet *master_period_changed(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + struct dlist *l; + struct dlist *n; + const char *pkgname; + const char *id; + int ret; + double period; + int status; + + ret = packet_get(packet, "idss", &status, &period, &pkgname, &id); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("WIDGET(%s) is not found\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + ErrPrint("WIDGET(%s) is not created\n", id); + goto out; + } + + if (status == (int)WIDGET_ERROR_NONE) { + _widget_set_period(common, period); + } + + common->request.period_changed = 0; + + dlist_foreach_safe(common->widget_list, l, n, handler) { + if (handler->cbs.period_changed.cb) { + widget_ret_cb cb; + void *cbdata; + + cb = handler->cbs.period_changed.cb; + cbdata = handler->cbs.period_changed.data; + + handler->cbs.period_changed.cb = NULL; + handler->cbs.period_changed.data = NULL; + + cb(handler, status, cbdata); + } else if (status == (int)WIDGET_ERROR_NONE) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_PERIOD_CHANGED); + } + } + +out: + return NULL; +} + +static struct packet *master_group_changed(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + struct dlist *l; + struct dlist *n; + const char *pkgname; + const char *id; + int ret; + const char *cluster; + const char *category; + int status; + + ret = packet_get(packet, "ssiss", &pkgname, &id, &status, &cluster, &category); + if (ret != 5) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = _widget_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("WIDGET(%s) is not exists\n", id); + goto out; + } + + if (common->state != WIDGET_STATE_CREATE) { + /*! + * \note + * Do no access this handler, + * You cannot believe this handler anymore. + */ + ErrPrint("WIDGET(%s) is not created\n", id); + goto out; + } + + if (status == (int)WIDGET_ERROR_NONE) { + (void)_widget_set_group(common, cluster, category); + } + + common->request.group_changed = 0; + + dlist_foreach_safe(common->widget_list, l, n, handler) { + if (handler->cbs.group_changed.cb) { + widget_ret_cb cb; + void *cbdata; + + cb = handler->cbs.group_changed.cb; + cbdata = handler->cbs.group_changed.data; + + handler->cbs.group_changed.cb = NULL; + handler->cbs.group_changed.data = NULL; + + cb(handler, status, cbdata); + } else if (status == (int)WIDGET_ERROR_NONE) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_GROUP_CHANGED); + } + } + +out: + return NULL; +} + +static struct packet *master_update_id(pid_t pid, int handle, const struct packet *packet) +{ + int ret; + double timestamp; + const char *id; + struct widget_common *common; + + if (!packet) { + ErrPrint("Invalid packet\n"); + return NULL; + } + + ret = packet_get(packet, "ds", ×tamp, &id); + if (ret != 2) { + ErrPrint("Invalid paramter\n"); + return NULL; + } + + common = _widget_find_common_handle_by_timestamp(timestamp); + if (!common) { + ErrPrint("Handle is not found for %d\n", timestamp); + return NULL; + } + + _widget_set_id(common, id); + DbgPrint("Update ID(%s) for %lf\n", id, timestamp); + return NULL; +} + +static struct packet *master_created(pid_t pid, int handle, const struct packet *packet) +{ + widget_h handler; + struct widget_common *common; + struct dlist *l; + + int widget_w; + int widget_h; + int gbar_w; + int gbar_h; + const char *pkgname; + const char *id; + + const char *content; + const char *cluster; + const char *category; + const char *widget_fname; + const char *gbar_fname; + const char *title; + + double timestamp; + const char *auto_launch; + double priority; + int size_list; + int user; + int pinup_supported; + widget_widget_type_e widget_type; + widget_gbar_type_e gbar_type; + double period; + int is_pinned_up; + + int old_state = WIDGET_STATE_DESTROYED; + + int ret; + + ret = packet_get(packet, "dsssiiiisssssdiiiiidsi", + ×tamp, + &pkgname, &id, &content, + &widget_w, &widget_h, &gbar_w, &gbar_h, + &cluster, &category, &widget_fname, &gbar_fname, + &auto_launch, &priority, &size_list, &user, &pinup_supported, + &widget_type, &gbar_type, &period, &title, &is_pinned_up); + if (ret != 22) { + ErrPrint("Invalid argument\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + ErrPrint("[%lf] pkgname: %s, id: %s, content: %s, " + "gbar_w: %d, gbar_h: %d, widget_w: %d, widget_h: %d, " + "cluster: %s, category: %s, widget_fname: \"%s\", gbar_fname: \"%s\", " + "auto_launch: %s, priority: %lf, size_list: %d, user: %d, pinup: %d, " + "widget_type: %d, gbar_type: %d, period: %lf, title: [%s], is_pinned_up: %d\n", + timestamp, pkgname, id, content, + gbar_w, gbar_h, widget_w, widget_h, + cluster, category, widget_fname, gbar_fname, + auto_launch, priority, size_list, user, pinup_supported, + widget_type, gbar_type, period, title, is_pinned_up); + + common = _widget_find_common_handle_by_timestamp(timestamp); + if (!common) { + handler = _widget_new_widget(pkgname, id, timestamp, cluster, category); + if (!handler) { + ErrPrint("Failed to create a new widget\n"); + ret = WIDGET_ERROR_FAULT; + goto out; + } + common = handler->common; + old_state = common->state; + } else { + if (common->state != WIDGET_STATE_CREATE) { + if (common->state != WIDGET_STATE_DELETE) { + /*! + * \note + * This is not possible!!! + */ + ErrPrint("Invalid handler\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + /*! + * \note + * After get the delete states, + * call the create callback with deleted result. + */ + } + + old_state = common->state; + + if (common->id && common->request.created == 0) { + ErrPrint("Already created: timestamp[%lf] " + "pkgname[%s], id[%s] content[%s] " + "cluster[%s] category[%s] widget_fname[%s] gbar_fname[%s]\n", + timestamp, pkgname, id, + content, cluster, category, + widget_fname, gbar_fname); + + ret = WIDGET_ERROR_ALREADY_EXIST; + goto out; + } + + _widget_set_id(common, id); + } + + common->request.created = 0; + _widget_set_size(common, widget_w, widget_h); + common->widget.type = widget_type; + common->is_pinned_up = is_pinned_up; + + switch (widget_type) { + case WIDGET_TYPE_UIFW: + case WIDGET_TYPE_FILE: + break; + case WIDGET_TYPE_SCRIPT: + case WIDGET_TYPE_BUFFER: + if (!strlen(widget_fname)) { + break; + } + (void)_widget_set_widget_fb(common, widget_fname); + + /*! + * \note + * WIDGET should create the lock file from here. + * Even if the old_state == WIDGET_STATE_DELETE, + * the lock file will be deleted from deleted event callback. + */ + switch (fb_type(_widget_get_widget_fb(common))) { + case WIDGET_FB_TYPE_FILE: + case WIDGET_FB_TYPE_SHM: + common->widget.lock = widget_service_create_lock(common->id, WIDGET_TYPE_WIDGET, WIDGET_LOCK_READ); + break; + case WIDGET_FB_TYPE_PIXMAP: + case WIDGET_FB_TYPE_ERROR: + default: + break; + } + + ret = _widget_sync_widget_fb(common); + if (ret < 0) { + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + } + break; + case WIDGET_TYPE_TEXT: + _widget_set_text_widget(common); + break; + default: + break; + } + + common->gbar.type = gbar_type; + _widget_set_gbarsize(common, gbar_w, gbar_h); + _widget_set_default_gbarsize(common, gbar_w, gbar_h); + switch (gbar_type) { + case GBAR_TYPE_SCRIPT: + case GBAR_TYPE_BUFFER: + if (!strlen(gbar_fname)) { + break; + } + + _widget_set_gbar_fb(common, gbar_fname); + + ret = _widget_sync_gbar_fb(common); + if (ret < 0) { + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + } + + /*! + * \brief + * GBAR doesn't need to create the lock file from here. + * Just create it from GBAR_CREATED event. + */ + + break; + case GBAR_TYPE_TEXT: + _widget_set_text_gbar(common); + break; + case GBAR_TYPE_UIFW: + default: + break; + } + + _widget_set_priority(common, priority); + + _widget_set_size_list(common, size_list); + _widget_set_group(common, cluster, category); + + _widget_set_content(common, content); + _widget_set_title(common, title); + + _widget_set_user(common, user); + + _widget_set_auto_launch(common, auto_launch); + _widget_set_pinup(common, pinup_supported); + + _widget_set_period(common, period); + + ret = 0; + + if (common->state == WIDGET_STATE_CREATE) { + dlist_foreach(common->widget_list, l, handler) { + /*! + * \note + * These callback can change the handler->state. + * So we have to use the "old_state" which stored state before call these callbacks + */ + + if (handler->cbs.created.cb) { + widget_ret_cb cb; + void *cbdata; + + cb = handler->cbs.created.cb; + cbdata = handler->cbs.created.data; + + handler->cbs.created.cb = NULL; + handler->cbs.created.data = NULL; + + cb(handler, ret, cbdata); + } else { + _widget_invoke_event_handler(handler, WIDGET_EVENT_CREATED); + } + + /** + * If there is any updates before get this event, + * Invoke all update event forcely + */ + switch (common->widget.last_extra_buffer_idx) { + case WIDGET_UNKNOWN_BUFFER: + break; + case WIDGET_PRIMARY_BUFFER: + DbgPrint("Primary buffer updated\n"); + _widget_invoke_event_handler(handler, WIDGET_EVENT_WIDGET_UPDATED); + break; + default: + DbgPrint("Extra buffer updated\n"); + _widget_invoke_event_handler(handler, WIDGET_EVENT_WIDGET_EXTRA_UPDATED); + break; + } + } + } + +out: + if (ret == 0 && old_state == WIDGET_STATE_DELETE) { + struct dlist *n; + + DbgPrint("Take place an unexpected case [%d]\n", common->refcnt); + dlist_foreach_safe(common->widget_list, l, n, handler) { + if (handler->cbs.created.cb) { + if (!handler->common->request.deleted) { + if (_widget_send_delete(handler, common->delete_type, handler->cbs.created.cb, handler->cbs.created.data) < 0) { + /*! + * \note + * Already sent or something else happens. + * Callback will be called in any cases + */ + } + } else if (handler->state != WIDGET_STATE_DELETE) { + handler->cbs.created.cb(handler, WIDGET_ERROR_CANCELED, handler->cbs.created.data); + _widget_unref(handler, 1); + } + } else { + _widget_invoke_event_handler(handler, WIDGET_EVENT_DELETED); + _widget_unref(handler, 1); + } + } + + /*! + * \note + * handler->cbs.created.cb = NULL; + * handler->cbs.created.data = NULL; + * + * Do not clear this to use this from the deleted event callback. + * if this value is not cleared when the deleted event callback check it, + * it means that the created function is not called yet. + * Then the call the deleted event callback with WIDGET_ERROR_CANCELED errno. + */ + } + + return NULL; +} + +static struct method s_direct_table[] = { + { + .cmd = CMD_STR_WIDGET_UPDATED, /* pkgname, id, lb_w, lb_h, priority, ret */ + .handler = master_widget_updated, + }, + { + .cmd = CMD_STR_GBAR_UPDATED, /* pkgname, id, descfile, pd_w, pd_h, ret */ + .handler = master_gbar_updated, + }, + { + .cmd = CMD_STR_EXTRA_UPDATED, + .handler = master_extra_updated, + }, + { + .cmd = NULL, + .handler = NULL, + }, +}; + +static struct method s_table[] = { + { /* WIDGET_UPDATED */ + .cmd = CMD_STR_WIDGET_UPDATED, /* pkgname, id, widget_w, widget_h, priority, ret */ + .handler = master_widget_updated, + }, + { /* GBAR_UPDATED */ + .cmd = CMD_STR_GBAR_UPDATED, /* pkgname, id, descfile, pd_w, pd_h, ret */ + .handler = master_gbar_updated, + }, + { /* EXTRA_UPDATED */ + .cmd = CMD_STR_EXTRA_UPDATED, + .handler = master_extra_updated, + }, + { /* EXTRA_INFO */ + .cmd = CMD_STR_EXTRA_INFO, + .handler = master_extra_info, + }, + { /* DELETED */ + .cmd = CMD_STR_DELETED, /* pkgname, id, timestamp, ret */ + .handler = master_deleted, + }, + { /* FAULTED */ + .cmd = CMD_STR_FAULT_PACKAGE, /* pkgname, id, function, ret */ + .handler = master_fault_package, + }, + { /* SCROLL */ + .cmd = CMD_STR_SCROLL, + .handler = master_hold_scroll, + }, + { /* WIDGET_UPDATE_BEGIN */ + .cmd = CMD_STR_WIDGET_UPDATE_BEGIN, + .handler = master_widget_update_begin, + }, + { /* WIDGET_UPDATE_END */ + .cmd = CMD_STR_WIDGET_UPDATE_END, + .handler = master_widget_update_end, + }, + { /* GBAR_UPDATE_BEGIN */ + .cmd = CMD_STR_GBAR_UPDATE_BEGIN, + .handler = master_gbar_update_begin, + }, + { /* GBAR_UPDATE_END */ + .cmd = CMD_STR_GBAR_UPDATE_END, + .handler = master_gbar_update_end, + }, + { /* ACCESS_STATUS */ + .cmd = CMD_STR_ACCESS_STATUS, + .handler = master_access_status, + }, + { /* KEY_STATUS */ + .cmd = CMD_STR_KEY_STATUS, + .handler = master_key_status, + }, + { /* CLOSE_GBAR */ + .cmd = CMD_STR_CLOSE_GBAR, + .handler = master_request_close_gbar, + }, + { /* GBAR_CREATED */ + .cmd = CMD_STR_GBAR_CREATED, + .handler = master_gbar_created, + }, + { /* GBAR_DESTROYED */ + .cmd = CMD_STR_GBAR_DESTROYED, + .handler = master_gbar_destroyed, + }, + { /* CREATED */ + .cmd = CMD_STR_CREATED, + .handler = master_created, + }, + { /* GROUP_CHANGED */ + .cmd = CMD_STR_GROUP_CHANGED, + .handler = master_group_changed, + }, + { /* PERIOD_CHANGED */ + .cmd = CMD_STR_PERIOD_CHANGED, + .handler = master_period_changed, + }, + { /* SIZE_CHANGED */ + .cmd = CMD_STR_SIZE_CHANGED, + .handler = master_size_changed, + }, + { /* PINUP */ + .cmd = CMD_STR_PINUP, + .handler = master_pinup, + }, + { /* UPDATE_MODE */ + .cmd = CMD_STR_UPDATE_MODE, + .handler = master_update_mode, + }, + { /* WIDGET_CREATE_XBUF */ + .cmd = CMD_STR_WIDGET_CREATE_XBUF, + .handler = master_widget_extra_buffer_created, + }, + { /* GBAR_CREATE_XBUF */ + .cmd = CMD_STR_GBAR_CREATE_XBUF, + .handler = master_gbar_extra_buffer_created, + }, + { /* WIDGET_DESTROY_XBUF */ + .cmd = CMD_STR_WIDGET_DESTROY_XBUF, + .handler = master_widget_extra_buffer_destroyed, + }, + { /* GBAR_DESTROY_XBUF */ + .cmd = CMD_STR_GBAR_DESTROY_XBUF, + .handler = master_gbar_extra_buffer_destroyed, + }, + { /* UPDATE_ID */ + .cmd = CMD_STR_UPDATE_ID, + .handler = master_update_id, + }, + { + .cmd = NULL, + .handler = NULL, + }, +}; + +static void make_direct_connection(void) +{ + struct packet *packet; + int ret; + + s_info.master_direct_fd = com_core_packet_client_init(SHARED_SOCKET, 0, s_direct_table); + if (s_info.master_direct_fd < 0) { + ErrPrint("Failed to create a connection\n"); + return; + } + + packet = packet_create_noack(CMD_STR_DIRECT_HELLO, "s", client_direct_addr()); + if (!packet) { + ErrPrint("Packet is not valid\n"); + return; + } + + ret = com_core_packet_send_only(s_info.master_direct_fd, packet); + packet_destroy(packet); + + DbgPrint("Direct connection request is sent: %d\n", ret); +} + +static void acquire_cb(widget_h handler, const struct packet *result, void *data) +{ + if (!result) { + DbgPrint("Result packet is not valid\n"); + } else { + int ret; + int extra_buffer_count; + + if (packet_get(result, "ii", &ret, &extra_buffer_count) != 2) { + ErrPrint("Invalid argument\n"); + } else { + DbgPrint("Acquire returns: %d (%d)\n", ret, extra_buffer_count); + conf_set_extra_buffer_count(extra_buffer_count); + /** + * Now the master has client object. + * We can make a direct connection handler from now. + */ + make_direct_connection(); + } + } + + return; +} + +static void prepare_direct_update(void) +{ + char path[MAX_DIRECT_ADDR]; + + if (!conf_direct_update()) { + return; + } + + if (s_info.direct_addr) { + DbgPrint("Direct path is already initiated: %s\n", s_info.direct_addr); + return; + } + + if (!strncmp(s_info.client_addr, COM_CORE_REMOTE_SCHEME, strlen(COM_CORE_REMOTE_SCHEME))) { + ErrPrint("Remote model is not support this\n"); + return; + } + + snprintf(path, sizeof(path) - 1, "%s/.%d.%lf.widget.viewer", WIDGET_CONF_IMAGE_PATH, getpid(), util_timestamp()); + + s_info.direct_addr = strdup(path); + if (!s_info.direct_addr) { + ErrPrint("strdup: %d\n", errno); + return; + } + + s_info.direct_fd = com_core_packet_server_init(client_direct_addr(), s_direct_table); + if (s_info.direct_fd < 0) { + ErrPrint("Failed to prepare server: %s\n", client_direct_addr()); + free(s_info.direct_addr); + s_info.direct_addr = NULL; + return; + } + + DbgPrint("Direct update is prepared: %s - %d\n", client_direct_addr(), client_direct_fd()); +} + +static inline int make_connection(void) +{ + struct packet *packet; + unsigned int cmd = CMD_ACQUIRE; + int ret; + + /** + * @note + * Before creating a connection with master, + * Initiate the private channel for getting the updated event from providers + * And this channel should be created after the master is launched. + * Or the master will delete all files in the shared folder. + */ + prepare_direct_update(); + + DbgPrint("Let's making connection!\n"); + + s_info.fd = com_core_packet_client_init(client_addr(), 0, s_table); + if (s_info.fd < 0) { + ErrPrint("Try this again later\n"); + return WIDGET_ERROR_IO_ERROR; + } + + packet = packet_create((const char *)&cmd, "ds", util_timestamp(), client_direct_addr()); + if (!packet) { + com_core_packet_client_fini(s_info.fd); + s_info.fd = -1; + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_async_request(NULL, packet, 1, acquire_cb, NULL); + if (ret < 0) { + ErrPrint("Master RPC returns %d\n", ret); + com_core_packet_client_fini(s_info.fd); + s_info.fd = -1; + return WIDGET_ERROR_IO_ERROR; + } + + return WIDGET_ERROR_NONE; +} + +static int connected_cb(int handle, void *data) +{ + if (s_info.fd == handle) { + master_rpc_check_and_fire_consumer(); + } + return 0; +} + +static void master_started_cb(keynode_t *node, void *data) +{ + int state = 0; + + if (vconf_get_bool(VCONFKEY_MASTER_STARTED, &state) < 0) { + ErrPrint("Unable to get [%s]\n", VCONFKEY_MASTER_STARTED); + } + + DbgPrint("Master state: %d\n", state); + if (state == 1 && make_connection() == (int)WIDGET_ERROR_NONE) { + int ret; + ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb); + if (ret < 0) { + DbgPrint("master_started vconf key de-registered [%d]\n", ret); + } + } +} + +static gboolean timeout_cb(gpointer data) +{ + if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) { + ErrPrint("Failed to add vconf for monitoring service state\n"); + } else { + DbgPrint("vconf event callback is registered\n"); + } + + master_started_cb(NULL, NULL); + + s_info.timer_id = 0; + return FALSE; +} + +static int disconnected_cb(int handle, void *data) +{ + if (s_info.fd != handle) { + /*!< This handle is not my favor */ + return 0; + } + + s_info.fd = -1; /*!< Disconnected */ + + master_rpc_clear_all_request(); + _widget_invoke_fault_handler(WIDGET_FAULT_PROVIDER_DISCONNECTED, MASTER_PKGNAME, "default", "disconnected"); + + _widget_delete_all(); + + /* Try to reconnect after 1 sec later */ + if (!s_info.timer_id) { + DbgPrint("Reconnecting timer is added\n"); + s_info.timer_id = g_timeout_add(1000, timeout_cb, NULL); + if (s_info.timer_id == 0) { + ErrPrint("Unable to add reconnecting timer\n"); + return 0; + } + } else { + ErrPrint("Reconnecting timer is already exists\n"); + } + + return 0; +} + +int client_init(int use_thread) +{ + widget_conf_init(); + + com_core_packet_use_thread(use_thread); + + s_info.client_addr = vconf_get_str(VCONFKEY_MASTER_CLIENT_ADDR); + if (!s_info.client_addr) { + s_info.client_addr = strdup(CLIENT_SOCKET); + if (!s_info.client_addr) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + } + + (void)file_service_init(); + + DbgPrint("Server Address: %s\n", s_info.client_addr); + + com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL); + com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL); + + if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) { + ErrPrint("Failed to add vconf for service state\n"); + } else { + DbgPrint("vconf event callback is registered\n"); + } + + master_started_cb(NULL, NULL); + return WIDGET_ERROR_NONE; +} + +int client_fd(void) +{ + return s_info.fd; +} + +const char *client_addr(void) +{ + return s_info.client_addr; +} + +const char *client_direct_addr(void) +{ + return s_info.direct_addr; +} + +int client_direct_fd(void) +{ + return s_info.direct_fd; +} + +int client_fini(void) +{ + int ret; + + (void)file_service_fini(); + + ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb); + if (ret < 0) { + DbgPrint("Ignore vconf key: %d\n", ret); + } + + com_core_del_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL); + com_core_del_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL); + + if (s_info.fd >= 0) { + com_core_packet_client_fini(s_info.fd); + s_info.fd = -1; + } + + if (s_info.master_direct_fd >= 0) { + com_core_packet_client_fini(s_info.master_direct_fd); + s_info.master_direct_fd = -1; + } + + if (s_info.direct_fd >= 0) { + com_core_packet_server_fini(s_info.direct_fd); + s_info.direct_fd = -1; + } + + if (s_info.timer_id > 0) { + g_source_remove(s_info.timer_id); + s_info.timer_id = 0; + } + + free(s_info.client_addr); + s_info.client_addr = NULL; + + free(s_info.direct_addr); + s_info.direct_addr = NULL; + + widget_conf_reset(); + return WIDGET_ERROR_NONE; +} + +/* End of a file */ diff --git a/widget_viewer/src/conf.c b/widget_viewer/src/conf.c new file mode 100644 index 0000000..fce80d3 --- /dev/null +++ b/widget_viewer/src/conf.c @@ -0,0 +1,82 @@ +#include +#include + +static struct info { + int manual_sync; + int frame_drop_for_resizing; + int shared_content; + int direct_update; + int extra_buffer_count; + + double event_filter; +} s_info = { + .manual_sync = 0, + .frame_drop_for_resizing = 1, + .shared_content = 0, + .direct_update = 0, + .extra_buffer_count = 0, + + .event_filter = 0.01f, +}; + +void conf_set_direct_update(int flag) +{ + s_info.direct_update = flag; +} + +int conf_direct_update(void) +{ + return s_info.direct_update; +} + +void conf_set_manual_sync(int flag) +{ + s_info.manual_sync = flag; +} + +int conf_manual_sync(void) +{ + return s_info.manual_sync; +} + +void conf_set_frame_drop_for_resizing(int flag) +{ + s_info.frame_drop_for_resizing = flag; +} + +int conf_frame_drop_for_resizing(void) +{ + return s_info.frame_drop_for_resizing; +} + +void conf_set_shared_content(int flag) +{ + s_info.shared_content = flag; +} + +int conf_shared_content(void) +{ + return s_info.shared_content; +} + +double conf_event_filter(void) +{ + return s_info.event_filter; +} + +void conf_set_event_filter(double filter) +{ + s_info.event_filter = filter; +} + +void conf_set_extra_buffer_count(int buffer_count) +{ + s_info.extra_buffer_count = buffer_count; +} + +int conf_extra_buffer_count(void) +{ + return s_info.extra_buffer_count; +} + +/* End of a file */ diff --git a/widget_viewer/src/desc_parser.c b/widget_viewer/src/desc_parser.c new file mode 100644 index 0000000..de8f283 --- /dev/null +++ b/widget_viewer/src/desc_parser.c @@ -0,0 +1,701 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 /* malloc */ +#include /* strdup */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "widget_viewer.h" +#include "widget_viewer_internal.h" +#include "desc_parser.h" +#include "dlist.h" +#include "util.h" + +#define INFO_SIZE "size" +#define INFO_CATEGORY "category" + +static const char *type_list[] = { + "access", + "access,operation", + "color", + "drag", + "image", + "info", + "script", + "signal", + "text", + NULL +}; + +static const char *field_list[] = { + "type", + "part", + "data", + "option", + "id", + "target", + "file", + NULL +}; + +enum block_type { + TYPE_ACCESS, + TYPE_ACCESS_OP, + TYPE_COLOR, + TYPE_DRAG, + TYPE_IMAGE, + TYPE_INFO, + TYPE_SCRIPT, + TYPE_SIGNAL, + TYPE_TEXT, + TYPE_MAX +}; + +enum field_type { + FIELD_TYPE, + FIELD_PART, + FIELD_DATA, + FIELD_OPTION, + FIELD_ID, + FIELD_TARGET, + FIELD_FILE +}; + +struct block { + enum block_type type; + char *part; + char *data; + char *option; + char *id; + char *target; + char *file; + + /* Should be released */ + char *filebuf; + const char *filename; +}; + +static int update_text(widget_h handle, struct block *block, int is_gbar) +{ + struct widget_script_operators *ops; + + if (!block || !block->part || !block->data) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.widget_ops; + if (ops->update_text) { + ops->update_text(handle, (const char *)block->id, (const char *)block->part, (const char *)block->data); + } + + return 0; +} + +static int update_image(widget_h handle, struct block *block, int is_gbar) +{ + struct widget_script_operators *ops; + + if (!block || !block->part) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.widget_ops; + if (ops->update_image) { + ops->update_image(handle, block->id, block->part, block->data, block->option); + } + + return 0; +} + +static int update_script(widget_h handle, struct block *block, int is_gbar) +{ + struct widget_script_operators *ops; + + if (!block || !block->part) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.widget_ops; + if (ops->update_script) { + ops->update_script(handle, block->id, block->target, block->part, block->data, block->option); + } + + return 0; +} + +static int update_signal(widget_h handle, struct block *block, int is_gbar) +{ + struct widget_script_operators *ops; + + if (!block) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.widget_ops; + if (ops->update_signal) { + ops->update_signal(handle, block->id, block->data, block->part); + } + + return 0; +} + +static int update_drag(widget_h handle, struct block *block, int is_gbar) +{ + double dx, dy; + struct widget_script_operators *ops; + + if (!block || !block->data || !block->part) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) { + ErrPrint("Invalid format of data\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.widget_ops; + if (ops->update_drag) { + ops->update_drag(handle, block->id, block->part, dx, dy); + } + + return 0; +} + +static int update_info(widget_h handle, struct block *block, int is_gbar) +{ + struct widget_script_operators *ops; + + if (!block || !block->part || !block->data) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.widget_ops; + if (!strcasecmp(block->part, INFO_SIZE)) { + int w, h; + + if (sscanf(block->data, "%dx%d", &w, &h) != 2) { + ErrPrint("Invalid format (%s)\n", block->data); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (ops->update_info_size) { + ops->update_info_size(handle, block->id, w, h); + } + } else if (!strcasecmp(block->part, INFO_CATEGORY)) { + if (ops->update_info_category) { + ops->update_info_category(handle, block->id, block->data); + } + } + + return 0; +} + +static int update_access(widget_h handle, struct block *block, int is_gbar) +{ + struct widget_script_operators *ops; + + if (!block) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.widget_ops; + if (ops->update_access) { + ops->update_access(handle, block->id, block->part, block->data, block->option); + } + + return 0; +} + +static int operate_access(widget_h handle, struct block *block, int is_gbar) +{ + struct widget_script_operators *ops; + + if (!block) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.widget_ops; + if (ops->operate_access) { + ops->operate_access(handle, block->id, block->part, block->data, block->option); + } + + return 0; +} + +static int update_color(widget_h handle, struct block *block, int is_gbar) +{ + struct widget_script_operators *ops; + + if (!block) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.widget_ops; + if (ops->update_color) { + ops->update_color(handle, block->id, block->part, block->data); + } + + return 0; +} + +static inline int update_begin(widget_h handle, int is_gbar) +{ + struct widget_script_operators *ops; + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.widget_ops; + if (ops->update_begin) { + ops->update_begin(handle); + } + + return 0; +} + +static inline int update_end(widget_h handle, int is_gbar) +{ + struct widget_script_operators *ops; + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.widget_ops; + if (ops->update_end) { + ops->update_end(handle); + } + + return 0; +} + +static inline void delete_block(struct block *block) +{ + free(block->filebuf); + free(block); +} + +static inline void consuming_parsed_block(widget_h handle, int is_gbar, struct block *block) +{ + typedef int (*update_function_t)(widget_h handle, struct block *block, int is_gbar); + static update_function_t updators[] = { + update_access, + operate_access, + update_color, + update_drag, + update_image, + update_info, + update_script, + update_signal, + update_text, + NULL + }; + + if (block->type >= 0 || block->type < TYPE_MAX) { + (void)updators[block->type](handle, block, is_gbar); + } else { + ErrPrint("Block type[%d] is not valid\n", block->type); + } +} + +static inline char *load_file(const char *filename) +{ + char *filebuf = NULL; + int fd; + off_t filesize; + int ret; + size_t readsize = 0; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + ErrPrint("open: %d (%s)\n", errno, filename); + return NULL; + } + + filesize = lseek(fd, 0L, SEEK_END); + if (filesize == (off_t)-1) { + ErrPrint("lseek: %d\n", errno); + goto errout; + } + + if (lseek(fd, 0L, SEEK_SET) < 0) { + ErrPrint("lseek: %d\n", errno); + goto errout; + } + + filebuf = malloc(filesize + 1); + if (!filebuf) { + ErrPrint("malloc: %d\n", errno); + goto errout; + } + + while (readsize < filesize) { + ret = read(fd, filebuf + readsize, (size_t)filesize - readsize); + if (ret < 0) { + if (errno == EINTR) { + DbgPrint("Read is interrupted\n"); + continue; + } + + ErrPrint("read: %d\n", errno); + free(filebuf); + filebuf = NULL; + break; + } + + readsize += ret; + } + + if (filebuf) { + filebuf[readsize] = '\0'; + } + + /*! + * \note + * Now, we are ready to parse the filebuf. + */ + +errout: + if (close(fd) < 0) { + ErrPrint("close: %d\n", errno); + } + + return filebuf; +} + +int parse_desc(struct widget_common *common, const char *filename, int is_gbar) +{ + int type_idx = 0; + int type_len = 0; + int field_idx = 0; + int field_len = 0; + char *filebuf; + char *fileptr; + char *ptr = NULL; + struct block *block = NULL; + struct dlist *block_list = NULL; + struct dlist *l; + struct dlist *n; + struct dlist *handle_iterator; + widget_h handler; + enum state { + BEGIN, + FIELD, + DATA, + END, + DONE, + ERROR, + } state; + + filebuf = load_file(filename); + if (!filebuf) { + return WIDGET_ERROR_IO_ERROR; + } + + fileptr = filebuf; + + state = BEGIN; + while (*fileptr && state != ERROR) { + switch (state) { + case BEGIN: + if (*fileptr == '{') { + if (block) + free(block); + block = calloc(1, sizeof(*block)); + if (!block) { + ErrPrint("calloc: %d\n", errno); + state = ERROR; + continue; + } + state = FIELD; + ptr = NULL; + } + break; + case FIELD: + if (isspace(*fileptr)) { + if (ptr != NULL) { + *fileptr = '\0'; + } + } else if (*fileptr == '=') { + *fileptr = '\0'; + ptr = NULL; + state = DATA; + } else if (ptr == NULL) { + ptr = fileptr; + field_idx = 0; + field_len = 0; + + while (field_list[field_idx]) { + if (field_list[field_idx][field_len] == *fileptr) { + break; + } + field_idx++; + } + + if (!field_list[field_idx]) { + ErrPrint("Invalid field\n"); + state = ERROR; + continue; + } + + field_len++; + } else { + if (field_list[field_idx][field_len] != *fileptr) { + field_idx++; + while (field_list[field_idx]) { + if (!strncmp(field_list[field_idx], fileptr - field_len, field_len)) { + break; + } else { + field_idx++; + } + } + + if (!field_list[field_idx]) { + state = ERROR; + ErrPrint("field is not valid\n"); + continue; + } + } + + field_len++; + } + break; + case DATA: + switch (field_idx) { + case FIELD_TYPE: + if (ptr == NULL) { + if (isspace(*fileptr)) { + break; + } + + if (*fileptr == '\0') { + state = ERROR; + ErrPrint("Type is not valid\n"); + continue; + } + + ptr = fileptr; + type_idx = 0; + type_len = 0; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (type_list[type_idx][type_len] != *fileptr) { + type_idx++; + while (type_list[type_idx]) { + if (!strncmp(type_list[type_idx], fileptr - type_len, type_len)) { + break; + } else { + type_idx++; + } + } + + if (!type_list[type_idx]) { + state = ERROR; + ErrPrint("type is not valid (%s)\n", fileptr - type_len); + continue; + } + } + + if (!*fileptr) { + block->type = type_idx; + state = DONE; + ptr = NULL; + } + + type_len++; + break; + case FIELD_PART: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->part = ptr; + state = DONE; + ptr = NULL; + } + break; + case FIELD_DATA: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->data = ptr; + state = DONE; + ptr = NULL; + } + break; + case FIELD_OPTION: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->option = ptr; + state = DONE; + ptr = NULL; + } + break; + case FIELD_ID: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->id = ptr; + state = DONE; + ptr = NULL; + } + break; + case FIELD_TARGET: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->target = ptr; + state = DONE; + ptr = NULL; + } + break; + case FIELD_FILE: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->target = ptr; + state = DONE; + ptr = NULL; + } + default: + break; + } + + break; + case DONE: + if (isspace(*fileptr)) { + } else if (*fileptr == '}') { + state = BEGIN; + block->filename = filename; + block_list = dlist_append(block_list, block); + block = NULL; + } else { + state = FIELD; + continue; + } + break; + case END: + default: + break; + } + + fileptr++; + } + + if (state != BEGIN) { + struct dlist *l; + struct dlist *n; + ErrPrint("State %d\n", state); + + free(filebuf); + free(block); + + dlist_foreach_safe(block_list, l, n, block) { + free(block); + block_list = dlist_remove(block_list, l); + } + + return WIDGET_ERROR_FAULT; + } + + + block = dlist_data(dlist_prev(block_list)); + if (block) { + block->filebuf = filebuf; + } else { + ErrPrint("Last block is not exists (There is no parsed block)\n"); + free(filebuf); + } + + ErrPrint("Begin: Set content for object\n"); + dlist_foreach(common->widget_list, l, handler) { + update_begin(handler, is_gbar); + } + + dlist_foreach_safe(block_list, l, n, block) { + dlist_foreach(common->widget_list, handle_iterator, handler) { + consuming_parsed_block(handler, is_gbar, block); + } + + block_list = dlist_remove(block_list, l); + delete_block(block); + } + + dlist_foreach(common->widget_list, l, handler) { + update_end(handler, is_gbar); + } + ErrPrint("End: Set content for object\n"); + + return WIDGET_ERROR_NONE; +} + +/* End of a file */ diff --git a/widget_viewer/src/dlist.c b/widget_viewer/src/dlist.c new file mode 100644 index 0000000..5b48b86 --- /dev/null +++ b/widget_viewer/src/dlist.c @@ -0,0 +1,189 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "dlist.h" + +/*! + * \brief + * This dlist is called Modified Doubly Linked List. + * + * Noramlly, The dobule linked list contains address of previous and next element. + * This dlist also contains them, but the tail element only contains prev address. + * + * The head element's prev pointer indicates the last element. + * But the last element's next pointer indicates NIL. + * + * So we can find the last element while crawling this DList + * But we have to remember the address of the head element. + */ + +struct dlist { + struct dlist *next; + struct dlist *prev; + void *data; +}; + +struct dlist *dlist_append(struct dlist *list, void *data) +{ + struct dlist *item; + + item = malloc(sizeof(*item)); + if (!item) { + return NULL; + } + + item->next = NULL; + item->data = data; + + if (!list) { + item->prev = item; + + list = item; + } else { + item->prev = list->prev; + item->prev->next = item; + list->prev = item; + } + + assert(!list->prev->next && "item NEXT"); + + return list; +} + +struct dlist *dlist_prepend(struct dlist *list, void *data) +{ + struct dlist *item; + + item = malloc(sizeof(*item)); + if (!item) { + return NULL; + } + + item->data = data; + + if (!list) { + item->prev = item; + item->next = NULL; + } else { + if (list->prev->next) { + list->prev->next = item; + } + + item->prev = list->prev; + item->next = list; + + list->prev = item; + + } + + return item; +} + +struct dlist *dlist_remove(struct dlist *list, struct dlist *l) +{ + if (!list || !l) { + return NULL; + } + + if (l == list) { + list = l->next; + } else { + l->prev->next = l->next; + } + + if (l->next) { + l->next->prev = l->prev; + } + /*! + * \note + * If the removed entry 'l' has no next element, it is the last element. + * In this case, check the existence of the list first, + * and if the list is not empty, update the 'prev' of the list (which is a head element of the list) + * + * If we didn't care about this, the head element(list) can indicates the invalid element. + */ + else if (list) { + list->prev = l->prev; + } + + free(l); + return list; +} + +struct dlist *dlist_find_data(struct dlist *list, void *data) +{ + struct dlist *l; + void *_data; + + dlist_foreach(list, l, _data) { + if (data == _data) { + return l; + } + } + + return NULL; +} + +void *dlist_data(struct dlist *l) +{ + return l ? l->data : NULL; +} + +struct dlist *dlist_next(struct dlist *l) +{ + return l ? l->next : NULL; +} + +struct dlist *dlist_prev(struct dlist *l) +{ + return l ? l->prev : NULL; +} + +int dlist_count(struct dlist *l) +{ + register int i; + struct dlist *n; + void *data; + + i = 0; + dlist_foreach(l, n, data) { + i++; + } + + return i; +} + +struct dlist *dlist_nth(struct dlist *l, int nth) +{ + register int i; + struct dlist *n; + + i = 0; + for (n = l; n; n = n->next) { + if (i == nth) { + return n; + } + i++; + } + + return NULL; +} + +/* End of a file */ diff --git a/widget_viewer/src/fb.c b/widget_viewer/src/fb.c new file mode 100644 index 0000000..a31e72c --- /dev/null +++ b/widget_viewer/src/fb.c @@ -0,0 +1,682 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include +#include +#include + +#include +#include +#include + +#include +#include /* For error code */ +#include /* For buffer event data */ +#include + +#include "debug.h" +#include "util.h" +#include "fb.h" + +int errno; + +static struct { + Display *disp; + int screen; + Visual *visual; + int disp_is_opened; +} s_info = { + .disp = NULL, + .disp_is_opened = 0, + .screen = -1, + .visual = NULL, +}; + +int fb_init(void *disp) +{ + s_info.disp = disp; + if (s_info.disp) { + Screen *screen; + + screen = DefaultScreenOfDisplay(s_info.disp); + + s_info.screen = DefaultScreen(s_info.disp); + s_info.visual = DefaultVisualOfScreen(screen); + } + + return WIDGET_ERROR_NONE; +} + +int fb_fini(void) +{ + if (s_info.disp_is_opened && s_info.disp) { + XCloseDisplay(s_info.disp); + } + + s_info.disp = NULL; + s_info.disp_is_opened = 0; + s_info.visual = NULL; + s_info.screen = -1; + return WIDGET_ERROR_NONE; +} + +static inline void update_fb_size(struct fb_info *info) +{ + info->bufsz = info->w * info->h * info->pixels; +} + +static int sync_for_file(struct fb_info *info, int x, int y, int w, int h) +{ + int fd; + widget_fb_t buffer; + const char *path = NULL; + + buffer = info->buffer; + + if (!buffer) { /* Ignore this sync request */ + return WIDGET_ERROR_NONE; + } + + if (buffer->state != WIDGET_FB_STATE_CREATED) { + ErrPrint("Invalid state of a FB\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (buffer->type != WIDGET_FB_TYPE_FILE) { + ErrPrint("Invalid buffer\n"); + return WIDGET_ERROR_NONE; + } + + path = util_uri_to_path(info->id); + + if (path == NULL) { + ErrPrint("Invalid parameter\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + fd = open(path, O_RDONLY); + if (fd < 0) { + ErrPrint("Failed to open a file (%s) because of (%d)\n", + util_uri_to_path(info->id), errno); + + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return WIDGET_ERROR_NONE; + } + + /** + * @note + * Could we get some advantage if we load a part of file instead of loading all of them? + */ + if (x != 0 || y != 0 || info->w != w || info->h != h) { + int iy; + register int index; + register int width; + + for (iy = y; iy < h; iy++) { + index = iy * info->w + x; + width = w * info->pixels; + + if (lseek(fd, index * info->pixels, SEEK_SET) != index * info->pixels) { + ErrPrint("lseek: %d\n", errno); + if (close(fd) < 0) { + ErrPrint("close: %d\n", errno); + } + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return WIDGET_ERROR_NONE; + } + + if (read(fd, ((unsigned int *)buffer->data) + index, width) != width) { + if (close(fd) < 0) { + ErrPrint("close: %d\n", errno); + } + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return WIDGET_ERROR_NONE; + } + } + } else { + if (read(fd, buffer->data, info->bufsz) != info->bufsz) { + ErrPrint("read: %d\n", errno); + if (close(fd) < 0) { + ErrPrint("close: %d\n", errno); + } + + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return WIDGET_ERROR_NONE; + } + } + + if (close(fd) < 0) { + ErrPrint("close: %d\n", errno); + } + return WIDGET_ERROR_NONE; +} + +static int sync_for_pixmap(struct fb_info *info, int x, int y, int w, int h) +{ + widget_fb_t buffer; + XShmSegmentInfo si; + XImage *xim; + + buffer = info->buffer; + if (!buffer) { /*!< Ignore this sync request */ + return WIDGET_ERROR_NONE; + } + + if (buffer->state != WIDGET_FB_STATE_CREATED) { + ErrPrint("Invalid state of a FB\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (buffer->type != WIDGET_FB_TYPE_PIXMAP) { + ErrPrint("Invalid buffer\n"); + return WIDGET_ERROR_NONE; + } + + if (!s_info.disp) { + s_info.disp = XOpenDisplay(NULL); + if (s_info.disp) { + Screen *screen; + + s_info.disp_is_opened = 1; + + screen = DefaultScreenOfDisplay(s_info.disp); + + s_info.screen = DefaultScreen(s_info.disp); + s_info.visual = DefaultVisualOfScreen(screen); + } else { + ErrPrint("Failed to open a display\n"); + return WIDGET_ERROR_FAULT; + } + } + + if (info->handle == 0) { + ErrPrint("Pixmap ID is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (info->bufsz == 0) { + /*! + * If the client does not acquire the buffer, + * This function will do nothing. + * It will work only if the buffer is acquired. + * To sync its contents. + */ + DbgPrint("Nothing can be sync\n"); + return WIDGET_ERROR_NONE; + } + + si.shmid = shmget(IPC_PRIVATE, info->bufsz, IPC_CREAT | 0666); + if (si.shmid < 0) { + ErrPrint("shmget: %d\n", errno); + return WIDGET_ERROR_FAULT; + } + + si.readOnly = False; + si.shmaddr = shmat(si.shmid, NULL, 0); + if (si.shmaddr == (void *)-1) { + if (shmctl(si.shmid, IPC_RMID, 0) < 0) { + ErrPrint("shmctl: %d\n", errno); + } + + return WIDGET_ERROR_FAULT; + } + + /*! + * \NOTE + * Use the 24 bits Pixmap for Video player + */ + xim = XShmCreateImage(s_info.disp, s_info.visual, + (info->pixels << 3), ZPixmap, NULL, + &si, + info->w, info->h); + if (xim == NULL) { + if (shmdt(si.shmaddr) < 0) { + ErrPrint("shmdt: %d\n", errno); + } + + if (shmctl(si.shmid, IPC_RMID, 0) < 0) { + ErrPrint("shmctl: %d\n", errno); + } + + return WIDGET_ERROR_FAULT; + } + + xim->data = si.shmaddr; + XShmAttach(s_info.disp, &si); + + XShmGetImage(s_info.disp, info->handle, xim, 0, 0, 0xFFFFFFFF); + XSync(s_info.disp, False); + + if (x != 0 || y != 0 || info->w != w || info->h != h) { + int ix; + int iy; + register int index; + + for (iy = y; iy < h; iy++) { + for (ix = x; ix < w; ix++) { + index = iy * info->w + x; + *(((unsigned int *)buffer->data) + index) = *(((unsigned int *)xim->data) + index); + } + } + } else { + memcpy(buffer->data, xim->data, info->bufsz); + } + + XShmDetach(s_info.disp, &si); + XDestroyImage(xim); + + if (shmdt(si.shmaddr) < 0) { + ErrPrint("shmdt: %d\n", errno); + } + + if (shmctl(si.shmid, IPC_RMID, 0) < 0) { + ErrPrint("shmctl: %d\n", errno); + } + + return WIDGET_ERROR_NONE; +} + +int fb_sync(struct fb_info *info, int x, int y, int w, int h) +{ + if (!info) { + ErrPrint("FB Handle is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!info->id || info->id[0] == '\0') { + DbgPrint("Ingore sync\n"); + return WIDGET_ERROR_NONE; + } + + if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + return sync_for_file(info, x, y, w, h); + } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + return sync_for_pixmap(info, x, y, w, h); + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + /* No need to do sync */ + return WIDGET_ERROR_NONE; + } + + return WIDGET_ERROR_INVALID_PARAMETER; +} + +struct fb_info *fb_create(const char *id, int w, int h) +{ + struct fb_info *info; + + if (!id || id[0] == '\0') { + ErrPrint("Invalid ID\n"); + return NULL; + } + + info = calloc(1, sizeof(*info)); + if (!info) { + ErrPrint("Heap: %d\n", errno); + return NULL; + } + + info->id = strdup(id); + if (!info->id) { + ErrPrint("Heap: %d\n", errno); + free(info); + return NULL; + } + + info->pixels = sizeof(int); /* Use the default pixels(depth) */ + + if (sscanf(info->id, SCHEMA_SHM "%d", &info->handle) == 1) { + DbgPrint("SHMID: %d is gotten\n", info->handle); + } else if (sscanf(info->id, SCHEMA_PIXMAP "%d:%d", &info->handle, &info->pixels) == 2) { + DbgPrint("PIXMAP-SHMID: %d is gotten (%d)\n", info->handle, info->pixels); + } else { + info->handle = WIDGET_ERROR_INVALID_PARAMETER; + } + + info->bufsz = 0; + info->buffer = NULL; + info->w = w; + info->h = h; + + return info; +} + +int fb_destroy(struct fb_info *info) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (info->buffer) { + widget_fb_t buffer; + buffer = info->buffer; + + buffer->info = NULL; + } + + free(info->id); + free(info); + return WIDGET_ERROR_NONE; +} + +int fb_is_created(struct fb_info *info) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return 0; + } + + if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)) && info->handle != 0) { + return 1; + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM)) && info->handle > 0) { + return 1; + } else { + const char *path; + path = util_uri_to_path(info->id); + if (path && access(path, F_OK | R_OK) == 0) { + return 1; + } else { + ErrPrint("access: %d (%s)\n", errno, path); + } + } + + return 0; +} + +void *fb_acquire_buffer(struct fb_info *info) +{ + widget_fb_t buffer; + + if (!info) { + ErrPrint("info == NIL\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!info->buffer) { + if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + update_fb_size(info); + + buffer = calloc(1, sizeof(*buffer) + info->bufsz); + if (!buffer) { + ErrPrint("Heap: %d\n", errno); + set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); + info->bufsz = 0; + return NULL; + } + + buffer->type = WIDGET_FB_TYPE_PIXMAP; + buffer->refcnt = 0; + buffer->state = WIDGET_FB_STATE_CREATED; + buffer->info = info; + info->buffer = buffer; + + /*! + * \note + * Just update from here. + */ + sync_for_pixmap(info, 0, 0, info->w, info->h); + } else if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + update_fb_size(info); + + buffer = calloc(1, sizeof(*buffer) + info->bufsz); + if (!buffer) { + ErrPrint("Heap: %d\n", errno); + info->bufsz = 0; + set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); + return NULL; + } + + buffer->type = WIDGET_FB_TYPE_FILE; + buffer->refcnt = 0; + buffer->state = WIDGET_FB_STATE_CREATED; + buffer->info = info; + info->buffer = buffer; + + sync_for_file(info, 0, 0, info->w, info->h); + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + buffer = shmat(info->handle, NULL, 0); + if (buffer == (void *)-1) { + ErrPrint("shmat: %d (%d)\n", errno, info->handle); + set_last_result(WIDGET_ERROR_FAULT); + return NULL; + } + + return buffer->data; + } else { + ErrPrint("Buffer is not created (%s)\n", info->id); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + } + + buffer = info->buffer; + + switch (buffer->type) { + case WIDGET_FB_TYPE_PIXMAP: + buffer->refcnt++; + break; + case WIDGET_FB_TYPE_FILE: + buffer->refcnt++; + break; + default: + DbgPrint("Unknwon FP: %d\n", buffer->type); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + break; + } + + return buffer->data; +} + +int fb_release_buffer(void *data) +{ + widget_fb_t buffer; + + if (!data) { + ErrPrint("buffer data == NIL\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + buffer = container_of(data, struct widget_fb, data); + + if (buffer->state != WIDGET_FB_STATE_CREATED) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + switch (buffer->type) { + case WIDGET_FB_TYPE_SHM: + if (shmdt(buffer) < 0) { + ErrPrint("shmdt: %d\n", errno); + } + break; + case WIDGET_FB_TYPE_PIXMAP: + buffer->refcnt--; + if (buffer->refcnt == 0) { + struct fb_info *info; + info = buffer->info; + + buffer->state = WIDGET_FB_STATE_DESTROYED; + + if (info && info->buffer == buffer) { + info->buffer = NULL; + } + free(buffer); + } + break; + case WIDGET_FB_TYPE_FILE: + buffer->refcnt--; + if (buffer->refcnt == 0) { + struct fb_info *info; + info = buffer->info; + + buffer->state = WIDGET_FB_STATE_DESTROYED; + + if (info && info->buffer == buffer) { + info->buffer = NULL; + } + + free(buffer); + } + break; + default: + ErrPrint("Unknwon buffer type\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + break; + } + + return WIDGET_ERROR_NONE; +} + +int fb_refcnt(void *data) +{ + widget_fb_t buffer; + struct shmid_ds buf; + int ret; + + if (!data) { + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + buffer = container_of(data, struct widget_fb, data); + + if (buffer->state != WIDGET_FB_STATE_CREATED) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + switch (buffer->type) { + case WIDGET_FB_TYPE_SHM: + if (shmctl(buffer->refcnt, IPC_STAT, &buf) < 0) { + ErrPrint("Error: %d\n", errno); + set_last_result(WIDGET_ERROR_FAULT); + return WIDGET_ERROR_FAULT; + } + + ret = buf.shm_nattch; + break; + case WIDGET_FB_TYPE_PIXMAP: + ret = buffer->refcnt; + break; + case WIDGET_FB_TYPE_FILE: + ret = buffer->refcnt; + break; + default: + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + ret = WIDGET_ERROR_INVALID_PARAMETER; + break; + } + + return ret; +} + +const char *fb_id(struct fb_info *info) +{ + return info ? info->id : NULL; +} + +int fb_get_size(struct fb_info *info, int *w, int *h) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + *w = info->w; + *h = info->h; + return WIDGET_ERROR_NONE; +} + +int fb_size(struct fb_info *info) +{ + if (!info) { + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return 0; + } + + update_fb_size(info); + + return info->bufsz; +} + +int fb_type(struct fb_info *info) +{ + widget_fb_t buffer; + + if (!info) { + return WIDGET_FB_TYPE_ERROR; + } + + buffer = info->buffer; + if (!buffer) { + int type = WIDGET_FB_TYPE_ERROR; + /*! + * \note + * Try to get this from SCHEMA + */ + if (info->id) { + if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + type = WIDGET_FB_TYPE_FILE; + } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + type = WIDGET_FB_TYPE_PIXMAP; + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + type = WIDGET_FB_TYPE_SHM; + } + } + + return type; + } + + return buffer->type; +} +/* End of a file */ diff --git a/widget_viewer/src/fb_wayland.c b/widget_viewer/src/fb_wayland.c new file mode 100644 index 0000000..d958515 --- /dev/null +++ b/widget_viewer/src/fb_wayland.c @@ -0,0 +1,639 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include +#include +#include + +#include +#include + +#include +#include /* For error code */ +#include /* For buffer event data */ +#include +#include + +#include "debug.h" +#include "util.h" +#include "fb.h" +#include "dlist.h" + +int errno; + +struct gem_data { + tbm_bo pixmap_bo; + tbm_bo_handle handle; + widget_fb_t buffer; +}; + +static struct { + struct wl_display *disp; + tbm_bufmgr bufmgr; + int disp_is_opened; + int fd; + struct dlist *canvas_list; +} s_info = { + .disp = NULL, + .bufmgr = NULL, + .disp_is_opened = 0, + .fd = -1, + .canvas_list = NULL, +}; + +int fb_init(void *disp) +{ + int ret; + + s_info.disp = disp; + if (!s_info.disp) { + s_info.disp = wl_display_connect(NULL); + if (!s_info.disp) { + ErrPrint("Failed to open a display\n"); + return WIDGET_ERROR_FAULT; + } + + s_info.disp_is_opened = 1; + } + + ret = widget_util_get_drm_fd(s_info.disp, &s_info.fd); + if (ret != WIDGET_ERROR_NONE || s_info.fd < 0) { + ErrPrint("Failed to open a drm device: (%d)\n", errno); + return WIDGET_ERROR_FAULT; + } + + s_info.bufmgr = tbm_bufmgr_init(s_info.fd); + if (!s_info.bufmgr) { + ErrPrint("Failed to init bufmgr\n"); + widget_util_release_drm_fd(s_info.fd); + s_info.fd = -1; + return WIDGET_ERROR_FAULT; + } + + return WIDGET_ERROR_NONE; +} + +int fb_fini(void) +{ + if (s_info.bufmgr) { + tbm_bufmgr_deinit(s_info.bufmgr); + s_info.bufmgr = NULL; + } + + if (s_info.fd >= 0) { + widget_util_release_drm_fd(s_info.fd); + s_info.fd = -1; + } + + if (s_info.disp_is_opened && s_info.disp) { + wl_display_disconnect(s_info.disp); + s_info.disp = NULL; + } + + s_info.disp = NULL; + return WIDGET_ERROR_NONE; +} + +static inline void update_fb_size(struct fb_info *info) +{ + info->bufsz = info->w * info->h * info->pixels; +} + +static int sync_for_file(struct fb_info *info, int x, int y, int w, int h) +{ + int fd; + widget_fb_t buffer; + const char *path = NULL; + + buffer = info->buffer; + + if (!buffer) { /* Ignore this sync request */ + return WIDGET_ERROR_NONE; + } + + if (buffer->state != WIDGET_FB_STATE_CREATED) { + ErrPrint("Invalid state of a FB\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (buffer->type != WIDGET_FB_TYPE_FILE) { + ErrPrint("Invalid buffer\n"); + return WIDGET_ERROR_NONE; + } + + path = util_uri_to_path(info->id); + + if (path == NULL) { + ErrPrint("Invalid parameter\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + fd = open(path, O_RDONLY); + if (fd < 0) { + ErrPrint("Failed to open a file (%s) because of (%d)\n", + util_uri_to_path(info->id), errno); + + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return WIDGET_ERROR_NONE; + } + + /** + * @note + * Could we get some advantage if we load a part of file instead of loading all of them? + */ + if (x != 0 || y != 0 || info->w != w || info->h != h) { + int iy; + register int index; + register int width; + + for (iy = y; iy < h; iy++) { + index = iy * info->w + x; + width = w * info->pixels; + + if (lseek(fd, index * info->pixels, SEEK_SET) != index * info->pixels) { + ErrPrint("lseek: %d\n", errno); + if (close(fd) < 0) { + ErrPrint("close: %d\n", errno); + } + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return WIDGET_ERROR_NONE; + } + + if (read(fd, ((unsigned int *)buffer->data) + index, width) != width) { + if (close(fd) < 0) { + ErrPrint("close: %d\n", errno); + } + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return WIDGET_ERROR_NONE; + } + } + } else { + if (read(fd, buffer->data, info->bufsz) != info->bufsz) { + ErrPrint("read: %d\n", errno); + if (close(fd) < 0) { + ErrPrint("close: %d\n", errno); + } + + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return WIDGET_ERROR_NONE; + } + } + + if (close(fd) < 0) { + ErrPrint("close: %d\n", errno); + } + return WIDGET_ERROR_NONE; +} + +int fb_sync(struct fb_info *info, int x, int y, int w, int h) +{ + if (!info) { + ErrPrint("FB Handle is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!info->id || info->id[0] == '\0') { + DbgPrint("Ingore sync\n"); + return WIDGET_ERROR_NONE; + } + + if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + return sync_for_file(info, x, y, w, h); + } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + return WIDGET_ERROR_NONE; + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + /* No need to do sync */ + return WIDGET_ERROR_NONE; + } + + return WIDGET_ERROR_INVALID_PARAMETER; +} + +struct fb_info *fb_create(const char *id, int w, int h) +{ + struct fb_info *info; + + if (!id || id[0] == '\0') { + ErrPrint("Invalid ID\n"); + return NULL; + } + + info = calloc(1, sizeof(*info)); + if (!info) { + ErrPrint("Heap: %d\n", errno); + return NULL; + } + + info->id = strdup(id); + if (!info->id) { + ErrPrint("Heap: %d\n", errno); + free(info); + return NULL; + } + + info->pixels = sizeof(int); /* Use the default pixels(depth) */ + + if (sscanf(info->id, SCHEMA_SHM "%d", &info->handle) == 1) { + DbgPrint("SHMID: %d is gotten\n", info->handle); + } else if (sscanf(info->id, SCHEMA_PIXMAP "%d:%d", &info->handle, &info->pixels) == 2) { + DbgPrint("PIXMAP-SHMID: %d is gotten (%d)\n", info->handle, info->pixels); + } else { + info->handle = WIDGET_ERROR_INVALID_PARAMETER; + } + + info->bufsz = 0; + info->buffer = NULL; + info->w = w; + info->h = h; + + return info; +} + +int fb_destroy(struct fb_info *info) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (info->buffer) { + widget_fb_t buffer; + buffer = info->buffer; + + buffer->info = NULL; + } + + free(info->id); + free(info); + return WIDGET_ERROR_NONE; +} + +int fb_is_created(struct fb_info *info) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return 0; + } + + if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)) && info->handle != 0) { + return 1; + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM)) && info->handle > 0) { + return 1; + } else { + const char *path; + path = util_uri_to_path(info->id); + if (path && access(path, F_OK | R_OK) == 0) { + return 1; + } else { + ErrPrint("access: %d (%s)\n", errno, path); + } + } + + return 0; +} + +void *fb_acquire_buffer(struct fb_info *info) +{ + widget_fb_t buffer; + + if (!info) { + ErrPrint("info == NIL\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!info->buffer) { + if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + struct gem_data *gem; + + update_fb_size(info); + + buffer = calloc(1, sizeof(*buffer) + info->bufsz); + if (!buffer) { + ErrPrint("Heap: %d\n", errno); + set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); + info->bufsz = 0; + return NULL; + } + + gem = calloc(1, sizeof(*gem)); + if (!gem) { + ErrPrint("Heap: %d\n", errno); + return NULL; + } + + buffer->type = WIDGET_FB_TYPE_PIXMAP; + buffer->refcnt = 0; + buffer->state = WIDGET_FB_STATE_CREATED; + buffer->info = info; + info->buffer = buffer; + info->gem = gem; + + gem->pixmap_bo = tbm_bo_import(s_info.bufmgr, info->handle); + if (!gem->pixmap_bo) { + ErrPrint("Failed to get bo\n"); + free(gem); + free(buffer); + return NULL; + } + + gem->handle = tbm_bo_map(gem->pixmap_bo, TBM_DEVICE_CPU, TBM_OPTION_READ); + gem->buffer = buffer; + + s_info.canvas_list = dlist_append(s_info.canvas_list, buffer); + } else if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + update_fb_size(info); + + buffer = calloc(1, sizeof(*buffer) + info->bufsz); + if (!buffer) { + ErrPrint("Heap: %d\n", errno); + info->bufsz = 0; + set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); + return NULL; + } + + buffer->type = WIDGET_FB_TYPE_FILE; + buffer->refcnt = 0; + buffer->state = WIDGET_FB_STATE_CREATED; + buffer->info = info; + info->buffer = buffer; + + sync_for_file(info, 0, 0, info->w, info->h); + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + buffer = shmat(info->handle, NULL, 0); + if (buffer == (void *)-1) { + ErrPrint("shmat: %d (%d)\n", errno, info->handle); + set_last_result(WIDGET_ERROR_FAULT); + return NULL; + } + + return buffer->data; + } else { + ErrPrint("Buffer is not created (%s)\n", info->id); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + } + + buffer = info->buffer; + + switch (buffer->type) { + case WIDGET_FB_TYPE_PIXMAP: + { + struct gem_data *gem; + + buffer->refcnt++; + gem = info->gem; + + return gem->handle.ptr; + } + break; + case WIDGET_FB_TYPE_FILE: + buffer->refcnt++; + break; + default: + DbgPrint("Unknwon FP: %d\n", buffer->type); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + break; + } + + return buffer->data; +} + +int fb_release_buffer(void *data) +{ + widget_fb_t buffer; + struct dlist *l; + + if (!data) { + ErrPrint("buffer data == NIL\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + buffer = NULL; + dlist_foreach(s_info.canvas_list, l, buffer) { + if (buffer) { + struct fb_info *info; + struct gem_data *gem; + + info = buffer->info; + gem = info->gem; + + if (gem->handle.ptr == data) { + break; + } + } + buffer = NULL; + } + + if (!buffer) { + buffer = container_of(data, struct widget_fb, data); + } + + if (buffer->state != WIDGET_FB_STATE_CREATED) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + switch (buffer->type) { + case WIDGET_FB_TYPE_SHM: + if (shmdt(buffer) < 0) { + ErrPrint("shmdt: %d\n", errno); + } + break; + case WIDGET_FB_TYPE_PIXMAP: + buffer->refcnt--; + if (buffer->refcnt == 0) { + struct fb_info *info; + struct gem_data *gem; + + info = buffer->info; + gem = info->gem; + + if (gem->pixmap_bo) { + tbm_bo_unmap(gem->pixmap_bo); + gem->pixmap_bo = NULL; + } + + dlist_remove_data(s_info.canvas_list, buffer); + free(gem); + free(buffer); + } + break; + case WIDGET_FB_TYPE_FILE: + buffer->refcnt--; + if (buffer->refcnt == 0) { + struct fb_info *info; + info = buffer->info; + + buffer->state = WIDGET_FB_STATE_DESTROYED; + + if (info && info->buffer == buffer) { + info->buffer = NULL; + } + + free(buffer); + } + break; + default: + ErrPrint("Unknwon buffer type\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + break; + } + + return WIDGET_ERROR_NONE; +} + +int fb_refcnt(void *data) +{ + widget_fb_t buffer; + struct shmid_ds buf; + int ret; + + if (!data) { + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + buffer = container_of(data, struct widget_fb, data); + + if (buffer->state != WIDGET_FB_STATE_CREATED) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + switch (buffer->type) { + case WIDGET_FB_TYPE_SHM: + if (shmctl(buffer->refcnt, IPC_STAT, &buf) < 0) { + ErrPrint("Error: %d\n", errno); + set_last_result(WIDGET_ERROR_FAULT); + return WIDGET_ERROR_FAULT; + } + + ret = buf.shm_nattch; + break; + case WIDGET_FB_TYPE_PIXMAP: + ret = buffer->refcnt; + break; + case WIDGET_FB_TYPE_FILE: + ret = buffer->refcnt; + break; + default: + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + ret = WIDGET_ERROR_INVALID_PARAMETER; + break; + } + + return ret; +} + +const char *fb_id(struct fb_info *info) +{ + return info ? info->id : NULL; +} + +int fb_get_size(struct fb_info *info, int *w, int *h) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + *w = info->w; + *h = info->h; + return WIDGET_ERROR_NONE; +} + +int fb_size(struct fb_info *info) +{ + if (!info) { + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return 0; + } + + update_fb_size(info); + + return info->bufsz; +} + +int fb_type(struct fb_info *info) +{ + widget_fb_t buffer; + + if (!info) { + return WIDGET_FB_TYPE_ERROR; + } + + buffer = info->buffer; + if (!buffer) { + int type = WIDGET_FB_TYPE_ERROR; + /*! + * \note + * Try to get this from SCHEMA + */ + if (info->id) { + if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + type = WIDGET_FB_TYPE_FILE; + } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + type = WIDGET_FB_TYPE_PIXMAP; + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + type = WIDGET_FB_TYPE_SHM; + } + } + + return type; + } + + return buffer->type; +} + +/* End of a file */ diff --git a/widget_viewer/src/file_service.c b/widget_viewer/src/file_service.c new file mode 100644 index 0000000..1beeb30 --- /dev/null +++ b/widget_viewer/src/file_service.c @@ -0,0 +1,715 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "client.h" +#include "debug.h" +#include "dlist.h" + +#define FILE_SERVICE_PORT 8209 + +#define CRITICAL_SECTION_BEGIN(handle) \ + do { \ + int ret; \ + ret = pthread_mutex_lock(handle); \ + if (ret != 0) { \ + ErrPrint("Failed to lock: %s\n", strerror(ret)); \ + } \ + } while (0) + +#define CRITICAL_SECTION_END(handle) \ + do { \ + int ret; \ + ret = pthread_mutex_unlock(handle); \ + if (ret != 0) { \ + ErrPrint("Failed to unlock: %s\n", strerror(ret)); \ + } \ + } while (0) + +#define CANCEL_SECTION_BEGIN() do { \ + int ret; \ + ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); \ + if (ret != 0) { \ + ErrPrint("Unable to set cancelate state: %s\n", strerror(ret)); \ + } \ +} while (0) + +#define CANCEL_SECTION_END() do { \ + int ret; \ + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); \ + if (ret != 0) { \ + ErrPrint("Unable to set cancelate state: %s\n", strerror(ret)); \ + } \ +} while (0) + +#define CLOSE_PIPE(p) do { \ + int status; \ + status = close(p[PIPE_READ]); \ + if (status < 0) { \ + ErrPrint("close: %d\n", errno); \ + } \ + status = close(p[PIPE_WRITE]); \ + if (status < 0) { \ + ErrPrint("close: %d\n", errno); \ + } \ +} while (0) + +#define PIPE_READ 0 +#define PIPE_WRITE 1 +#define PIPE_MAX 2 + +#define EVT_END_CH 'c' +#define EVT_CH 'e' + +static struct { + pthread_t file_svc_thid; + pthread_mutex_t file_svc_lock; + int ctrl_pipe[PIPE_MAX]; + int evt_pipe[PIPE_MAX]; + struct dlist *request_list; + int file_service_fd; +} s_info = { + .ctrl_pipe = { -1, -1 }, + .evt_pipe = { -1, -1 }, + .request_list = NULL, + .file_service_fd = -1, +}; + +struct request_item { + char *filename; + char *save_to; + void (*result_cb)(const char *filename, const char *save_to, int ret, void *data); + void *data; + int ret; +}; + +/*! + * File transfer header. + * This must should be shared with client. + */ +struct burst_head { + off_t size; + int flen; + char fname[]; +}; + +struct burst_data { + int size; + char data[]; +}; + +static inline int put_event_ch(int fd, char ch) +{ + int ret; + + ret = write(fd, &ch, sizeof(ch)); + if (ret != sizeof(ch)) { + ErrPrint("write: %d\n", errno); + return ret; + } + + return 0; +} + +static inline int get_event_ch(int fd) +{ + int ret; + char ch; + + ret = read(fd, &ch, sizeof(ch)); + if (ret != sizeof(ch)) { + ErrPrint("read: %d\n", errno); + return ret; + } + + ret = (int)((unsigned int)ch); + return ret; +} + +static inline int file_service_close(int fd) +{ + return secure_socket_destroy_handle(fd); +} + +static inline int file_service_open(void) +{ + char *addr; + int port; + char *file_addr; + int len; + int fd; + + addr = malloc(strlen(client_addr()) + 1); + if (!addr) { + ErrPrint("Heap: %d\n", errno); + return -ENOMEM; + } + + if (sscanf(client_addr(), COM_CORE_REMOTE_SCHEME"%[^:]:%d", addr, &port) != 2) { + ErrPrint("Invalid URL\n"); + free(addr); + return -EINVAL; + } + + len = strlen(COM_CORE_REMOTE_SCHEME); + len += strlen(addr); + len += 6; /* Port length? */ + + file_addr = malloc(len); + if (!file_addr) { + ErrPrint("Heap: %d\n", errno); + free(addr); + return -ENOMEM; + } + + snprintf(file_addr, len, COM_CORE_REMOTE_SCHEME"%s:%d", addr, FILE_SERVICE_PORT); + DbgPrint("File service: %s\n", file_addr); + fd = secure_socket_create_client(file_addr); + free(file_addr); + free(addr); + + return fd; +} + +/*! + * Service Thread + */ +static void write_item_to_pipe(struct request_item *item, int ret) +{ + item->ret = WIDGET_ERROR_FAULT; + if (write(s_info.evt_pipe[PIPE_WRITE], &item, sizeof(item)) != sizeof(item)) { + ErrPrint("write: %d\n", errno); + free(item->filename); + free(item->save_to); + free(item); + item = NULL; + } +} + +/*! + * Service Thread + */ +static void *file_service_main(void *data) +{ + int ret = 0; + int select_fd; + struct timeval tv; + fd_set set; + int offset; + enum { + RECV_INIT, + RECV_HEADER, + RECV_DATA, + } recv_state; + struct burst_head *head; + struct burst_data *body; + int recvsz; + struct request_item *item; + int file_offset; + int file_fd; + + head = NULL; + item = NULL; + recv_state = RECV_INIT; + select_fd = (s_info.file_service_fd > s_info.ctrl_pipe[PIPE_READ] ? s_info.file_service_fd : s_info.ctrl_pipe[PIPE_READ]) + 1; + while (ret == 0) { + FD_ZERO(&set); + FD_SET(s_info.file_service_fd, &set); + FD_SET(s_info.ctrl_pipe[PIPE_READ], &set); + + tv.tv_sec = 3; + tv.tv_usec = 0; + ret = select(select_fd , &set, NULL, NULL, &tv); + if (ret < 0) { + ret = -errno; + if (errno == EINTR) { + ErrPrint("INTERRUPTED\n"); + ret = 0; + continue; + } + ErrPrint("Error: %d\n", errno); + break; + } else if (ret == 0) { + ErrPrint("Timeout\n"); + ret = -ETIMEDOUT; + break; + } + + if (item && FD_ISSET(s_info.file_service_fd, &set)) { + switch (recv_state) { + case RECV_INIT: + if (head == NULL) { + recvsz = sizeof(*head); + + head = malloc(recvsz); + if (!head) { + ErrPrint("Heap: %d\n", errno); + ret = WIDGET_ERROR_OUT_OF_MEMORY; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + offset = 0; + recv_state = RECV_HEADER; + } + case RECV_HEADER: + if (offset < recvsz) { + ret = secure_socket_recv(s_info.file_service_fd, (char *)head + offset, recvsz - offset, NULL); + if (ret > 0) { + offset += ret; + } else { + free(head); + head = NULL; + recv_state = RECV_INIT; + ret = WIDGET_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + } + + if (offset == sizeof(*head)) { + void *tmp; + + recvsz += head->flen; + + tmp = realloc(head, recvsz); + if (!tmp) { + ErrPrint("Heap: %d\n", errno); + + free(head); + head = NULL; + recv_state = RECV_INIT; + + ret = WIDGET_ERROR_OUT_OF_MEMORY; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + head = tmp; + } else if (offset == recvsz) { + DbgPrint("Filesize: %d, name[%s]\n", head->size, head->fname); + if (strcmp(item->filename, head->fname)) { + ErrPrint("Invalid data sequence (%s <> %s)\n", item->filename, head->fname); + + free(head); + head = NULL; + recv_state = RECV_INIT; + ret = WIDGET_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + file_fd = open(item->save_to, O_WRONLY|O_CREAT, 0644); + if (file_fd < 0) { + ErrPrint("open: %d\n", errno); + free(head); + head = NULL; + recv_state = RECV_INIT; + + ret = WIDGET_ERROR_IO_ERROR; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + recv_state = RECV_DATA; + body = NULL; + + } else { + ErrPrint("Invalid state\n"); + free(head); + head = NULL; + recv_state = RECV_INIT; + ret = WIDGET_ERROR_INVALID_PARAMETER; + write_item_to_pipe(item, ret); + item = NULL; + } + break; + case RECV_DATA: + if (!body) { + body = malloc(sizeof(*body)); + if (!body) { + free(head); + head = NULL; + recv_state = RECV_INIT; + ret = WIDGET_ERROR_OUT_OF_MEMORY; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + recvsz = sizeof(*body); + offset = 0; + } + + ret = secure_socket_recv(s_info.file_service_fd, (char *)body + offset, recvsz - offset, NULL); + if (ret > 0) { + offset += ret; + } else { + free(head); + head = NULL; + free(body); + body = NULL; + recv_state = RECV_INIT; + ret = WIDGET_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + if (offset == sizeof(*body)) { + void *tmp; + + if (body->size < 0) { + ErrPrint("body->size: %d\n", body->size); + free(head); + head = NULL; + free(body); + body = NULL; + recv_state = RECV_INIT; + ret = WIDGET_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + recvsz += body->size; + + tmp = realloc(body, recvsz); + if (!tmp) { + ErrPrint("Heap: %d\n", errno); + free(head); + head = NULL; + + free(body); + body = NULL; + recv_state = RECV_INIT; + + ret = WIDGET_ERROR_OUT_OF_MEMORY; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + } else if (offset == recvsz) { + /* Flush this to the file */ + ret = write(file_fd, body->data, body->size); + if (ret < 0) { + ErrPrint("write: %d\n", errno); + free(head); + head = NULL; + + free(body); + body = NULL; + recv_state = RECV_INIT; + + ret = WIDGET_ERROR_IO_ERROR; + write_item_to_pipe(item, ret); + item = NULL; + break; + } else { + if (body->size != ret) { + DbgPrint("Body is not flushed correctly: %d, %d\n", ret, body->size); + ret = body->size; + } + + file_offset += ret; + if (file_offset == head->size) { + if (close(file_fd) < 0) { + ErrPrint("close: %d\n", errno); + } + ret = WIDGET_ERROR_NONE; + write_item_to_pipe(item, ret); + item = NULL; + } + } + + free(body); + body = NULL; + + free(head); + head = NULL; + + recv_state = RECV_INIT; + } else { + ErrPrint("Invalid state\n"); + + ret = -EFAULT; + free(body); + body = NULL; + free(head); + head = NULL; + recv_state = RECV_INIT; + + ret = WIDGET_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + } + break; + default: + ErrPrint("Unknown event: %d\n", recv_state); + ret = WIDGET_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + } else if (item == NULL && recv_state == RECV_INIT && FD_ISSET(s_info.ctrl_pipe[PIPE_READ], &set)) { + int ch; + struct dlist *l; + + /* Only if the recv state is not changed, we can get next request item */ + ch = get_event_ch(s_info.ctrl_pipe[PIPE_READ]); + if (ch == EVT_END_CH) { + DbgPrint("Service thread is canceled\n"); + break; + } + + CRITICAL_SECTION_BEGIN(&s_info.file_svc_lock); + l = dlist_nth(s_info.request_list, 0); + item = dlist_data(l); + s_info.request_list = dlist_remove(s_info.request_list, l); + CRITICAL_SECTION_END(&s_info.file_svc_lock); + } + } + + return (void *)((long)ret); +} + +/* Master */ +static gboolean evt_cb(GIOChannel *src, GIOCondition cond, gpointer data) +{ + int fd; + struct request_item *item; + + fd = g_io_channel_unix_get_fd(src); + + if (!(cond & G_IO_IN)) { + DbgPrint("Client is disconencted\n"); + return FALSE; + } + + if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) { + DbgPrint("Client connection is lost\n"); + return FALSE; + } + + if (read(fd, &item, sizeof(item)) != sizeof(item)) { + ErrPrint("read: %d\n", errno); + } else { + if (item->result_cb) { + item->result_cb(item->filename, item->save_to, item->ret, item->data); + } + + free(item->filename); + free(item->save_to); + free(item); + } + + return TRUE; +} + +int file_service_send_request(const char *filename, const char *save_to, void (*result_cb)(const char *filename, const char *save_to, int ret, void *data), void *data) +{ + struct request_item *item; + + item = malloc(sizeof(*item)); + if (!item) { + ErrPrint("Heap: %d\n", errno); + return -ENOMEM; + } + + item->filename = strdup(filename); + if (!item->filename) { + ErrPrint("Heap: %d\n", errno); + free(item); + return -ENOMEM; + } + + item->save_to = strdup(save_to); + if (!item->save_to) { + ErrPrint("Heap: %d\n", errno); + free(item->filename); + free(item); + return -ENOMEM; + } + + item->result_cb = result_cb; + item->data = data; + + CRITICAL_SECTION_BEGIN(&s_info.file_svc_lock); + s_info.request_list = dlist_append(s_info.request_list, item); + CRITICAL_SECTION_END(&s_info.file_svc_lock); + return 0; +} + +int file_service_init(void) +{ + int status; + GIOChannel *gio; + guint id; + + if (strncmp(client_addr(), COM_CORE_REMOTE_SCHEME, strlen(COM_CORE_REMOTE_SCHEME))) { + return 0; + } + + s_info.file_service_fd = file_service_open(); + if (s_info.file_service_fd < 0) { + return -EFAULT; + } + + if (pipe2(s_info.ctrl_pipe, O_NONBLOCK | O_CLOEXEC) < 0) { + ErrPrint("file service: %d\n", errno); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + return -EFAULT; + } + + if (pipe2(s_info.evt_pipe, O_NONBLOCK | O_CLOEXEC) < 0) { + ErrPrint("file service: %d\n", errno); + CLOSE_PIPE(s_info.ctrl_pipe); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + return -EFAULT; + } + + status = pthread_mutex_init(&s_info.file_svc_lock, NULL); + if (status != 0) { + ErrPrint("Mutex: %s\n", strerror(status)); + CLOSE_PIPE(s_info.ctrl_pipe); + CLOSE_PIPE(s_info.evt_pipe); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + return -EFAULT; + } + + gio = g_io_channel_unix_new(s_info.evt_pipe[PIPE_READ]); + if (!gio) { + ErrPrint("io channel new\n"); + status = pthread_mutex_destroy(&s_info.file_svc_lock); + if (status != 0) { + ErrPrint("destroy: %s\n", strerror(status)); + } + CLOSE_PIPE(s_info.ctrl_pipe); + CLOSE_PIPE(s_info.evt_pipe); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + return -EFAULT; + } + + g_io_channel_set_close_on_unref(gio, FALSE); + + id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)evt_cb, NULL); + if (id <= 0) { + GError *err = NULL; + ErrPrint("Failed to add IO watch\n"); + g_io_channel_shutdown(gio, TRUE, &err); + if (err) { + ErrPrint("Shutdown: %s\n", err->message); + g_error_free(err); + } + g_io_channel_unref(gio); + + status = pthread_mutex_destroy(&s_info.file_svc_lock); + if (status != 0) { + ErrPrint("destroy: %s\n", strerror(status)); + } + CLOSE_PIPE(s_info.ctrl_pipe); + CLOSE_PIPE(s_info.evt_pipe); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + return -EIO; + } + + status = pthread_create(&s_info.file_svc_thid, NULL, file_service_main, NULL); + if (status != 0) { + GError *err = NULL; + ErrPrint("Failed to add IO watch\n"); + g_io_channel_shutdown(gio, TRUE, &err); + if (err) { + ErrPrint("Shutdown: %s\n", err->message); + g_error_free(err); + } + g_io_channel_unref(gio); + + ErrPrint("file service: %s\n", strerror(status)); + CLOSE_PIPE(s_info.ctrl_pipe); + CLOSE_PIPE(s_info.evt_pipe); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + + status = pthread_mutex_destroy(&s_info.file_svc_lock); + if (status != 0) { + ErrPrint("destroy: %s\n", strerror(status)); + } + + return -EFAULT; + } + + g_io_channel_unref(gio); + return 0; +} + +int file_service_fini(void) +{ + void *svc_ret; + int ret; + + if (strncmp(client_addr(), COM_CORE_REMOTE_SCHEME, strlen(COM_CORE_REMOTE_SCHEME))) { + return 0; + } + + (void)put_event_ch(s_info.ctrl_pipe[PIPE_WRITE], EVT_END_CH); + + ret = pthread_join(s_info.file_svc_thid, &svc_ret); + if (ret != 0) { + ErrPrint("join: %s\n", strerror(ret)); + } else { + DbgPrint("file svc returns: %p\n", svc_ret); + } + + ret = pthread_mutex_destroy(&s_info.file_svc_lock); + if (ret != 0) { + ErrPrint("destroy: %s\n", strerror(ret)); + } + + CLOSE_PIPE(s_info.evt_pipe); + CLOSE_PIPE(s_info.ctrl_pipe); + + return 0; +} + +/* End of a file */ diff --git a/widget_viewer/src/master_rpc.c b/widget_viewer/src/master_rpc.c new file mode 100644 index 0000000..3457ebc --- /dev/null +++ b/widget_viewer/src/master_rpc.c @@ -0,0 +1,319 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include +#include +#include + +#include "debug.h" +#include "dlist.h" +#include "widget_viewer.h" +#include "widget_viewer_internal.h" +#include "master_rpc.h" +#include "client.h" +#include "util.h" + +#define DEFAULT_TTL 10 +#define REQUEST_DELAY 10 + +struct command { + int ttl; + struct packet *packet; + widget_h handler; + void (*ret_cb)(widget_h handler, const struct packet *result, void *data); + void *data; + enum { + TYPE_ACK, + TYPE_NOACK + } type; +}; + +int errno; + +static struct { + guint cmd_timer; + struct dlist *cmd_list; +} s_info = { + .cmd_timer = 0, + .cmd_list = NULL, +}; + +static int done_cb(pid_t pid, int handle, const struct packet *packet, void *data); + +static inline struct command *pop_command(void) +{ + struct dlist *l; + struct command *command; + + l = dlist_nth(s_info.cmd_list, 0); + if (!l) { + return NULL; + } + + command = dlist_data(l); + s_info.cmd_list = dlist_remove(s_info.cmd_list, l); + return command; +} + +static inline struct command *create_command(widget_h handler, struct packet *packet) +{ + struct command *command; + + command = malloc(sizeof(*command)); + if (!command) { + ErrPrint("Failed to allocate mem for command\n"); + return NULL; + } + + command->handler = _widget_ref(handler); + command->packet = packet_ref(packet); + return command; +} + +static inline void destroy_command(struct command *command) +{ + packet_unref(command->packet); + _widget_unref(command->handler, 1); + free(command); +} + +static gboolean cmd_consumer(gpointer user_data) +{ + struct command *command; + + command = pop_command(); + if (!command) { + s_info.cmd_timer = 0; + return FALSE; + } + + /*! + * \NOTE: + * Item will be deleted in the "done_cb" + * + * item->param be release by the g_dbus_proxy_call + * so to use it again from the done_cb function, + * increate the reference counter of the item->param + */ + if (command->type == TYPE_NOACK) { + if (com_core_packet_send_only(client_fd(), command->packet) < 0) { + ErrPrint("Failed to send a packet to master\n"); + } + + destroy_command(command); + } else { + if (com_core_packet_async_send(client_fd(), command->packet, 0u, done_cb, command) < 0) { + ErrPrint("Failed to send a packet to master\n"); + if (command->ret_cb) { + command->ret_cb(command->handler, NULL, command->data); + } + destroy_command(command); + } + } + return TRUE; +} + +static inline void prepend_command(struct command *command) +{ + s_info.cmd_list = dlist_prepend(s_info.cmd_list, command); + master_rpc_check_and_fire_consumer(); +} + +void master_rpc_check_and_fire_consumer(void) +{ + if (!s_info.cmd_list || s_info.cmd_timer || client_fd() < 0) { + return; + } + + s_info.cmd_timer = g_timeout_add(REQUEST_DELAY, cmd_consumer, NULL); + if (!s_info.cmd_timer) { + ErrPrint("Failed to add timer\n"); + } +} + +static int done_cb(pid_t pid, int handle, const struct packet *packet, void *data) +{ + struct command *command; + int ret; + + command = data; + + if (!packet) { + /*! \NOTE: + * Release resource even if + * we failed to finish the method call + */ + command->ttl--; + if (command->ttl > 0) { + prepend_command(command); + return 0; + } + + goto out; + } + + if (packet_get(packet, "i", &ret) != 1) { + ErrPrint("Invalid result packet\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + } + +out: + if (command->ret_cb) { + command->ret_cb(command->handler, packet, command->data); + } + + destroy_command(command); + return 0; +} + +static inline void push_command(struct command *command) +{ + s_info.cmd_list = dlist_append(s_info.cmd_list, command); + master_rpc_check_and_fire_consumer(); +} + +/*! + * \note + * "handler" could be NULL + */ +int master_rpc_async_request(widget_h handler, struct packet *packet, int urgent, void (*ret_cb)(widget_h handler, const struct packet *result, void *data), void *data) +{ + struct command *command; + + command = create_command(handler, packet); + if (!command) { + ErrPrint("Failed to create a command\n"); + packet_unref(packet); + return WIDGET_ERROR_FAULT; + } + + command->ret_cb = ret_cb; + command->data = data; + command->ttl = DEFAULT_TTL; + command->type = TYPE_ACK; + + if (urgent) { + prepend_command(command); + } else { + push_command(command); + } + + packet_unref(packet); + return WIDGET_ERROR_NONE; +} + +int master_rpc_request_only(widget_h handler, struct packet *packet) +{ + struct command *command; + + command = create_command(handler, packet); + if (!command) { + ErrPrint("Failed to create a command\n"); + packet_unref(packet); + return WIDGET_ERROR_FAULT; + } + + command->ret_cb = NULL; + command->data = NULL; + command->ttl = 0; + command->type = TYPE_NOACK; + + push_command(command); + packet_unref(packet); + return WIDGET_ERROR_NONE; +} + +int master_rpc_clear_fault_package(const char *pkgname) +{ + struct dlist *l; + struct dlist *n; + struct command *command; + + if (!pkgname) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + dlist_foreach_safe(s_info.cmd_list, l, n, command) { + if (!command->handler) { + continue; + } + + if (!strcmp(command->handler->common->pkgname, pkgname)) { + s_info.cmd_list = dlist_remove(s_info.cmd_list, l); + if (command->ret_cb) { + command->ret_cb(command->handler, NULL, command->data); + } + + destroy_command(command); + } + } + + return 0; +} + +int master_rpc_clear_all_request(void) +{ + struct command *command; + struct dlist *l; + struct dlist *n; + + dlist_foreach_safe(s_info.cmd_list, l, n, command) { + s_info.cmd_list = dlist_remove(s_info.cmd_list, l); + + if (command->ret_cb) { + command->ret_cb(command->handler, NULL, command->data); + } + + destroy_command(command); + } + + return 0; +} + +int master_rpc_sync_request(struct packet *packet) +{ + struct packet *result; + int ret; + + result = com_core_packet_oneshot_send(client_addr(), packet, 0.0f); + if (result) { + if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid result packet\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + } + + packet_unref(result); + } else { + ErrPrint("Failed to send a sync request\n"); + ret = WIDGET_ERROR_FAULT; + } + + packet_unref(packet); + return ret; +} + +/* End of a file */ diff --git a/widget_viewer/src/util.c b/widget_viewer/src/util.c new file mode 100644 index 0000000..c9cc01d --- /dev/null +++ b/widget_viewer/src/util.c @@ -0,0 +1,150 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include /* For error code */ + +#include "debug.h" +#include "util.h" + +int errno; +#if defined(_USE_ECORE_TIME_GET) +static struct { + clockid_t type; +} s_info = { + .type = CLOCK_MONOTONIC, +}; +#endif + +int util_check_extension(const char *filename, const char *check_ptr) +{ + int name_len; + + name_len = strlen(filename); + while (--name_len >= 0 && *check_ptr) { + if (filename[name_len] != *check_ptr) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + check_ptr++; + } + + return 0; +} + +double util_timestamp(void) +{ +#if defined(_USE_ECORE_TIME_GET) + struct timespec ts; + + do { + if (clock_gettime(s_info.type, &ts) == 0) { + return ts.tv_sec + ts.tv_nsec / 1000000000.0f; + } + + ErrPrint("%d: %d\n", s_info.type, errno); + if (s_info.type == CLOCK_MONOTONIC) { + s_info.type = CLOCK_REALTIME; + } else if (s_info.type == CLOCK_REALTIME) { + struct timeval tv; + if (gettimeofday(&tv, NULL) < 0) { + ErrPrint("gettimeofday: %d\n", errno); + break; + } + + return tv.tv_sec + tv.tv_usec / 1000000.0f; + } + } while (1); + + return 0.0f; +#else + struct timeval tv; + + if (gettimeofday(&tv, NULL) < 0) { + ErrPrint("gettimeofday: %d\n", errno); + tv.tv_sec = 0; + tv.tv_usec = 0; + } + + return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f; +#endif +} + +const char *util_basename(const char *name) +{ + int length; + length = name ? strlen(name) : 0; + if (!length) { + return "."; + } + + while (--length > 0 && name[length] != '/'); + + return length <= 0 ? name : name + length + (name[length] == '/'); +} + +const char *util_uri_to_path(const char *uri) +{ + int len; + + len = strlen(SCHEMA_FILE); + if (strncasecmp(uri, SCHEMA_FILE, len)) { + return NULL; + } + + return uri + len; +} + +int util_unlink(const char *filename) +{ + char *descfile; + int desclen; + int ret; + + if (!filename) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + desclen = strlen(filename) + 6; /* .desc */ + descfile = malloc(desclen); + if (!descfile) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + ret = snprintf(descfile, desclen, "%s.desc", filename); + if (ret < 0) { + ErrPrint("Error: %d\n", errno); + free(descfile); + return WIDGET_ERROR_FAULT; + } + + (void)unlink(descfile); + free(descfile); + (void)unlink(filename); + + return WIDGET_ERROR_NONE; +} + +/* End of a file */ diff --git a/widget_viewer/src/widget.c b/widget_viewer/src/widget.c new file mode 100644 index 0000000..0adcd84 --- /dev/null +++ b/widget_viewer/src/widget.c @@ -0,0 +1,4228 @@ +/* + * Copyright 2014 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 /* malloc */ +#include /* strdup */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "fb.h" +#include "widget_viewer.h" +#include "widget_viewer_internal.h" +#include "dlist.h" +#include "util.h" +#include "master_rpc.h" +#include "client.h" +#include "conf.h" + +#define EAPI __attribute__((visibility("default"))) +#if !defined(WIDGET_COUNT_OF_SIZE_TYPE) + #define WIDGET_COUNT_OF_SIZE_TYPE 13 +#endif + +#if defined(FLOG) +FILE *__file_log_fp; +#endif + +static int default_launch_handler(widget_h handle, const char *appid, void *data); + +static struct info { + int init_count; + int prevent_overwrite; + guint job_timer; + struct dlist *job_list; + + struct launch { + int (*handle)(widget_h handle, const char *appid, void *data); + void *data; + } launch; +} s_info = { + .init_count = 0, + .prevent_overwrite = 0, + .job_timer = 0, + .job_list = NULL, + .launch = { + .handle = default_launch_handler, + .data = NULL, + }, +}; + +static void widget_pixmap_acquired_cb(widget_h handle, const struct packet *result, void *data); +static void gbar_pixmap_acquired_cb(widget_h handle, const struct packet *result, void *data); +static void gbar_xpixmap_acquired_cb(widget_h handle, const struct packet *result, void *data); +static void widget_xpixmap_acquired_cb(widget_h handle, const struct packet *result, void *data); + +static int default_launch_handler(widget_h handle, const char *appid, void *data) +{ + int ret; + + ret = aul_launch_app(appid, NULL); + if (ret <= 0) { + ErrPrint("Failed to launch an app %s (%d)\n", appid, ret); + } + + /* + app_control_h service; + + DbgPrint("AUTO_LAUNCH [%s]\n", handle->common->widget.auto_launch); + + ret = app_control_create(&service); + if (ret == APP_CONTROL_ERROR_NONE) { + app_control_set_package(service, handle->common->widget.auto_launch); + app_control_send_launch_request(service, NULL, NULL); + app_control_destroy(service); + } else { + ErrPrint("Failed to launch an app %s (%d)\n", handle->common->widget.auto_launch, ret); + } + */ + + return ret > 0 ? WIDGET_ERROR_NONE : WIDGET_ERROR_FAULT; +} + +static inline void default_create_cb(widget_h handle, int ret, void *data) +{ + DbgPrint("Default created event handle: %d\n", ret); +} + +static inline void default_pinup_cb(widget_h handle, int ret, void *data) +{ + DbgPrint("Default pinup event handle: %d\n", ret); +} + +static inline void default_group_changed_cb(widget_h handle, int ret, void *data) +{ + DbgPrint("Default group changed event handle: %d\n", ret); +} + +static inline void default_period_changed_cb(widget_h handle, int ret, void *data) +{ + DbgPrint("Default period changed event handle: %d\n", ret); +} + +static inline void default_gbar_created_cb(widget_h handle, int ret, void *data) +{ + DbgPrint("Default GBAR created event handle: %d\n", ret); +} + +static inline void default_gbar_destroyed_cb(widget_h handle, int ret, void *data) +{ + DbgPrint("Default GBAR destroyed event handle: %d\n", ret); +} + +static inline void default_widget_size_changed_cb(widget_h handle, int ret, void *data) +{ + DbgPrint("Default WIDGET size changed event handle: %d\n", ret); +} + +static inline void default_update_mode_cb(widget_h handle, int ret, void *data) +{ + DbgPrint("Default update mode set event handle: %d\n", ret); +} + +static inline void default_access_event_cb(widget_h handle, int ret, void *data) +{ + DbgPrint("Default access event handle: %d\n", ret); +} + +static inline void default_key_event_cb(widget_h handle, int ret, void *data) +{ + DbgPrint("Default key event handle: %d\n", ret); +} + +static void update_mode_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = WIDGET_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto errout; + } + + if (ret < 0) { + ErrPrint("Resize request is failed: %d\n", ret); + goto errout; + } + + return; + +errout: + handle->cbs.update_mode.cb(handle, ret, handle->cbs.update_mode.data); + handle->cbs.update_mode.cb = NULL; + handle->cbs.update_mode.data = NULL; + handle->common->request.update_mode = 0; + + if (handle->common->state != WIDGET_STATE_DELETE) { + if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } +} + +static void resize_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = WIDGET_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto errout; + } + + /*! + * \note + * In case of resize request, + * The widget handle will not have resized value right after this callback, + * It can only get the new size when it makes updates. + * + * So the user can only get the resized value(result) from the first update event + * after this request. + */ + if (ret < 0) { + ErrPrint("Resize request is failed: %d\n", ret); + goto errout; + } + + return; + +errout: + handle->cbs.size_changed.cb(handle, ret, handle->cbs.size_changed.data); + handle->cbs.size_changed.cb = NULL; + handle->cbs.size_changed.data = NULL; + handle->common->request.size_changed = 0; + + if (handle->common->state != WIDGET_STATE_DELETE) { + if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } +} + +static void text_signal_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + void *cbdata; + struct cb_info *info = data; + widget_ret_cb cb; + + cbdata = info->data; + cb = info->cb; + _widget_destroy_cb_info(info); + + if (!result) { + ret = WIDGET_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + } + + if (cb) { + cb(handle, ret, cbdata); + } + return; +} + +static void set_group_ret_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = WIDGET_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto errout; + } + + if (ret < 0) { + goto errout; + } + + return; + +errout: + handle->cbs.group_changed.cb(handle, ret, handle->cbs.group_changed.data); + handle->cbs.group_changed.cb = NULL; + handle->cbs.group_changed.data = NULL; + handle->common->request.group_changed = 0; + + if (handle->common->state != WIDGET_STATE_DELETE) { + if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } +} + +static void period_ret_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = WIDGET_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto errout; + } + + if (ret < 0) { + goto errout; + } + + return; + +errout: + handle->cbs.period_changed.cb(handle, ret, handle->cbs.period_changed.data); + handle->cbs.period_changed.cb = NULL; + handle->cbs.period_changed.data = NULL; + handle->common->request.period_changed = 0; + + if (handle->common->state != WIDGET_STATE_DELETE) { + if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } +} + +static void gbar_create_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = WIDGET_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto errout; + } + + if (ret < 0) { + ErrPrint("Failed to create a GBAR[%d]\n", ret); + goto errout; + } + + return; + +errout: + handle->cbs.gbar_created.cb(handle, ret, handle->cbs.gbar_created.data); + handle->cbs.gbar_created.cb = NULL; + handle->cbs.gbar_created.data = NULL; + handle->common->request.gbar_created = 0; + + if (handle->common->state != WIDGET_STATE_DELETE) { + if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } +} + +static void activated_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + struct cb_info *info = data; + void *cbdata; + widget_ret_cb cb; + const char *pkgname = ""; + + cbdata = info->data; + cb = info->cb; + _widget_destroy_cb_info(info); + + if (!result) { + ret = WIDGET_ERROR_FAULT; + } else if (packet_get(result, "is", &ret, &pkgname) != 2) { + ret = WIDGET_ERROR_INVALID_PARAMETER; + } + + if (cb) { + cb(handle, ret, cbdata); + } +} + +static void gbar_destroy_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + widget_ret_cb cb; + void *cbdata; + struct cb_info *info = data; + + cbdata = info->data; + cb = info->cb; + _widget_destroy_cb_info(info); + + if (!result) { + ErrPrint("Result is NIL (may connection lost)\n"); + ret = WIDGET_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid parameter\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + } + + if (ret == (int)WIDGET_ERROR_NONE) { + handle->cbs.gbar_destroyed.cb = cb; + handle->cbs.gbar_destroyed.data = cbdata; + } else { + handle->common->is_gbar_created = 0; + handle->common->request.gbar_destroyed = 0; + + if (cb) { + cb(handle, ret, cbdata); + } + } +} + +static void _delete_cluster_cb(widget_h handle, const struct packet *result, void *data) +{ + struct cb_info *info = data; + int ret; + widget_ret_cb cb; + void *cbdata; + + cb = info->cb; + cbdata = info->data; + _widget_destroy_cb_info(info); + + if (!result) { + ret = WIDGET_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ret = WIDGET_ERROR_INVALID_PARAMETER; + } + + if (cb) { + cb(handle, ret, cbdata); + } +} + +static void _delete_category_cb(widget_h handle, const struct packet *result, void *data) +{ + struct cb_info *info = data; + int ret; + widget_ret_cb cb; + void *cbdata; + + cb = info->cb; + cbdata = info->data; + _widget_destroy_cb_info(info); + + if (!result) { + ret = WIDGET_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ret = WIDGET_ERROR_INVALID_PARAMETER; + } + + if (cb) { + cb(handle, ret, cbdata); + } +} + +static int _widget_acquire_widget_pixmap(widget_h handle, widget_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + const char *id; + unsigned int cmd = CMD_WIDGET_ACQUIRE_PIXMAP; + int ret; + + id = fb_id(handle->common->widget.fb); + if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + packet = packet_create((const char *)&cmd, "ss", handle->common->pkgname, handle->common->id); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_async_request(handle, packet, 0, widget_pixmap_acquired_cb, cbinfo); + if (ret < 0) { + _widget_destroy_cb_info(cbinfo); + } + + return ret; +} + +static void widget_pixmap_acquired_cb(widget_h handle, const struct packet *result, void *data) +{ + int pixmap; + int ret = WIDGET_ERROR_INVALID_PARAMETER; + widget_ret_cb cb; + void *cbdata; + struct cb_info *info = data; + + cb = info->cb; + cbdata = info->data; + _widget_destroy_cb_info(info); + + if (!result) { + pixmap = 0; /* PIXMAP 0 means error */ + } else if (packet_get(result, "ii", &pixmap, &ret) != 2) { + pixmap = 0; + } + + if (ret == (int)WIDGET_ERROR_RESOURCE_BUSY) { + ret = _widget_acquire_widget_pixmap(handle, cb, cbdata); + DbgPrint("Busy, Try again: %d\n", ret); + /* Try again */ + } else if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + if (cb) { + cb(handle, pixmap, cbdata); + } + + if (handle->common->state != WIDGET_STATE_DELETE) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } else { + if (cb) { + cb(handle, pixmap, cbdata); + } + } +} + +static void widget_xpixmap_acquired_cb(widget_h handle, const struct packet *result, void *data) +{ + int pixmap; + int ret = WIDGET_ERROR_INVALID_PARAMETER; + widget_ret_cb cb; + void *cbdata; + struct cb_info *info = data; + + cb = info->cb; + cbdata = info->data; + _widget_destroy_cb_info(info); + + if (!result) { + pixmap = 0; + } else if (packet_get(result, "ii", &pixmap, &ret) != 2) { + pixmap = 0; + } + + if (cb) { + cb(handle, pixmap, cbdata); + } + + if (handle->common->state != WIDGET_STATE_DELETE) { + if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } +} + +static int widget_acquire_gbar_extra_pixmap(widget_h handle, int idx, widget_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_GBAR_ACQUIRE_XPIXMAP; + int ret; + + packet = packet_create((const char *)&cmd, "ssi", handle->common->pkgname, handle->common->id, idx); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_async_request(handle, packet, 0, gbar_xpixmap_acquired_cb, cbinfo); + if (ret < 0) { + /*! + * \note + * Packet will be destroyed by master_rpc_async_request + */ + _widget_destroy_cb_info(cbinfo); + } + + return ret; +} + +static int widget_acquire_widget_extra_pixmap(widget_h handle, int idx, widget_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_WIDGET_ACQUIRE_XPIXMAP; + int ret; + + packet = packet_create((const char *)&cmd, "ssi", handle->common->pkgname, handle->common->id, idx); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_async_request(handle, packet, 0, widget_xpixmap_acquired_cb, cbinfo); + if (ret < 0) { + /*! + * \note + * Packet will be destroyed by master_rpc_async_request + */ + _widget_destroy_cb_info(cbinfo); + } + + return ret; +} + +static int widget_acquire_gbar_pixmap(widget_h handle, widget_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_GBAR_ACQUIRE_PIXMAP; + const char *id; + int ret; + + id = fb_id(handle->common->gbar.fb); + if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + packet = packet_create((const char *)&cmd, "ss", handle->common->pkgname, handle->common->id); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_async_request(handle, packet, 0, gbar_pixmap_acquired_cb, cbinfo); + if (ret < 0) { + /*! + * \note + * Packet will be destroyed by master_rpc_async_request + */ + _widget_destroy_cb_info(cbinfo); + } + + return ret; +} + +static void gbar_xpixmap_acquired_cb(widget_h handle, const struct packet *result, void *data) +{ + int pixmap; + int ret; + widget_ret_cb cb; + void *cbdata; + struct cb_info *info = data; + + cb = info->cb; + cbdata = info->data; + _widget_destroy_cb_info(info); + + if (!result) { + pixmap = 0; /* PIXMAP 0 means error */ + ret = WIDGET_ERROR_FAULT; + } else if (packet_get(result, "ii", &pixmap, &ret) != 2) { + pixmap = 0; + ret = WIDGET_ERROR_INVALID_PARAMETER; + } + + if (cb) { + DbgPrint("ret: %x, pixmap: %d\n", ret, pixmap); + cb(handle, pixmap, cbdata); + } + + if (handle->common->state != WIDGET_STATE_DELETE) { + if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } +} + +static void gbar_pixmap_acquired_cb(widget_h handle, const struct packet *result, void *data) +{ + int pixmap; + int ret; + widget_ret_cb cb; + void *cbdata; + struct cb_info *info = data; + + cb = info->cb; + cbdata = info->data; + _widget_destroy_cb_info(info); + + if (!result) { + pixmap = 0; /* PIXMAP 0 means error */ + ret = WIDGET_ERROR_FAULT; + } else if (packet_get(result, "ii", &pixmap, &ret) != 2) { + pixmap = 0; + ret = WIDGET_ERROR_INVALID_PARAMETER; + } + + if (ret == (int)WIDGET_ERROR_RESOURCE_BUSY) { + ret = widget_acquire_gbar_pixmap(handle, cb, cbdata); + DbgPrint("Busy, Try again: %d\n", ret); + /* Try again */ + } else if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + if (cb) { + cb(handle, pixmap, cbdata); + } + + if (handle->common->state != WIDGET_STATE_DELETE) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } else { + if (cb) { + DbgPrint("ret: %d, pixmap: %d\n", ret, pixmap); + cb(handle, pixmap, cbdata); + } + } +} + +static void pinup_done_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = WIDGET_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + goto errout; + } + + if (ret < 0) { + goto errout; + } + + return; + +errout: + handle->cbs.pinup.cb(handle, ret, handle->cbs.pinup.data); + handle->cbs.pinup.cb = NULL; + handle->cbs.pinup.data = NULL; + handle->common->request.pinup = 0; + + if (handle->common->state != WIDGET_STATE_DELETE) { + if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } +} + +static void key_ret_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = WIDGET_ERROR_FAULT; + return; + } + + if (packet_get(result, "i", &ret) != 1) { + ret = WIDGET_ERROR_INVALID_PARAMETER; + return; + } + + if (ret != WIDGET_ERROR_NONE) { + goto errout; + } + + return; +errout: + handle->cbs.key_event.cb(handle, ret, handle->cbs.key_event.data); + handle->cbs.key_event.cb = NULL; + handle->cbs.key_event.data = NULL; + handle->common->request.key_event = 0; + + if (handle->common->state != WIDGET_STATE_DELETE) { + if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } +} + +static void access_ret_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = WIDGET_ERROR_FAULT; + return; + } + + if (packet_get(result, "i", &ret) != 1) { + ret = WIDGET_ERROR_INVALID_PARAMETER; + return; + } + + if (ret != WIDGET_ERROR_NONE) { + goto errout; + } + + return; + +errout: + handle->cbs.access_event.cb(handle, ret, handle->cbs.access_event.data); + handle->cbs.access_event.cb = NULL; + handle->cbs.access_event.data = NULL; + handle->common->request.access_event = 0; + + if (handle->common->state != WIDGET_STATE_DELETE) { + if (ret == (int)WIDGET_ERROR_NOT_EXIST && handle->refcnt == 2) { + _widget_invoke_event_handler(handle, WIDGET_EVENT_DELETED); + _widget_unref(handle, 1); + } + } +} + +static int send_access_event(widget_h handle, const char *event, int x, int y, int type) +{ + struct packet *packet; + double timestamp; + + timestamp = util_timestamp(); + + packet = packet_create(event, "ssdiii", handle->common->pkgname, handle->common->id, timestamp, x, y, type); + if (!packet) { + ErrPrint("Failed to build packet\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_async_request(handle, packet, 0, access_ret_cb, NULL); +} + +static int send_key_event(widget_h handle, const char *event, unsigned int keycode, int device) +{ + struct packet *packet; + double timestamp; + + timestamp = util_timestamp(); + packet = packet_create(event, "ssdii", handle->common->pkgname, handle->common->id, timestamp, keycode, device); + if (!packet) { + ErrPrint("Failed to build packet\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_async_request(handle, packet, 0, key_ret_cb, NULL); +} + +static int send_mouse_event(widget_h handle, const char *event, int x, int y, double ratio_w, double ratio_h, int device) +{ + struct packet *packet; + double timestamp; + + timestamp = util_timestamp(); + packet = packet_create_noack(event, "ssdiiiddi", handle->common->pkgname, handle->common->id, timestamp, x, y, INPUT_EVENT_SOURCE_VIEWER, ratio_w, ratio_h, device); + if (!packet) { + ErrPrint("Failed to build param\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(handle, packet); +} + +static int initialize_widget(void *disp, int use_thread) +{ + int ret; +#if defined(FLOG) + char filename[BUFSIZ]; + snprintf(filename, sizeof(filename), "/tmp/%d.box.log", getpid()); + __file_log_fp = fopen(filename, "w+t"); + if (!__file_log_fp) { + __file_log_fp = fdopen(1, "w+t"); + } +#endif + ret = widget_service_init(); + if (ret != WIDGET_ERROR_NONE) { + return ret; + } + + ret = fb_init(disp); + if (ret != WIDGET_ERROR_NONE) { + widget_service_fini(); + return ret; + } + + ret = client_init(use_thread); + if (ret != WIDGET_ERROR_NONE) { + fb_fini(); + widget_service_fini(); + return ret; + } + + s_info.init_count++; + return ret; +} + +static inline char *_widget_pkgname(const char *pkgname) +{ + char *widget; + + widget = widget_service_get_widget_id(pkgname); + if (!widget) { + widget = strdup(pkgname); + } + + return widget; +} + +static gboolean job_execute_cb(void *data) +{ + struct job_item *item; + struct dlist *l; + + l = dlist_nth(s_info.job_list, 0); + if (!l) { + s_info.job_timer = 0; + return FALSE; + } + + item = dlist_data(l); + s_info.job_list = dlist_remove(s_info.job_list, l); + + if (item) { + item->cb(item->handle, item->ret, item->data); + _widget_unref(item->handle, 1); + free(item); + } + + return TRUE; +} + +static int job_add(widget_h handle, widget_ret_cb job_cb, int ret, void *data) +{ + struct job_item *item; + + if (!job_cb) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + item = malloc(sizeof(*item)); + if (!item) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + item->handle = _widget_ref(handle); + item->cb = job_cb; + item->data = data; + item->ret = ret; + + s_info.job_list = dlist_append(s_info.job_list, item); + + if (!s_info.job_timer) { + s_info.job_timer = g_timeout_add(1, job_execute_cb, NULL); + if (!s_info.job_timer) { + ErrPrint("Failed to create a job timer\n"); + } + } + + return WIDGET_ERROR_NONE; +} + +static void new_ret_cb(widget_h handle, const struct packet *result, void *data) +{ + int ret; + struct cb_info *info = data; + widget_ret_cb cb; + void *cbdata; + + cb = info->cb; + cbdata = info->data; + _widget_destroy_cb_info(info); + + if (!result) { + ret = WIDGET_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ret = WIDGET_ERROR_INVALID_PARAMETER; + } + + if (ret >= 0) { + handle->cbs.created.cb = cb; + handle->cbs.created.data = cbdata; + + /*! + * \note + * Don't go anymore ;) + */ + return; + } else if (cb) { + /*! + * \note + * It means the current instance is not created, + * so user has to know about this. + * notice it to user using "deleted" event. + */ + cb(handle, ret, cbdata); + } + + _widget_unref(handle, 1); +} + +static int create_real_instance(widget_h handle, widget_ret_cb cb, void *data) +{ + struct cb_info *cbinfo; + struct packet *packet; + struct widget_common *common; + unsigned int cmd = CMD_NEW; + int ret; + + common = handle->common; + + packet = packet_create((const char *)&cmd, "dssssdii", + common->timestamp, common->pkgname, common->content, + common->cluster, common->category, + common->widget.period, common->widget.width, common->widget.height); + if (!packet) { + ErrPrint("Failed to create a new packet\n"); + set_last_result(WIDGET_ERROR_FAULT); + return WIDGET_ERROR_FAULT; + } + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + ErrPrint("Failed to create a cbinfo\n"); + packet_destroy(packet); + set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + /*! + * \note + * master_rpc_async_request will destroy the packet (decrease the refcnt) + * So be aware the packet object after return from master_rpc_async_request. + */ + ret = master_rpc_async_request(handle, packet, 0, new_ret_cb, cbinfo); + if (ret < 0) { + ErrPrint("Failed to send a new packet\n"); + _widget_destroy_cb_info(cbinfo); + set_last_result(WIDGET_ERROR_FAULT); + return WIDGET_ERROR_FAULT; + } + handle->common->request.created = 1; + return WIDGET_ERROR_NONE; +} + +static void create_cb(widget_h handle, int ret, void *data) +{ + struct cb_info *cbinfo = data; + + if (cbinfo->cb) { + cbinfo->cb(handle, ret, cbinfo->data); + } + + _widget_destroy_cb_info(cbinfo); + + /*! + * \note + * Forcely generate "updated" event + */ + _widget_invoke_event_handler(handle, WIDGET_EVENT_WIDGET_UPDATED); +} + +static int create_fake_instance(widget_h handle, widget_ret_cb cb, void *data) +{ + struct cb_info *cbinfo; + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + ErrPrint("Failed to create a cbinfo\n"); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + if (job_add(handle, create_cb, WIDGET_ERROR_NONE, cbinfo) != WIDGET_ERROR_NONE) { + _widget_destroy_cb_info(cbinfo); + } + + return WIDGET_ERROR_NONE; +} + +static void refresh_for_paused_updating_cb(widget_h handle, int ret, void *data) +{ + if (handle->paused_updating == 0) { + DbgPrint("Paused updates are cleared\n"); + return; + } + + DbgPrint("Pending updates are found\n"); + _widget_invoke_event_handler(handle, WIDGET_EVENT_WIDGET_UPDATED); +} + +static int _widget_set_visibility(widget_h handle, widget_visible_state_e state) +{ + struct packet *packet; + int need_to_add_job = 0; + unsigned int cmd = CMD_CHANGE_VISIBILITY; + int ret; + + if (handle->common->visible != WIDGET_SHOW && state == WIDGET_SHOW) { + need_to_add_job = !!handle->paused_updating; + } else if (handle->common->visible == WIDGET_SHOW && state != WIDGET_SHOW) { + if (!!_widget_find_widget_in_show(handle->common)) { + return WIDGET_ERROR_NONE; + } + } else if (handle->common->visible == WIDGET_SHOW && state == WIDGET_SHOW && handle->paused_updating) { + if (job_add(handle, refresh_for_paused_updating_cb, WIDGET_ERROR_NONE, NULL) < 0) { + ErrPrint("Unable to add a new job for refreshing box\n"); + } + + return WIDGET_ERROR_NONE; + } else { + /*! + * \brief + * No need to send this to the master + */ + return WIDGET_ERROR_NONE; + } + + packet = packet_create_noack((const char *)&cmd, "ssi", handle->common->pkgname, handle->common->id, (int)state); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_request_only(handle, packet); + if (ret == (int)WIDGET_ERROR_NONE) { + DbgPrint("[%s] visibility is changed 0x[%x]\n", handle->common->pkgname, state); + handle->common->visible = state; + + if (need_to_add_job) { + if (job_add(handle, refresh_for_paused_updating_cb, WIDGET_ERROR_NONE, NULL) < 0) { + ErrPrint("Unable to add a new job for refreshing box\n"); + } + } + } + + return ret; +} + +static void _widget_update_visibility(struct widget_common *old_common) +{ + widget_h item; + + item = _widget_find_widget_in_show(old_common); + if (!item) { + item = _widget_get_widget_nth(old_common, 0); + if (item) { + _widget_set_visibility(item, WIDGET_HIDE_WITH_PAUSE); + } else { + ErrPrint("Unable to get the valid handle from common handle\n"); + } + } else { + _widget_set_visibility(item, WIDGET_SHOW); + } +} + +/*! + * \note + * The second parameter should be the "return value", + * But in this case, we will use it for "type of deleting instance". + */ +static void _job_del_cb(widget_h handle, int type, void *data) +{ + struct cb_info *cbinfo = data; + widget_ret_cb cb; + + if (handle->visible == WIDGET_SHOW) { + _widget_update_visibility(handle->common); + } + + cb = cbinfo->cb; + data = cbinfo->data; + _widget_destroy_cb_info(cbinfo); + + if (handle->common->state != WIDGET_STATE_CREATE) { + DbgPrint("[%s] %d\n", handle->common->pkgname, handle->refcnt); + if (cb) { + cb(handle, WIDGET_ERROR_NONE, data); + } + + return; + } + + if (handle->common->refcnt == 1) { + handle->common->delete_type = type; + handle->common->state = WIDGET_STATE_DELETE; + + if (!handle->common->id) { + /*! + * \note + * The id is not determined yet. + * It means a user didn't receive created event yet. + * Then just stop to delete procedure from here. + * Because the "created" event handle will release this. + * By the way, if the user adds any callback for getting return status of this, + * call it at here. + */ + if (cb) { + cb(handle, WIDGET_ERROR_NONE, data); + } + } + + DbgPrint("Send delete request\n"); + _widget_send_delete(handle, type, cb, data); + } else { + if (cb) { + cb(handle, WIDGET_ERROR_NONE, data); + } + + DbgPrint("Before unref: %d\n", handle->common->refcnt); + _widget_unref(handle, 1); + } +} + +static void _resize_job_cb(widget_h handle, int ret, void *data) +{ + struct cb_info *info = data; + + if (info->cb) { + info->cb(handle, ret, info->data); + } + + free(info); + + /*! + * \note + * Forcely update the box + */ + _widget_invoke_event_handler(handle, WIDGET_EVENT_WIDGET_UPDATED); +} + +static void _turn_off_gbar_destroyed_flag_cb(widget_h handle, int ret, void *data) +{ + if (handle->common->request.gbar_destroyed) { + widget_ret_cb cb; + void *data; + + DbgPrint("gbar_destroyed request is canceled\n"); + handle->common->request.gbar_destroyed = 0; + cb = handle->cbs.gbar_destroyed.cb; + data = handle->cbs.gbar_destroyed.data; + handle->cbs.gbar_destroyed.cb = NULL; + handle->cbs.gbar_destroyed.data = NULL; + + if (cb) { + cb(handle, ret, data); + } + } +} + +static void _turn_off_gbar_created_flag_cb(widget_h handle, int ret, void *data) +{ + if (handle->common->request.gbar_created) { + widget_ret_cb cb; + void *data; + + DbgPrint("gbar_created request is canceled\n"); + handle->common->request.gbar_created = 0; + cb = handle->cbs.gbar_created.cb; + data = handle->cbs.gbar_created.data; + handle->cbs.gbar_created.cb = NULL; + handle->cbs.gbar_created.data = NULL; + + if (cb) { + cb(handle, ret, data); + } + } +} + +EAPI int widget_viewer_init(void *disp, int prevent_overwrite, double event_filter, int use_thread) +{ + if (s_info.init_count > 0) { + s_info.init_count++; + return WIDGET_ERROR_NONE; + } + + /*! + * \note + * Some application doesn't want to use the environment value. + * So set them using arguments. + */ + s_info.prevent_overwrite = prevent_overwrite; + conf_set_event_filter(event_filter); + + return initialize_widget(disp, use_thread); +} + +EAPI int widget_viewer_fini(void) +{ + if (s_info.init_count <= 0) { + ErrPrint("Doesn't initialized\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + s_info.init_count--; + if (s_info.init_count > 0) { + ErrPrint("init count : %d\n", s_info.init_count); + return WIDGET_ERROR_NONE; + } + + client_fini(); + fb_fini(); + widget_service_fini(); + return WIDGET_ERROR_NONE; +} + +EAPI widget_h widget_viewer_add_widget(const char *pkgname, const char *content, const char *cluster, const char *category, double period, widget_size_type_e type, widget_ret_cb cb, void *data) +{ + char *widgetid; + widget_h handle; + int w = 0; + int h = 0; + + if (!pkgname || !cluster || !category) { + ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n", + pkgname, cluster, category); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + widgetid = _widget_pkgname(pkgname); + if (!widgetid) { + ErrPrint("Invalid package: %s\n", pkgname); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (widget_service_is_enabled(widgetid) == 0) { + DbgPrint("Livebox [%s](%s) is disabled package\n", widgetid, pkgname); + free(widgetid); + set_last_result(WIDGET_ERROR_DISABLED); + return NULL; + } + + if (type != WIDGET_SIZE_TYPE_UNKNOWN) { + (void)widget_service_get_size(type, &w, &h); + } + + handle = calloc(1, sizeof(*handle)); + if (!handle) { + ErrPrint("Error: %d\n", errno); + free(widgetid); + set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); + return NULL; + } + + if (!cb) { + cb = default_create_cb; + } + + handle->common = _widget_find_sharable_common_handle(widgetid, content, w, h, cluster, category); + if (!handle->common) { + handle->common = _widget_create_common_handle(handle, widgetid, cluster, category); + free(widgetid); + if (!handle->common) { + ErrPrint("Failed to find common handle\n"); + free(handle); + return NULL; + } + + if (!content || !strlen(content)) { + char *pc; + /** + * @note + * I know the content should not be modified. use it temporarly without "const" + */ + pc = widget_service_get_content_string(handle->common->pkgname); + _widget_set_content(handle->common, pc); + free(pc); + } else { + _widget_set_content(handle->common, content); + } + + _widget_set_period(handle->common, period); + _widget_set_size(handle->common, w, h); + _widget_common_ref(handle->common, handle); + + if (create_real_instance(handle, cb, data) < 0) { + if (_widget_common_unref(handle->common, handle) == 0) { + /*! + * Delete common + */ + _widget_destroy_common_handle(handle->common); + handle->common = NULL; + } + free(handle); + return NULL; + } + } else { + free(widgetid); + + _widget_common_ref(handle->common, handle); + + if (handle->common->request.created) { + /*! + * If a box is in creating, wait its result too + */ + handle->cbs.created.cb = cb; + handle->cbs.created.data = data; + } else { + /*! + * or fire the fake created_event + */ + if (create_fake_instance(handle, cb, data) < 0) { + if (_widget_common_unref(handle->common, handle) == 0) { + /*! + * Delete common + */ + _widget_destroy_common_handle(handle->common); + } + free(handle); + return NULL; + } + } + } + + handle->visible = WIDGET_HIDE_WITH_PAUSE; + handle->state = WIDGET_STATE_CREATE; + handle = _widget_ref(handle); + + return handle; +} + +EAPI int widget_viewer_get_period(widget_h handle, double *period) +{ + int ret = WIDGET_ERROR_NONE; + double result_period = -1.0f; + + if (!handle || handle->state != WIDGET_STATE_CREATE || period == NULL) { + ErrPrint("Handler is not valid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + if (!handle->common->id) { + ErrPrint("Hnalder is not valid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + result_period = handle->common->widget.period; + +out: + if (period) + *period = result_period; + + return ret; +} + +EAPI int widget_viewer_set_period(widget_h handle, double period, widget_ret_cb cb, void *data) +{ + struct packet *packet; + unsigned int cmd = CMD_SET_PERIOD; + int ret; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->common->request.period_changed) { + ErrPrint("Previous request for changing period is not finished\n"); + return WIDGET_ERROR_RESOURCE_BUSY; + } + + if (!handle->common->is_user) { + ErrPrint("CA Livebox is not able to change the period\n"); + return WIDGET_ERROR_PERMISSION_DENIED; + } + + if (handle->common->widget.period == period) { + DbgPrint("No changes\n"); + return WIDGET_ERROR_ALREADY_EXIST; + } + + packet = packet_create((const char *)&cmd, "ssd", handle->common->pkgname, handle->common->id, period); + if (!packet) { + ErrPrint("Failed to build a packet %s\n", handle->common->pkgname); + return WIDGET_ERROR_FAULT; + } + + if (!cb) { + cb = default_period_changed_cb; + } + + ret = master_rpc_async_request(handle, packet, 0, period_ret_cb, NULL); + if (ret == (int)WIDGET_ERROR_NONE) { + handle->cbs.period_changed.cb = cb; + handle->cbs.period_changed.data = data; + handle->common->request.period_changed = 1; + } + + return ret; +} + +EAPI int widget_viewer_delete_widget(widget_h handle, widget_delete_type_e type, widget_ret_cb cb, void *data) +{ + struct cb_info *cbinfo; + + if (!handle) { + ErrPrint("Handler is NIL\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is already deleted\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + handle->state = WIDGET_STATE_DELETE; + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + ErrPrint("Failed to create a cbinfo\n"); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + if (job_add(handle, _job_del_cb, type, cbinfo) != WIDGET_ERROR_NONE) { + ErrPrint("Failed to add a new job\n"); + _widget_destroy_cb_info(cbinfo); + return WIDGET_ERROR_FAULT; + } + + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_add_fault_handler(widget_fault_handler_cb widget_cb, void *data) +{ + if (!widget_cb) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return _widget_add_fault_handler(widget_cb, data); +} + +EAPI void *widget_viewer_remove_fault_handler(widget_fault_handler_cb widget_cb) +{ + if (!widget_cb) { + return NULL; + } + + return _widget_remove_fault_handler(widget_cb); +} + +EAPI int widget_viewer_add_event_handler(widget_event_handler_cb widget_cb, void *data) +{ + if (!widget_cb) { + ErrPrint("Invalid argument widget_cb is nil\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return _widget_add_event_handler(widget_cb, data); +} + +EAPI void *widget_viewer_remove_event_handler(widget_event_handler_cb widget_cb) +{ + if (!widget_cb) { + return NULL; + } + + return _widget_remove_event_handler(widget_cb); +} + +EAPI int widget_viewer_set_update_mode(widget_h handle, int active_update, widget_ret_cb cb, void *data) +{ + struct packet *packet; + unsigned int cmd = CMD_UPDATE_MODE; + int ret; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is Invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is Invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is Invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->common->request.update_mode) { + ErrPrint("Previous update_mode cb is not finished yet\n"); + return WIDGET_ERROR_RESOURCE_BUSY; + } + + if (handle->common->is_active_update == active_update) { + return WIDGET_ERROR_ALREADY_EXIST; + } + + if (!handle->common->is_user) { + return WIDGET_ERROR_PERMISSION_DENIED; + } + + packet = packet_create((const char *)&cmd, "ssi", handle->common->pkgname, handle->common->id, active_update); + if (!packet) { + return WIDGET_ERROR_FAULT; + } + + if (!cb) { + cb = default_update_mode_cb; + } + + ret = master_rpc_async_request(handle, packet, 0, update_mode_cb, NULL); + if (ret == (int)WIDGET_ERROR_NONE) { + handle->cbs.update_mode.cb = cb; + handle->cbs.update_mode.data = data; + handle->common->request.update_mode = 1; + } + + return ret; +} + +EAPI int widget_viewer_is_active_update(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is Invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is Invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return handle->common->is_active_update; +} + +EAPI int widget_viewer_resize_widget(widget_h handle, widget_size_type_e type, widget_ret_cb cb, void *data) +{ + struct widget_common *common; + int w; + int h; + int ret; + + /*! + * \TODO + * If this handle is host instance or link instance, + * Create a new instance or find another linkable instance. + */ + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + /*! + * \note + * resize operation should be separated by each handle. + * If a handle is resizing, the other handle can request resize too. + * So we should not use the common->request.size_changed flag. + */ + if (handle->cbs.size_changed.cb) { + ErrPrint("Previous resize request is not finished yet\n"); + return WIDGET_ERROR_RESOURCE_BUSY; + } + + if (widget_service_get_size(type, &w, &h) != 0) { + ErrPrint("Invalid size type\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->common->widget.width == w && handle->common->widget.height == h) { + DbgPrint("No changes\n"); + return WIDGET_ERROR_ALREADY_EXIST; + } + + if (!handle->common->is_user) { + ErrPrint("CA Livebox is not able to be resized\n"); + return WIDGET_ERROR_PERMISSION_DENIED; + } + + if (handle->common->refcnt <= 1) { + struct packet *packet; + unsigned int cmd = CMD_RESIZE; + + /* Only 1 instance */ + packet = packet_create((const char *)&cmd, "ssii", handle->common->pkgname, handle->common->id, w, h); + if (!packet) { + ErrPrint("Failed to build param\n"); + return WIDGET_ERROR_FAULT; + } + + if (!cb) { + cb = default_widget_size_changed_cb; + } + + ret = master_rpc_async_request(handle, packet, 0, resize_cb, NULL); + if (ret == (int)WIDGET_ERROR_NONE) { + handle->cbs.size_changed.cb = cb; + handle->cbs.size_changed.data = data; + handle->common->request.size_changed = 1; + } + } else { + common = _widget_find_sharable_common_handle(handle->common->pkgname, handle->common->content, w, h, handle->common->cluster, handle->common->category); + if (!common) { + struct widget_common *old_common; + /*! + * \note + * If the common handle is in resizing, + * if user tries to resize a hander, then simply create new one even if the requested size is same with this. + + if (handle->common->request.size_changed) { + } + + */ + + old_common = handle->common; + + common = _widget_create_common_handle(handle, old_common->pkgname, old_common->cluster, old_common->category); + if (!common) { + ErrPrint("Failed to create common handle\n"); + return WIDGET_ERROR_FAULT; + } + + _widget_set_size(common, w, h); + _widget_set_content(common, old_common->content); + _widget_set_period(common, old_common->widget.period); + + /*! + * \note + * Disconnecting from old one. + */ + if (_widget_common_unref(old_common, handle) == 0) { + /*! + * \note + * Impossible + */ + ErrPrint("Common has no associated handle\n"); + } + + _widget_common_ref(common, handle); + + /*! + * Connect to a new one + */ + handle->common = common; + + /*! + * \TODO + * Need to care, if it fails to create a common handle, + * the resize operation will be failed. + * in that case, we should reuse the old common handle + */ + ret = create_real_instance(handle, cb, data); + if (ret < 0) { + _widget_common_unref(common, handle); + _widget_destroy_common_handle(common); + + _widget_common_ref(old_common, handle); + handle->common = old_common; + } else { + /*! + * In this case, we should update visibility of old_common's widgetes + */ + if (handle->visible == WIDGET_SHOW) { + _widget_update_visibility(old_common); + } + } + } else { + struct cb_info *cbinfo; + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + ErrPrint("Failed to create a cbinfo\n"); + ret = WIDGET_ERROR_OUT_OF_MEMORY; + } else { + ret = job_add(handle, _resize_job_cb, WIDGET_ERROR_NONE, cbinfo); + if (ret == (int)WIDGET_ERROR_NONE) { + struct widget_common *old_common; + + old_common = handle->common; + + if (_widget_common_unref(handle->common, handle) == 0) { + ErrPrint("Old common has no associated handle\n"); + } + + _widget_common_ref(common, handle); + handle->common = common; + + if (handle->visible == WIDGET_SHOW) { + _widget_update_visibility(old_common); /* To update visibility: Show --> Paused */ + _widget_update_visibility(common); /* To update visibility: Paused --> Show */ + } + } else { + _widget_destroy_cb_info(cbinfo); + } + } + } + } + + return ret; +} + +EAPI int widget_viewer_send_click_event(widget_h handle, double x, double y) +{ + struct packet *packet; + double timestamp; + unsigned int cmd = CMD_CLICKED; + int ret; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->common->widget.auto_launch) { + if (s_info.launch.handle) { + ret = s_info.launch.handle(handle, handle->common->widget.auto_launch, s_info.launch.data); + if (ret < 0) { + ErrPrint("launch handle app %s (%d)\n", handle->common->widget.auto_launch, ret); + } + } + } + + timestamp = util_timestamp(); + DbgPrint("CLICKED: %lf\n", timestamp); + + packet = packet_create_noack((const char *)&cmd, "sssddd", handle->common->pkgname, handle->common->id, "clicked", timestamp, x, y); + if (!packet) { + ErrPrint("Failed to build param\n"); + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_request_only(handle, packet); + return ret; +} + +EAPI int widget_viewer_has_glance_bar(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return !!handle->common->gbar.fb; +} + +EAPI int widget_viewer_glance_bar_is_created(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->gbar.fb || !handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return handle->common->is_gbar_created; +} + +EAPI int widget_viewer_create_glance_bar(widget_h handle, double x, double y, widget_ret_cb cb, void *data) +{ + struct packet *packet; + unsigned int cmd = CMD_CREATE_GBAR; + int ret; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->gbar.fb || !handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + /*! + * \note + * Only one handle can have a GBAR + */ + if (handle->common->is_gbar_created) { + DbgPrint("GBAR is already created\n"); + return WIDGET_ERROR_NONE; + } + + if (handle->common->request.gbar_created) { + ErrPrint("Previous request is not completed yet\n"); + return WIDGET_ERROR_RESOURCE_BUSY; + } + + /*! + * \note + * Turn off the gbar_destroyed request flag + */ + if (handle->common->request.gbar_destroyed) { + if (job_add(handle, _turn_off_gbar_destroyed_flag_cb, WIDGET_ERROR_CANCELED, NULL) < 0) { + ErrPrint("Failed to add gbar_destroyed job\n"); + } + } + + packet = packet_create((const char *)&cmd, "ssdd", handle->common->pkgname, handle->common->id, x, y); + if (!packet) { + ErrPrint("Failed to build param\n"); + return WIDGET_ERROR_FAULT; + } + + if (!cb) { + cb = default_gbar_created_cb; + } + + DbgPrint("PERF_WIDGET\n"); + ret = master_rpc_async_request(handle, packet, 0, gbar_create_cb, NULL); + if (ret == (int)WIDGET_ERROR_NONE) { + handle->cbs.gbar_created.cb = cb; + handle->cbs.gbar_created.data = data; + handle->common->request.gbar_created = 1; + } + + return ret; +} + +EAPI int widget_viewer_move_glance_bar(widget_h handle, double x, double y) +{ + struct packet *packet; + unsigned int cmd = CMD_GBAR_MOVE; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->gbar.fb || !handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->is_gbar_created) { + ErrPrint("GBAR is not created\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + packet = packet_create_noack((const char *)&cmd, "ssdd", handle->common->pkgname, handle->common->id, x, y); + if (!packet) { + ErrPrint("Failed to build param\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(handle, packet); +} + +EAPI int widget_viewer_activate_faulted_widget(const char *pkgname, widget_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_ACTIVATE_PACKAGE; + int ret; + + if (!pkgname) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + packet = packet_create((const char *)&cmd, "s", pkgname); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + ErrPrint("Unable to create cbinfo\n"); + packet_destroy(packet); + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_async_request(NULL, packet, 0, activated_cb, cbinfo); + if (ret < 0) { + _widget_destroy_cb_info(cbinfo); + } + + return ret; +} + +EAPI int widget_viewer_destroy_glance_bar(widget_h handle, widget_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_DESTROY_GBAR; + int ret; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->gbar.fb || !handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + /*! + * \FIXME + * Replace the callback check code. + * Use the flag instead of callback. + * the flag should be in the ADT "common" + */ + if (!handle->common->is_gbar_created && !handle->common->request.gbar_created) { + ErrPrint("GBAR is not created\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->common->request.gbar_destroyed) { + ErrPrint("GBAR destroy request is already sent\n"); + return WIDGET_ERROR_ALREADY_EXIST; + } + + /*! + * \note + * Disable the gbar_created request flag + */ + if (handle->common->request.gbar_created) { + if (job_add(handle, _turn_off_gbar_created_flag_cb, WIDGET_ERROR_CANCELED, NULL) < 0) { + ErrPrint("Failed to add a new job\n"); + } + } + + DbgPrint("[%s]\n", handle->common->pkgname); + + packet = packet_create((const char *)&cmd, "ss", handle->common->pkgname, handle->common->id); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + if (!cb) { + cb = default_gbar_destroyed_cb; + } + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_async_request(handle, packet, 0, gbar_destroy_cb, cbinfo); + if (ret < 0) { + _widget_destroy_cb_info(cbinfo); + } else { + handle->common->request.gbar_destroyed = 1; + } + + return ret; +} + +EAPI int widget_viewer_feed_access_event(widget_h handle, widget_access_event_type_e type, widget_access_event_info_s info, widget_ret_cb cb, void *data) +{ + int w = 1; + int h = 1; + unsigned int cmd; + int ret = 0; /* re-used for sending event type */ + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->common->request.access_event) { + ErrPrint("Previous access event is not yet done\n"); + return WIDGET_ERROR_RESOURCE_BUSY; + } + + if (type & WIDGET_ACCESS_EVENT_GBAR_MASK) { + if (!handle->common->is_gbar_created) { + ErrPrint("GBAR is not created\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + w = handle->common->gbar.width; + h = handle->common->gbar.height; + + switch (type & ~(WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_WIDGET_MASK)) { + case WIDGET_ACCESS_EVENT_HIGHLIGHT: + cmd = CMD_GBAR_ACCESS_HL; + ret = (int)info->type; + break; + case WIDGET_ACCESS_EVENT_ACTIVATE: + cmd = CMD_GBAR_ACCESS_ACTIVATE; + break; + case WIDGET_ACCESS_EVENT_ACTION: + cmd = CMD_GBAR_ACCESS_ACTION; + ret = (int)info->type; + break; + case WIDGET_ACCESS_EVENT_SCROLL: + cmd = CMD_GBAR_ACCESS_SCROLL; + ret = (int)info->type; + break; + case WIDGET_ACCESS_EVENT_VALUE_CHANGE: + cmd = CMD_GBAR_ACCESS_VALUE_CHANGE; + break; + case WIDGET_ACCESS_EVENT_MOUSE: + cmd = CMD_GBAR_ACCESS_MOUSE; + ret = (int)info->type; + break; + case WIDGET_ACCESS_EVENT_BACK: + cmd = CMD_GBAR_ACCESS_BACK; + break; + case WIDGET_ACCESS_EVENT_OVER: + cmd = CMD_GBAR_ACCESS_OVER; + break; + case WIDGET_ACCESS_EVENT_READ: + cmd = CMD_GBAR_ACCESS_READ; + break; + case WIDGET_ACCESS_EVENT_ENABLE: + cmd = CMD_GBAR_ACCESS_ENABLE; + ret = info->type; + break; + default: + return WIDGET_ERROR_INVALID_PARAMETER; + } + + } else if (type & WIDGET_ACCESS_EVENT_WIDGET_MASK) { + w = handle->common->widget.width; + h = handle->common->widget.height; + switch (type & ~(WIDGET_ACCESS_EVENT_GBAR_MASK | WIDGET_ACCESS_EVENT_WIDGET_MASK)) { + case WIDGET_ACCESS_EVENT_HIGHLIGHT: + cmd = CMD_WIDGET_ACCESS_HL; + ret = (int)info->type; + break; + case WIDGET_ACCESS_EVENT_ACTIVATE: + cmd = CMD_WIDGET_ACCESS_ACTIVATE; + break; + case WIDGET_ACCESS_EVENT_ACTION: + cmd = CMD_WIDGET_ACCESS_ACTION; + ret = (int)info->type; + break; + case WIDGET_ACCESS_EVENT_SCROLL: + cmd = CMD_WIDGET_ACCESS_SCROLL; + ret = (int)info->type; + break; + case WIDGET_ACCESS_EVENT_VALUE_CHANGE: + cmd = CMD_WIDGET_ACCESS_VALUE_CHANGE; + break; + case WIDGET_ACCESS_EVENT_MOUSE: + cmd = CMD_WIDGET_ACCESS_MOUSE; + ret = (int)info->type; + break; + case WIDGET_ACCESS_EVENT_BACK: + cmd = CMD_WIDGET_ACCESS_BACK; + break; + case WIDGET_ACCESS_EVENT_OVER: + cmd = CMD_WIDGET_ACCESS_OVER; + break; + case WIDGET_ACCESS_EVENT_READ: + cmd = CMD_WIDGET_ACCESS_READ; + break; + case WIDGET_ACCESS_EVENT_ENABLE: + cmd = CMD_WIDGET_ACCESS_ENABLE; + ret = info->type; + break; + default: + return WIDGET_ERROR_INVALID_PARAMETER; + } + } else { + ErrPrint("Invalid event type\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!cb) { + cb = default_access_event_cb; + } + + ret = send_access_event(handle, (const char *)&cmd, info->x * w, info->y * h, ret); + if (ret == (int)WIDGET_ERROR_NONE) { + handle->cbs.access_event.cb = cb; + handle->cbs.access_event.data = data; + handle->common->request.access_event = 1; + } + + return ret; +} + +EAPI int widget_viewer_feed_mouse_event(widget_h handle, widget_mouse_event_type_e type, widget_mouse_event_info_s info) +{ + unsigned int cmd; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!(type & WIDGET_MOUSE_EVENT_MASK)) { + ErrPrint("Invalid content event is used\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (type & WIDGET_MOUSE_EVENT_GBAR_MASK) { + int flag = 1; + + if (!handle->common->is_gbar_created) { + ErrPrint("GBAR is not created\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->gbar.fb) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (type & WIDGET_MOUSE_EVENT_MOVE) { + if (fabs(info->x - handle->common->gbar.x) < conf_event_filter() && fabs(info->y - handle->common->gbar.y) < conf_event_filter()) { + return WIDGET_ERROR_RESOURCE_BUSY; + } + } else if (type & WIDGET_MOUSE_EVENT_SET) { + flag = 0; + } + + if (flag) { + handle->common->gbar.x = info->x; + handle->common->gbar.y = info->y; + } + + switch ((type & ~(WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_WIDGET_MASK))) { + case WIDGET_MOUSE_EVENT_ENTER | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_ENTER; + break; + case WIDGET_MOUSE_EVENT_LEAVE | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_LEAVE; + break; + case WIDGET_MOUSE_EVENT_UP | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_UP; + break; + case WIDGET_MOUSE_EVENT_DOWN | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_DOWN; + break; + case WIDGET_MOUSE_EVENT_MOVE | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_MOVE; + break; + case WIDGET_MOUSE_EVENT_SET | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_SET; + break; + case WIDGET_MOUSE_EVENT_UNSET | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_UNSET; + break; + case WIDGET_MOUSE_EVENT_ON_SCROLL | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_ON_SCROLL; + break; + case WIDGET_MOUSE_EVENT_ON_HOLD | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_ON_HOLD; + DbgPrint("Send ON_HOLD\n"); + break; + case WIDGET_MOUSE_EVENT_OFF_SCROLL | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_OFF_SCROLL; + break; + case WIDGET_MOUSE_EVENT_OFF_HOLD | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_OFF_HOLD; + break; + default: + ErrPrint("Invalid event type\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + } else if (type & WIDGET_MOUSE_EVENT_WIDGET_MASK) { + int flag = 1; + + if (!handle->common->widget.fb) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->common->widget.auto_launch) { + return WIDGET_ERROR_DISABLED; + } + + if (type & WIDGET_MOUSE_EVENT_MOVE) { + if (fabs(info->x - handle->common->widget.x) < conf_event_filter() && fabs(info->y - handle->common->widget.y) < conf_event_filter()) { + return WIDGET_ERROR_RESOURCE_BUSY; + } + } else if (type & WIDGET_MOUSE_EVENT_SET) { + flag = 0; + } + + if (flag) { + handle->common->widget.x = info->x; + handle->common->widget.y = info->y; + } + + switch ((type & ~(WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_WIDGET_MASK))) { + case WIDGET_MOUSE_EVENT_ENTER | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_WIDGET_MOUSE_ENTER; + break; + case WIDGET_MOUSE_EVENT_LEAVE | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_WIDGET_MOUSE_LEAVE; + break; + case WIDGET_MOUSE_EVENT_UP | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_WIDGET_MOUSE_UP; + break; + case WIDGET_MOUSE_EVENT_DOWN | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_WIDGET_MOUSE_DOWN; + break; + case WIDGET_MOUSE_EVENT_MOVE | WIDGET_MOUSE_EVENT_MASK: + if (!handle->common->widget.mouse_event) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + cmd = CMD_WIDGET_MOUSE_MOVE; + break; + case WIDGET_MOUSE_EVENT_SET | WIDGET_MOUSE_EVENT_MASK: + if (!handle->common->widget.mouse_event) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + cmd = CMD_WIDGET_MOUSE_SET; + break; + case WIDGET_MOUSE_EVENT_UNSET | WIDGET_MOUSE_EVENT_MASK: + if (!handle->common->widget.mouse_event) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + cmd = CMD_WIDGET_MOUSE_UNSET; + break; + case WIDGET_MOUSE_EVENT_ON_SCROLL | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_WIDGET_MOUSE_ON_SCROLL; + break; + case WIDGET_MOUSE_EVENT_ON_HOLD | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_WIDGET_MOUSE_ON_HOLD; + DbgPrint("Send ON_HOLD\n"); + break; + case WIDGET_MOUSE_EVENT_OFF_SCROLL | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_WIDGET_MOUSE_OFF_SCROLL; + break; + case WIDGET_MOUSE_EVENT_OFF_HOLD | WIDGET_MOUSE_EVENT_MASK: + cmd = CMD_WIDGET_MOUSE_OFF_HOLD; + break; + default: + ErrPrint("Invalid event type\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + } else { + ErrPrint("Invalid event type\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return send_mouse_event(handle, (const char *)&cmd, info->x, info->y, info->ratio_w, info->ratio_h, info->device); +} + +EAPI int widget_viewer_feed_key_event(widget_h handle, widget_key_event_type_e type, widget_key_event_info_s info, widget_ret_cb cb, void *data) +{ + int ret; + unsigned int cmd; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!(type & WIDGET_KEY_EVENT_MASK)) { + ErrPrint("Invalid key event is used\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->common->request.key_event) { + ErrPrint("Previous key event is not completed yet\n"); + return WIDGET_ERROR_RESOURCE_BUSY; + } + + if (type & WIDGET_MOUSE_EVENT_GBAR_MASK) { + if (!handle->common->is_gbar_created) { + ErrPrint("GBAR is not created\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->gbar.fb) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (type & WIDGET_KEY_EVENT_DOWN) { + /*! + * \TODO + * filtering the reproduced events if it is too fast + */ + } else if (type & WIDGET_KEY_EVENT_SET) { + /*! + * \TODO + * What can I do for this case? + */ + } + + /*! + * Must be short than 29 bytes. + */ + switch ((type & ~(WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_WIDGET_MASK))) { + case WIDGET_KEY_EVENT_FOCUS_IN | WIDGET_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_FOCUS_IN; + break; + case WIDGET_KEY_EVENT_FOCUS_OUT | WIDGET_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_FOCUS_OUT; + break; + case WIDGET_KEY_EVENT_UP | WIDGET_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_UP; + break; + case WIDGET_KEY_EVENT_DOWN | WIDGET_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_DOWN; + break; + case WIDGET_KEY_EVENT_SET | WIDGET_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_SET; + break; + case WIDGET_KEY_EVENT_UNSET | WIDGET_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_UNSET; + break; + default: + ErrPrint("Invalid event type\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + } else if (type & WIDGET_MOUSE_EVENT_WIDGET_MASK) { + if (!handle->common->widget.fb) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (type & WIDGET_KEY_EVENT_DOWN) { + /*! + * \TODO + * filtering the reproduced events if it is too fast + */ + } else if (type & WIDGET_KEY_EVENT_SET) { + /*! + * What can I do for this case? + */ + } + + switch ((type & ~(WIDGET_MOUSE_EVENT_GBAR_MASK | WIDGET_MOUSE_EVENT_WIDGET_MASK))) { + case WIDGET_KEY_EVENT_FOCUS_IN | WIDGET_KEY_EVENT_MASK: + cmd = CMD_WIDGET_KEY_FOCUS_IN; + break; + case WIDGET_KEY_EVENT_FOCUS_OUT | WIDGET_KEY_EVENT_MASK: + cmd = CMD_WIDGET_KEY_FOCUS_OUT; + break; + case WIDGET_KEY_EVENT_UP | WIDGET_KEY_EVENT_MASK: + cmd = CMD_WIDGET_KEY_UP; + break; + case WIDGET_KEY_EVENT_DOWN | WIDGET_KEY_EVENT_MASK: + cmd = CMD_WIDGET_KEY_DOWN; + break; + case WIDGET_KEY_EVENT_SET | WIDGET_KEY_EVENT_MASK: + cmd = CMD_WIDGET_KEY_SET; + break; + case WIDGET_KEY_EVENT_UNSET | WIDGET_KEY_EVENT_MASK: + cmd = CMD_WIDGET_KEY_UNSET; + break; + default: + ErrPrint("Invalid event type\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + } else { + ErrPrint("Invalid event type\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!cb) { + cb = default_key_event_cb; + } + + ret = send_key_event(handle, (const char *)&cmd, info->keycode, info->device); + if (ret == (int)WIDGET_ERROR_NONE) { + handle->cbs.key_event.cb = cb; + handle->cbs.key_event.data = data; + handle->common->request.key_event = 1; + } + + return ret; +} + +EAPI const char *widget_viewer_get_filename(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return NULL; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return NULL; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return NULL; + } + + if (handle->common->filename) { + return handle->common->filename; + } + + /* Oooops */ + set_last_result(WIDGET_ERROR_NONE); + return util_uri_to_path(handle->common->id); +} + +EAPI int widget_viewer_get_glance_bar_size(widget_h handle, int *w, int *h) +{ + int _w; + int _h; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!w) { + w = &_w; + } + if (!h) { + h = &_h; + } + + if (!handle->common->is_gbar_created) { + *w = handle->common->gbar.default_width; + *h = handle->common->gbar.default_height; + } else { + *w = handle->common->gbar.width; + *h = handle->common->gbar.height; + } + + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_get_size_type(widget_h handle, widget_size_type_e *size_type) +{ + int w; + int h; + int ret = WIDGET_ERROR_NONE; + widget_size_type_e result_size_type = WIDGET_SIZE_TYPE_UNKNOWN; + + if (!handle || handle->state != WIDGET_STATE_CREATE || size_type == NULL) { + ErrPrint("Handler is invalid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + w = handle->common->widget.width; + h = handle->common->widget.height; + + switch (handle->common->widget.type) { + case WIDGET_TYPE_BUFFER: + case WIDGET_TYPE_SCRIPT: + if (!fb_is_created(handle->common->widget.fb)) { + DbgPrint("FB is not created yet, but give its size to the caller: %dx%d\n", w, h); + } + break; + default: + break; + } + + if ((ret = widget_service_get_size_type(w, h, &result_size_type)) != WIDGET_ERROR_NONE) { + ErrPrint("widget_service_get_size_type failed : %d\n", ret); + goto out; + } + +out: + + if (size_type) { + *size_type = result_size_type; + } + + return ret; +} + +EAPI int widget_viewer_set_group(widget_h handle, const char *cluster, const char *category, widget_ret_cb cb, void *data) +{ + struct packet *packet; + unsigned int cmd = CMD_CHANGE_GROUP; + int ret; + + if (!handle) { + ErrPrint("Handler is NIL\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!cluster || !category || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->common->request.group_changed) { + ErrPrint("Previous group changing request is not finished yet\n"); + return WIDGET_ERROR_RESOURCE_BUSY; + } + + if (!handle->common->is_user) { + ErrPrint("CA Livebox is not able to change the group\n"); + return WIDGET_ERROR_PERMISSION_DENIED; + } + + if (!strcmp(handle->common->cluster, cluster) && !strcmp(handle->common->category, category)) { + DbgPrint("No changes\n"); + return WIDGET_ERROR_ALREADY_EXIST; + } + + packet = packet_create((const char *)&cmd, "ssss", handle->common->pkgname, handle->common->id, cluster, category); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + if (!cb) { + cb = default_group_changed_cb; + } + + ret = master_rpc_async_request(handle, packet, 0, set_group_ret_cb, NULL); + if (ret == (int)WIDGET_ERROR_NONE) { + handle->cbs.group_changed.cb = cb; + handle->cbs.group_changed.data = data; + handle->common->request.group_changed = 1; + } + + return ret; +} + +EAPI int widget_viewer_get_group(widget_h handle, const char **cluster, const char **category) +{ + if (!handle) { + ErrPrint("Handler is NIL\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!cluster || !category || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + *cluster = handle->common->cluster; + *category = handle->common->category; + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_get_supported_sizes(widget_h handle, int *cnt, widget_size_type_e *size_list) +{ + register int i; + register int j; + + if (!handle || !size_list) { + ErrPrint("Invalid argument, handle(%p), size_list(%p)\n", handle, size_list); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!cnt || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + for (j = i = 0; i < WIDGET_COUNT_OF_SIZE_TYPE; i++) { + if (handle->common->widget.size_list & (0x01 << i)) { + if (j == *cnt) { + break; + } + + size_list[j++] = (widget_size_type_e)(0x01 << i); + } + } + + *cnt = j; + return WIDGET_ERROR_NONE; +} + +EAPI const char *widget_viewer_get_pkgname(widget_h handle) +{ + if (!handle) { + ErrPrint("Handler is NIL\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + set_last_result(WIDGET_ERROR_NONE); + return handle->common->pkgname; +} + +EAPI int widget_viewer_get_priority(widget_h handle, double *priority) +{ + int ret = WIDGET_ERROR_NONE; + double result_priority = -1.0f; + + if (!handle || handle->state != WIDGET_STATE_CREATE || priority == NULL) { + ErrPrint("Handler is invalid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid (%p)\n", handle); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + result_priority = handle->common->widget.priority; + +out: + if (priority) + *priority = result_priority; + + return ret; +} + +EAPI int widget_delete_cluster(const char *cluster, widget_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_DELETE_CLUSTER; + int ret; + + packet = packet_create((const char *)&cmd, "s", cluster); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_async_request(NULL, packet, 0, _delete_cluster_cb, cbinfo); + if (ret < 0) { + _widget_destroy_cb_info(cbinfo); + } + + return ret; +} + +EAPI int widget_delete_category(const char *cluster, const char *category, widget_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_DELETE_CATEGORY; + int ret; + + packet = packet_create((const char *)&cmd, "ss", cluster, category); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_async_request(NULL, packet, 0, _delete_category_cb, cbinfo); + if (ret < 0) { + _widget_destroy_cb_info(cbinfo); + } + + return ret; +} + +EAPI int widget_viewer_get_type(widget_h handle, int gbar, widget_type_e *widget_type) +{ + int ret = WIDGET_ERROR_INVALID_PARAMETER; + widget_type_e result_widget_type = WIDGET_CONTENT_TYPE_INVALID; + + if (!handle || handle->state != WIDGET_STATE_CREATE || widget_type == NULL) { + ErrPrint("Handler is invalid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + result_widget_type = WIDGET_CONTENT_TYPE_INVALID; + goto out; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + result_widget_type = WIDGET_CONTENT_TYPE_INVALID; + goto out; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + result_widget_type = WIDGET_CONTENT_TYPE_INVALID; + goto out; + } + + if (gbar) { + switch (handle->common->gbar.type) { + case GBAR_TYPE_TEXT: + result_widget_type = WIDGET_CONTENT_TYPE_TEXT; + break; + case GBAR_TYPE_BUFFER: + case GBAR_TYPE_SCRIPT: + { + const char *id; + id = fb_id(handle->common->gbar.fb); + if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + result_widget_type = WIDGET_CONTENT_TYPE_RESOURCE_ID; + break; + } + } + result_widget_type = WIDGET_CONTENT_TYPE_BUFFER; + break; + case GBAR_TYPE_UIFW: + result_widget_type = WIDGET_CONTENT_TYPE_UIFW; + break; + default: + break; + } + } else { + switch (handle->common->widget.type) { + case WIDGET_TYPE_FILE: + result_widget_type = WIDGET_CONTENT_TYPE_IMAGE; + break; + case WIDGET_TYPE_BUFFER: + case WIDGET_TYPE_SCRIPT: + { + const char *id; + id = fb_id(handle->common->widget.fb); + if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + result_widget_type = WIDGET_CONTENT_TYPE_RESOURCE_ID; + break; + } + } + result_widget_type = WIDGET_CONTENT_TYPE_BUFFER; + break; + case WIDGET_TYPE_TEXT: + result_widget_type = WIDGET_CONTENT_TYPE_TEXT; + break; + case WIDGET_TYPE_UIFW: + result_widget_type = WIDGET_CONTENT_TYPE_UIFW; + break; + default: + break; + } + } + +out: + if (widget_type) + *widget_type = result_widget_type; + return ret; +} + +EAPI int widget_viewer_set_text_handler(widget_h handle, int gbar, struct widget_script_operators *ops) +{ + if (!handle) { + ErrPrint("Handler is NIL\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + memcpy(&handle->cbs.gbar_ops, ops, sizeof(*ops)); + } else { + memcpy(&handle->cbs.widget_ops, ops, sizeof(*ops)); + } + + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_acquire_extra_resource_id(widget_h handle, int gbar, int idx, widget_ret_cb cb, void *data) +{ + if (idx < 0) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handle's buffer type yet + * so we cannot use its type to validate handle + * + * handle->common.gbar.type == unknown + */ + if (!handle->common->gbar.extra_buffer) { + return WIDGET_ERROR_NOT_EXIST; + } + + if (idx >= conf_extra_buffer_count()) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return widget_acquire_gbar_extra_pixmap(handle, idx, cb, data); + } else { + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handle's buffer type yet + * so we cannot use its type to validate handle + * + * handle->common.widget.type == unknown + */ + if (!handle->common->widget.extra_buffer) { + ErrPrint("Extra buffer is not prepared\n"); + return WIDGET_ERROR_NOT_EXIST; + } + + if (idx >= conf_extra_buffer_count()) { + ErrPrint("Invalid parameter: %d / %d\n", idx, conf_extra_buffer_count()); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return widget_acquire_widget_extra_pixmap(handle, idx, cb, data); + } +} + +EAPI int widget_viewer_acquire_resource_id(widget_h handle, int gbar, widget_ret_cb cb, void *data) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + if (handle->common->gbar.type != GBAR_TYPE_SCRIPT && handle->common->gbar.type != GBAR_TYPE_BUFFER) { + ErrPrint("Handler is not valid type\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return widget_acquire_gbar_pixmap(handle, cb, data); + } else { + if (handle->common->widget.type != WIDGET_TYPE_SCRIPT && handle->common->widget.type != WIDGET_TYPE_BUFFER) { + ErrPrint("Handler is not valid type\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return _widget_acquire_widget_pixmap(handle, cb, data); + } +} + +/*! + * \note + * Do not check the state of handle and common-handle. + * If this function is used in the deleted callback, + * the handle and common-handle's state would be DELETE + * if this function check the state of handles, + * user cannot release the pixmap. + */ +EAPI int widget_viewer_release_resource_id(widget_h handle, int gbar, unsigned int resource_id) +{ + struct packet *packet; + const char *pkgname; + const char *id; + unsigned int cmd; + + if (resource_id == 0 /* || handle->state != WIDGET_STATE_CREATE */) { + ErrPrint("Pixmap is invalid [%d]\n", resource_id); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + if (!handle) { + /*! + * \note + * Even though the handle is NULL, we should send the release request to the master. + * Because the resource_id resource can be released after the handle is destroyed. + * Pixmap resource is used by client. and it cannot be guaranteed to release resource_id. + * In some cases, the resource_id can be released after the handle is deleted. + * + * Its implementation is up to the viewer app. + * But we cannot force it to use only with valid handle. + */ + DbgPrint("Using NULL handle\n"); + pkgname = NULL; + id = NULL; + /*! + * \note + * Master will try to find the buffer handle using given resource_id. if the pkgname and id is not valid. + */ + } else { + if (!handle->common /* || handle-common->state != WIDGET_STATE_CREATE */) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handle's buffer type yet + * so we cannot use its type to validate handle + * + * handle->common.gbar.type == unknown + */ + + pkgname = handle->common->pkgname; + id = handle->common->id; + } + + cmd = CMD_GBAR_RELEASE_PIXMAP; + } else { + if (!handle) { + /*! + * \note + * Even though the handle is NULL, we should send the release request to the master. + * Because the resource_id resource can be released after the handle is destroyed. + * Pixmap resource is used by client. and it cannot be guaranteed to release resource_id. + * In some cases, the resource_id can be released after the handle is deleted. + * + * Its implementation is up to the viewer app. + * But we cannot force it to use only with valid handle. + */ + DbgPrint("Using NULL handle\n"); + pkgname = NULL; + id = NULL; + /*! + * \note + * Master will try to find the buffer handle using given resource_id. if the pkgname and id is not valid. + */ + } else { + if (!handle->common /* || handle->common->state != WIDGET_STATE_CREATE */) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handle's buffer type yet + * so we cannot use its type to validate handle + * + * handle->common.widget.type == unknown + */ + + pkgname = handle->common->pkgname; + id = handle->common->id; + } + + cmd = CMD_WIDGET_RELEASE_PIXMAP; + } + + packet = packet_create_noack((const char *)&cmd, "ssi", pkgname, id, resource_id); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(handle, packet); +} + +EAPI unsigned int widget_extra_resource_id(const widget_h handle, int gbar, int idx) +{ + if (idx < 0) { + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return 0u; + } + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return 0u; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return 0u; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return 0u; + } + + if (gbar) { + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handle's buffer type yet + * so we cannot use its type to validate handle + * + * handle->common.gbar.type == unknown + */ + + if (!handle->common->gbar.extra_buffer || handle->common->gbar.last_extra_buffer_idx < 0) { + set_last_result(WIDGET_ERROR_NOT_EXIST); + return 0u; + } + + return handle->common->gbar.extra_buffer[handle->common->gbar.last_extra_buffer_idx]; + } else { + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handle's buffer type yet + * so we cannot use its type to validate handle + * + * handle->common.widget.type == unknown + */ + + if (!handle->common->widget.extra_buffer || handle->common->widget.last_extra_buffer_idx < 0) { + set_last_result(WIDGET_ERROR_NOT_EXIST); + return 0u; + } + + return handle->common->widget.extra_buffer[handle->common->widget.last_extra_buffer_idx]; + } +} + +EAPI int widget_viewer_get_resource_id(const widget_h handle, int gbar, unsigned int *resouce_id) +{ + const char *id; + unsigned int pixmap = 0u; + int ret = WIDGET_ERROR_NONE; + + if (!handle || handle->state != WIDGET_STATE_CREATE || resouce_id == NULL) { + ErrPrint("Handler is invalid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + if (gbar) { + if (handle->common->gbar.type != GBAR_TYPE_SCRIPT && handle->common->gbar.type != GBAR_TYPE_BUFFER) { + ErrPrint("Invalid handle\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + id = fb_id(handle->common->gbar.fb); + if (id && sscanf(id, SCHEMA_PIXMAP "%u", &pixmap) != 1) { + ErrPrint("PIXMAP Id is not valid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + } else { + if (handle->common->widget.type != WIDGET_TYPE_SCRIPT && handle->common->widget.type != WIDGET_TYPE_BUFFER) { + ErrPrint("Invalid handle\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + + id = fb_id(handle->common->widget.fb); + if (id && sscanf(id, SCHEMA_PIXMAP "%u", &pixmap) != 1) { + ErrPrint("PIXMAP Id is not valid\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + goto out; + } + } +out: + if (resouce_id) + *resouce_id = pixmap; + + return ret; +} + +EAPI void *widget_viewer_acquire_buffer(widget_h handle, int gbar) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (gbar) { + if (handle->common->gbar.type != GBAR_TYPE_SCRIPT && handle->common->gbar.type != GBAR_TYPE_BUFFER) { + ErrPrint("Handler is not valid type\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + return fb_acquire_buffer(handle->common->gbar.fb); + } else { + if (handle->common->widget.type != WIDGET_TYPE_SCRIPT && handle->common->widget.type != WIDGET_TYPE_BUFFER) { + ErrPrint("Handler is not valid type\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + return fb_acquire_buffer(handle->common->widget.fb); + } +} + +EAPI int widget_viewer_release_buffer(void *buffer) +{ + return fb_release_buffer(buffer); +} + +EAPI int widget_viewer_get_buffer_reference_count(void *buffer) +{ + return fb_refcnt(buffer); +} + +EAPI int widget_viewer_get_buffer_size(widget_h handle, int gbar) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + return fb_size(handle->common->gbar.fb); + } else { + return fb_size(handle->common->widget.fb); + } +} + +EAPI int widget_viewer_is_created_by_user(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return handle->common->is_user; +} + +EAPI int widget_viewer_set_pinup(widget_h handle, int flag, widget_ret_cb cb, void *data) +{ + struct packet *packet; + unsigned int cmd = CMD_PINUP_CHANGED; + int ret; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->common->request.pinup) { + ErrPrint("Previous pinup request is not finished\n"); + return WIDGET_ERROR_RESOURCE_BUSY; + } + + if (handle->common->is_pinned_up == flag) { + DbgPrint("No changes\n"); + return WIDGET_ERROR_ALREADY_EXIST; + } + + packet = packet_create((const char *)&cmd, "ssi", handle->common->pkgname, handle->common->id, flag); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + if (!cb) { + cb = default_pinup_cb; + } + + ret = master_rpc_async_request(handle, packet, 0, pinup_done_cb, NULL); + if (ret == (int)WIDGET_ERROR_NONE) { + handle->cbs.pinup.cb = cb; + handle->cbs.pinup.data = data; + handle->common->request.pinup = 1; + } + + return ret; +} + +EAPI int widget_viewer_is_pinned_up(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return handle->common->is_pinned_up; +} + +EAPI int widget_viewer_has_pinup(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return handle->common->widget.pinup_supported; +} + +EAPI int widget_viewer_set_data(widget_h handle, void *data) +{ + if (!handle) { + ErrPrint("Handler is NIL\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + handle->data = data; + return WIDGET_ERROR_NONE; +} + +EAPI void *widget_viewer_get_data(widget_h handle) +{ + if (!handle) { + ErrPrint("Handler is NIL\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + return handle->data; +} + +EAPI const char *widget_viewer_get_content_string(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + set_last_result(WIDGET_ERROR_NONE); + return handle->common->content; +} + +EAPI const char *widget_viewer_get_title_string(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + set_last_result(WIDGET_ERROR_NONE); + return handle->common->title; +} + +EAPI int widget_viewer_emit_text_signal(widget_h handle, widget_text_signal_s event_info, widget_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_TEXT_SIGNAL; + int ret; + const char *signal_name; + const char *source; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (handle->common->widget.type != WIDGET_TYPE_TEXT && handle->common->gbar.type != GBAR_TYPE_TEXT) { + DbgPrint("Not a text box, but send signal\n"); + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!event_info) { + ErrPrint("Invalid event info\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + signal_name = event_info->signal_name; + if (!signal_name) { + signal_name = ""; + } + + source = event_info->source; + if (!source) { + source = ""; + } + + packet = packet_create((const char *)&cmd, "ssssdddd", + handle->common->pkgname, handle->common->id, + signal_name, source, + event_info->geometry.sx, event_info->geometry.sy, + event_info->geometry.ex, event_info->geometry.ey); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return WIDGET_ERROR_FAULT; + } + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_async_request(handle, packet, 0, text_signal_cb, cbinfo); + if (ret < 0) { + _widget_destroy_cb_info(cbinfo); + } + + return ret; +} + +EAPI int widget_viewer_subscribe_group(const char *cluster, const char *category) +{ + struct packet *packet; + unsigned int cmd = CMD_SUBSCRIBE; + + /*! + * \todo + * Validate the group info using DB + * If the group info is not valid, do not send this request + */ + + packet = packet_create_noack((const char *)&cmd, "ss", cluster ? cluster : "", category ? category : ""); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int widget_viewer_unsubscribe_group(const char *cluster, const char *category) +{ + struct packet *packet; + unsigned int cmd = CMD_UNSUBSCRIBE; + + /*! + * \todo + * Validate the group info using DB + * If the group info is not valid, do not send this request + * AND Check the subscribed or not too + */ + + packet = packet_create_noack((const char *)&cmd, "ss", cluster ? cluster : "", category ? category : ""); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int widget_viewer_subscribe_category(const char *category) +{ + struct packet *packet; + unsigned int cmd = CMD_SUBSCRIBE_CATEGORY; + + if (!category) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + packet = packet_create_noack((const char *)&cmd, "s", category); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int widget_viewer_unsubscribe_category(const char *category) +{ + struct packet *packet; + unsigned int cmd = CMD_UNSUBSCRIBE_CATEGORY; + + if (!category) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + packet = packet_create_noack((const char *)&cmd, "s", category); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int widget_viewer_refresh(widget_h handle, int force) +{ + struct packet *packet; + unsigned int cmd = CMD_UPDATE; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + packet = packet_create_noack((const char *)&cmd, "ssi", handle->common->pkgname, handle->common->id, force); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(handle, packet); +} + +EAPI int widget_viewer_refresh_group(const char *cluster, const char *category, int force) +{ + struct packet *packet; + unsigned int cmd = CMD_REFRESH_GROUP; + + if (!cluster || !category) { + ErrPrint("Invalid argument\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + packet = packet_create_noack((const char *)&cmd, "ssi", cluster, category, force); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int widget_viewer_set_visibility(widget_h handle, widget_visible_state_e state) +{ + int old_state; + int ret; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->is_user) { + /* System cluster widget cannot be changed its visible states */ + if (state == WIDGET_HIDE_WITH_PAUSE) { + ErrPrint("CA Livebox is not able to change the visibility\n"); + return WIDGET_ERROR_PERMISSION_DENIED; + } + } + + if (handle->visible == state) { + DbgPrint("%s has no changes\n", handle->common->pkgname); + return WIDGET_ERROR_ALREADY_EXIST; + } + + old_state = handle->visible; + handle->visible = state; + + ret = _widget_set_visibility(handle, state); + if (ret < 0) { + handle->visible = old_state; + } + + return ret; +} + +EAPI widget_visible_state_e widget_viewer_get_visibility(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_VISIBLE_ERROR; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_VISIBLE_ERROR; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return WIDGET_VISIBLE_ERROR; + } + + return handle->visible; +} + +EAPI int widget_viewer_notify_paused_status_of_viewer(void) +{ + struct packet *packet; + unsigned int cmd = CMD_CLIENT_PAUSED; + + packet = packet_create_noack((const char *)&cmd, "d", util_timestamp()); + if (!packet) { + ErrPrint("Failed to create a pause packet\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int widget_viewer_notify_resumed_status_of_viewer(void) +{ + struct packet *packet; + unsigned int cmd = CMD_CLIENT_RESUMED; + + packet = packet_create_noack((const char *)&cmd, "d", util_timestamp()); + if (!packet) { + ErrPrint("Failed to create a resume packet\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int widget_viewer_notify_orientation_of_viewer(int orientation) +{ + struct packet *packet; + unsigned int cmd = CMD_ORIENTATION; + + if (orientation < 0 || orientation > 360) { + ErrPrint("Invalid parameter: %d\n", orientation); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + packet = packet_create_noack((const char *)&cmd, "di", util_timestamp(), orientation); + if (!packet) { + ErrPrint("Failed to create a orientation packet\n"); + return WIDGET_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int widget_viewer_sync_buffer(widget_h handle, int gbar) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + return _widget_sync_gbar_fb(handle->common); + } else { + return _widget_sync_widget_fb(handle->common); + } +} + +EAPI const char *widget_viewer_get_alternative_icon(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid[%p]\n", handle); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + return handle->common->alt.icon; +} + +EAPI const char *widget_viewer_get_alternative_name(widget_h handle) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid[%p]\n", handle); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + return handle->common->alt.name; +} + +EAPI int widget_viewer_acquire_buffer_lock(widget_h handle, int is_gbar) +{ + int ret = WIDGET_ERROR_NONE; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid[%p]\n", handle); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid[%p]\n", handle); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (is_gbar) { + ret = widget_service_acquire_lock(handle->common->gbar.lock); + } else { + ret = widget_service_acquire_lock(handle->common->widget.lock); + } + + return ret == 0 ? WIDGET_ERROR_NONE : WIDGET_ERROR_FAULT; +} + +EAPI int widget_viewer_release_buffer_lock(widget_h handle, int is_gbar) +{ + int ret = WIDGET_ERROR_NONE; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid[%p]\n", handle); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (is_gbar) { + ret = widget_service_release_lock(handle->common->gbar.lock); + } else { + ret = widget_service_release_lock(handle->common->widget.lock); + } + + return ret == 0 ? WIDGET_ERROR_NONE : WIDGET_ERROR_FAULT; +} + +EAPI int widget_viewer_set_option(widget_option_type_e option, int state) +{ + int ret = WIDGET_ERROR_NONE; + + switch (option) { + case WIDGET_OPTION_MANUAL_SYNC: + conf_set_manual_sync(state); + break; + case WIDGET_OPTION_FRAME_DROP_FOR_RESIZE: + conf_set_frame_drop_for_resizing(state); + break; + case WIDGET_OPTION_SHARED_CONTENT: + conf_set_shared_content(state); + break; + case WIDGET_OPTION_DIRECT_UPDATE: + if (s_info.init_count) { + DbgPrint("Already intialized, this option is not applied\n"); + } + conf_set_direct_update(state); + break; + case WIDGET_OPTION_EXTRA_BUFFER_CNT: + ErrPrint("Permission denied\n"); + ret = WIDGET_ERROR_PERMISSION_DENIED; + break; + default: + ret = WIDGET_ERROR_INVALID_PARAMETER; + break; + } + + return ret; +} + +EAPI int widget_viewer_get_option(widget_option_type_e option) +{ + int ret; + + set_last_result(WIDGET_ERROR_NONE); + switch (option) { + case WIDGET_OPTION_MANUAL_SYNC: + ret = conf_manual_sync(); + break; + case WIDGET_OPTION_FRAME_DROP_FOR_RESIZE: + ret = conf_frame_drop_for_resizing(); + break; + case WIDGET_OPTION_SHARED_CONTENT: + ret = conf_shared_content(); + break; + case WIDGET_OPTION_DIRECT_UPDATE: + ret = conf_direct_update(); + break; + case WIDGET_OPTION_EXTRA_BUFFER_CNT: + ret = conf_extra_buffer_count(); + break; + default: + ret = WIDGET_ERROR_INVALID_PARAMETER; + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + break; + } + + return ret; +} + +EAPI int widget_viewer_set_auto_launch_handler(widget_auto_launch_handler_cb widget_launch_handler, void *data) +{ + s_info.launch.handle = widget_launch_handler; + s_info.launch.data = data; + + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_get_damaged_region(widget_h handle, int gbar, const widget_damage_region_s *region) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid[%p]\n", handle); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + region = &handle->common->widget.last_damage; + } else { + region = &handle->common->gbar.last_damage; + } + + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_get_affected_extra_buffer(widget_h handle, int gbar, int *idx, unsigned int *resource_id) +{ + int _idx; + unsigned int _resource_id; + + if (!handle || handle->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid[%p]\n", handle); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!idx) { + idx = &_idx; + } + + if (!resource_id) { + resource_id = &_resource_id; + } + + if (gbar) { + if (!handle->common->gbar.extra_buffer || handle->common->gbar.last_extra_buffer_idx < 0) { + return WIDGET_ERROR_NOT_EXIST; + } + + *idx = handle->common->gbar.last_extra_buffer_idx; + *resource_id = handle->common->gbar.extra_buffer[*idx]; + } else { + if (!handle->common->widget.extra_buffer || handle->common->widget.last_extra_buffer_idx < 0) { + return WIDGET_ERROR_NOT_EXIST; + } + + *idx = handle->common->widget.last_extra_buffer_idx; + *resource_id = handle->common->widget.extra_buffer[*idx]; + } + + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_get_instance_id(widget_h handle, char **instance_id) +{ + if (!handle || handle->state != WIDGET_STATE_CREATE || !instance_id) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common || handle->common->state != WIDGET_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!handle->common->id) { + ErrPrint("Handler is not valid[%p]\n", handle); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + *instance_id = strdup(handle->common->id); + if (!*instance_id) { + ErrPrint("Out of memory: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + return WIDGET_ERROR_NONE; +} + +/* End of a file */ diff --git a/widget_viewer/src/widget_internal.c b/widget_viewer/src/widget_internal.c new file mode 100644 index 0000000..a767b12 --- /dev/null +++ b/widget_viewer/src/widget_internal.c @@ -0,0 +1,1061 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include "dlist.h" +#include "debug.h" +#include "widget_viewer.h" +#include "widget_viewer_internal.h" +#include "fb.h" +#include "conf.h" +#include "util.h" +#include "master_rpc.h" + +int errno; + +typedef enum event_state { + INFO_STATE_CALLBACK_IN_IDLE = 0x00, + INFO_STATE_CALLBACK_IN_PROCESSING = 0x01 +} event_state_e; + +struct event_info { + int is_deleted; + int (*handler)(widget_h handler, widget_event_type_e event, void *data); + void *user_data; +}; + +struct fault_info { + int is_deleted; + int (*handler)(widget_fault_type_e event, const char *pkgname, const char *filename, const char *func, void *data); + void *user_data; +}; + +static struct info { + struct dlist *widget_common_list; + struct dlist *widget_list; + struct dlist *event_list; + struct dlist *fault_list; + event_state_e event_state; + event_state_e fault_state; +} s_info = { + .widget_common_list = NULL, + .widget_list = NULL, + .event_list = NULL, + .fault_list = NULL, + .event_state = INFO_STATE_CALLBACK_IN_IDLE, + .fault_state = INFO_STATE_CALLBACK_IN_IDLE, +}; + +static inline void default_delete_cb(widget_h handler, int ret, void *data) +{ + DbgPrint("Default deleted event handler: %d\n", ret); +} + +static void del_ret_cb(widget_h handler, const struct packet *result, void *data) +{ + struct cb_info *info = data; + int ret; + widget_ret_cb cb; + void *cbdata; + + cb = info->cb; + cbdata = info->data; + _widget_destroy_cb_info(info); + + if (!result) { + ErrPrint("Connection lost?\n"); + ret = WIDGET_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = WIDGET_ERROR_INVALID_PARAMETER; + } + + if (ret == 0) { + handler->cbs.deleted.cb = cb; + handler->cbs.deleted.data = cbdata; + } else if (cb) { + cb(handler, ret, cbdata); + } + + /*! + * \note + * Do not call the deleted callback from here. + * master will send the "deleted" event. + * Then invoke this callback. + * + * if (handler->cbs.deleted.cb) + * handler->cbs.deleted.cb(handler, ret, handler->cbs.deleted.data); + */ +} + +struct widget_common *_widget_create_common_handle(widget_h handle, const char *pkgname, const char *cluster, const char *category) +{ + struct widget_common *common; + + common = calloc(1, sizeof(*common)); + if (!common) { + ErrPrint("Heap: %d\n", errno); + set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); + return NULL; + } + + common->pkgname = strdup(pkgname); + if (!common->pkgname) { + free(common); + set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); + return NULL; + } + + common->cluster = strdup(cluster); + if (!common->cluster) { + ErrPrint("Error: %d\n", errno); + free(common->pkgname); + free(common); + set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); + return NULL; + } + + common->category = strdup(category); + if (!common->category) { + ErrPrint("Error: %d\n", errno); + free(common->cluster); + free(common->pkgname); + free(common); + set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); + return NULL; + } + + /* Data provider will set this */ + common->widget.type = WIDGET_TYPE_FILE; + common->gbar.type = GBAR_TYPE_SCRIPT; + + /* Used for handling the mouse event on a box */ + common->widget.mouse_event = 0; + + /* Cluster infomration is not determined yet */ + common->nr_of_sizes = 0x01; + + common->timestamp = util_timestamp(); + common->is_user = 1; + common->delete_type = WIDGET_DELETE_PERMANENTLY; + + common->gbar.lock = NULL; + common->gbar.last_extra_buffer_idx = WIDGET_UNKNOWN_BUFFER; + + common->widget.lock = NULL; + common->widget.last_extra_buffer_idx = WIDGET_UNKNOWN_BUFFER; + + common->state = WIDGET_STATE_CREATE; + common->visible = WIDGET_HIDE_WITH_PAUSE; + + s_info.widget_common_list = dlist_append(s_info.widget_common_list, common); + return common; +} + +int _widget_destroy_common_handle(struct widget_common *common) +{ + dlist_remove_data(s_info.widget_common_list, common); + + common->state = WIDGET_STATE_DESTROYED; + + if (common->filename) { + (void)util_unlink(common->filename); + } + + free(common->cluster); + free(common->category); + free(common->id); + free(common->pkgname); + free(common->filename); + free(common->widget.auto_launch); + free(common->alt.icon); + free(common->alt.name); + + if (common->widget.fb) { + fb_destroy(common->widget.fb); + common->widget.fb = NULL; + } + + if (common->gbar.fb) { + fb_destroy(common->gbar.fb); + common->gbar.fb = NULL; + } + + return 0; +} + +int _widget_common_ref(struct widget_common *common, widget_h handle) +{ + common->widget_list = dlist_append(common->widget_list, handle); + common->refcnt++; + + return common->refcnt; +} + +int _widget_common_unref(struct widget_common *common, widget_h handle) +{ + int refcnt; + dlist_remove_data(common->widget_list, handle); + refcnt = --common->refcnt; + + return refcnt; +} + +int _widget_set_group(struct widget_common *common, const char *cluster, const char *category) +{ + void *pc = NULL; + void *ps = NULL; + + if (cluster) { + pc = strdup(cluster); + if (!pc) { + ErrPrint("Heap: %d (cluster: %s)\n", errno, cluster); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + } + + if (category) { + ps = strdup(category); + if (!ps) { + ErrPrint("Heap: %d (category: %s)\n", errno, category); + free(pc); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + } + + if (common->cluster) { + free(common->cluster); + } + + if (common->category) { + free(common->category); + } + + common->cluster = pc; + common->category = ps; + + return WIDGET_ERROR_NONE; +} + +void _widget_set_size(struct widget_common *common, int w, int h) +{ + widget_size_type_e size_type; + + common->widget.width = w; + common->widget.height = h; + + widget_service_get_size_type(w, h, &size_type); + if (size_type != WIDGET_SIZE_TYPE_UNKNOWN) { + widget_service_get_need_of_mouse_event(common->pkgname, size_type, (bool*)&common->widget.mouse_event); + } +} + +void _widget_set_update_mode(struct widget_common *common, int active_mode) +{ + common->is_active_update = active_mode; +} + +void _widget_set_gbarsize(struct widget_common *common, int w, int h) +{ + common->gbar.width = w; + common->gbar.height = h; +} + +void _widget_set_default_gbarsize(struct widget_common *common, int w, int h) +{ + common->gbar.default_width = w; + common->gbar.default_height = h; +} + +void _widget_invoke_fault_handler(widget_fault_type_e event, const char *pkgname, const char *file, const char *func) +{ + struct dlist *l; + struct dlist *n; + struct fault_info *info; + + s_info.fault_state = INFO_STATE_CALLBACK_IN_PROCESSING; + + dlist_foreach_safe(s_info.fault_list, l, n, info) { + if (!info->is_deleted && info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) { + info->is_deleted = 1; + } + + if (info->is_deleted) { + s_info.fault_list = dlist_remove(s_info.fault_list, l); + free(info); + } + } + + s_info.fault_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING; +} + +void _widget_invoke_event_handler(widget_h handler, widget_event_type_e event) +{ + struct dlist *l; + struct dlist *n; + struct event_info *info; + + if (event == WIDGET_EVENT_WIDGET_UPDATED && handler->common->refcnt > 1) { + if (handler->visible != WIDGET_SHOW) { + DbgPrint("Update requested(pending) - %s\n", handler->common->pkgname); + handler->paused_updating++; + return; + } else { + handler->paused_updating = 0; + } + } + + s_info.event_state = INFO_STATE_CALLBACK_IN_PROCESSING; + + dlist_foreach_safe(s_info.event_list, l, n, info) { + if (!info->is_deleted && info->handler(handler, event, info->user_data) == EXIT_FAILURE) { + DbgPrint("Event handler returns EXIT_FAILURE\n"); + info->is_deleted = 1; + } + + if (info->is_deleted) { + s_info.event_list = dlist_remove(s_info.event_list, l); + free(info); + } + } + + s_info.event_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING; +} + +struct widget_common *_widget_find_common_handle(const char *pkgname, const char *id) +{ + struct dlist *l; + struct widget_common *common; + + dlist_foreach(s_info.widget_common_list, l, common) { + if (!common->id) { + continue; + } + + if (!strcmp(common->pkgname, pkgname) && !strcmp(common->id, id)) { + return common; + } + } + + return NULL; +} + +struct widget_common *_widget_find_common_handle_by_timestamp(double timestamp) +{ + struct dlist *l; + struct widget_common *common; + + dlist_foreach(s_info.widget_common_list, l, common) { + if (common->timestamp == timestamp) { + return common; + } + } + + return NULL; +} + +widget_h _widget_new_widget(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category) +{ + widget_h handler; + + handler = calloc(1, sizeof(*handler)); + if (!handler) { + ErrPrint("Failed to create a new widget\n"); + return NULL; + } + + handler->common = _widget_create_common_handle(handler, pkgname, cluster, category); + if (!handler->common) { + ErrPrint("Heap: %d\n", errno); + free(handler); + return NULL; + } + + _widget_common_ref(handler->common, handler); + _widget_set_id(handler->common, id); + handler->common->timestamp = timestamp; + handler->common->state = WIDGET_STATE_CREATE; + handler->visible = WIDGET_HIDE_WITH_PAUSE; + handler->state = WIDGET_STATE_CREATE; + handler = _widget_ref(handler); + s_info.widget_list = dlist_append(s_info.widget_list, handler); + + return _widget_ref(handler); +} + +int _widget_delete_all(void) +{ + struct dlist *l; + struct dlist *n; + widget_h handler; + + dlist_foreach_safe(s_info.widget_list, l, n, handler) { + _widget_invoke_event_handler(handler, WIDGET_EVENT_DELETED); + _widget_unref(handler, 1); + } + + return WIDGET_ERROR_NONE; +} + +int _widget_set_content(struct widget_common *common, const char *content) +{ + char *pc = NULL; + + if (content) { + pc = strdup(content); + if (!pc) { + ErrPrint("heap: %d [%s]\n", errno, content); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + } + + free(common->content); + common->content = pc; + return WIDGET_ERROR_NONE; +} + +int _widget_set_title(struct widget_common *common, const char *title) +{ + char *pt = NULL; + + if (title) { + pt = strdup(title); + if (!pt) { + ErrPrint("heap: %d [%s]\n", errno, title); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + } + + free(common->title); + common->title = pt; + return WIDGET_ERROR_NONE; +} + +void _widget_set_size_list(struct widget_common *common, int size_list) +{ + common->widget.size_list = size_list; +} + +void _widget_set_auto_launch(struct widget_common *common, const char *auto_launch) +{ + char *pa = NULL; + + if (!auto_launch || !strlen(auto_launch)) { + return; + } + + pa = strdup(auto_launch); + if (!pa) { + ErrPrint("heap: %d, [%s]\n", errno, auto_launch); + return; + } + + free(common->widget.auto_launch); + common->widget.auto_launch = pa; +} + +void _widget_set_priority(struct widget_common *common, double priority) +{ + common->widget.priority = priority; +} + +void _widget_set_id(struct widget_common *common, const char *id) +{ + char *pi = NULL; + + if (id) { + pi = strdup(id); + if (!pi) { + ErrPrint("heap: %d [%s]\n", errno, pi); + return; + } + } + + free(common->id); + common->id = pi; +} + +void _widget_unlink_filename(struct widget_common *common) +{ + if (common->widget.type == WIDGET_TYPE_FILE || common->widget.type == WIDGET_TYPE_TEXT) { + if (common->filename && common->filename[0] && unlink(common->filename) < 0) { + ErrPrint("unlink: %d (%s)\n", errno, common->filename); + } + } +} + +void _widget_set_filename(struct widget_common *common, const char *filename) +{ + if (common->filename) { + free(common->filename); + } + + common->filename = strdup(filename); + if (!common->filename) { + ErrPrint("Heap: %d\n", errno); + } +} + +void _widget_set_alt_icon(struct widget_common *common, const char *icon) +{ + char *_icon = NULL; + + if (icon && strlen(icon)) { + _icon = strdup(icon); + if (!_icon) { + ErrPrint("Heap: %d\n", errno); + } + } + + free(common->alt.icon); + common->alt.icon = _icon; +} + +void _widget_set_alt_name(struct widget_common *common, const char *name) +{ + char *_name = NULL; + + if (name && strlen(name)) { + _name = strdup(name); + if (!_name) { + ErrPrint("Heap: %d\n", errno); + } + } + + free(common->alt.name); + common->alt.name = _name; +} + +int _widget_set_widget_fb(struct widget_common *common, const char *filename) +{ + struct fb_info *fb; + + if (!common) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + fb = common->widget.fb; + if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */ + return WIDGET_ERROR_NONE; + } + + common->widget.fb = NULL; + + if (!filename || filename[0] == '\0') { + if (fb) { + fb_destroy(fb); + } + return WIDGET_ERROR_NONE; + } + + common->widget.fb = fb_create(filename, common->widget.width, common->widget.height); + if (!common->widget.fb) { + ErrPrint("Faield to create a FB\n"); + if (fb) { + fb_destroy(fb); + } + return WIDGET_ERROR_FAULT; + } + + if (fb) { + fb_destroy(fb); + } + + return WIDGET_ERROR_NONE; +} + +int _widget_set_gbar_fb(struct widget_common *common, const char *filename) +{ + struct fb_info *fb; + + if (!common || common->state != WIDGET_STATE_CREATE) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + fb = common->gbar.fb; + if (fb && !strcmp(fb_id(fb), filename)) { + /* BUFFER is not changed, just update the content */ + return WIDGET_ERROR_ALREADY_EXIST; + } + common->gbar.fb = NULL; + + if (!filename || filename[0] == '\0') { + if (fb) { + fb_destroy(fb); + } + return WIDGET_ERROR_NONE; + } + + common->gbar.fb = fb_create(filename, common->gbar.width, common->gbar.height); + if (!common->gbar.fb) { + ErrPrint("Failed to create a FB\n"); + if (fb) { + fb_destroy(fb); + } + return WIDGET_ERROR_FAULT; + } + + if (fb) { + fb_destroy(fb); + } + return WIDGET_ERROR_NONE; +} + +struct fb_info *_widget_get_widget_fb(struct widget_common *common) +{ + return common->widget.fb; +} + +struct fb_info *_widget_get_gbar_fb(struct widget_common *common) +{ + return common->gbar.fb; +} + +void _widget_set_user(struct widget_common *common, int user) +{ + common->is_user = user; +} + +void _widget_set_pinup(struct widget_common *common, int pinup_supported) +{ + common->widget.pinup_supported = pinup_supported; +} + +void _widget_set_text_widget(struct widget_common *common) +{ + common->widget.type = WIDGET_TYPE_TEXT; +} + +void _widget_set_text_gbar(struct widget_common *common) +{ + common->gbar.type = GBAR_TYPE_TEXT; +} + +int _widget_text_widget(struct widget_common *common) +{ + return common->widget.type == WIDGET_TYPE_TEXT; +} + +int _widget_text_gbar(struct widget_common *common) +{ + return common->gbar.type == GBAR_TYPE_TEXT; +} + +void _widget_set_period(struct widget_common *common, double period) +{ + common->widget.period = period; +} + +widget_h _widget_ref(widget_h handler) +{ + if (!handler) { + return NULL; + } + + handler->refcnt++; + return handler; +} + +widget_h _widget_unref(widget_h handler, int destroy_common) +{ + if (!handler) { + return NULL; + } + + handler->refcnt--; + if (handler->refcnt > 0) { + return handler; + } + + if (handler->cbs.created.cb) { + handler->cbs.created.cb(handler, WIDGET_ERROR_FAULT, handler->cbs.created.data); + handler->cbs.created.cb = NULL; + handler->cbs.created.data = NULL; + } + + if (handler->cbs.deleted.cb) { + handler->cbs.deleted.cb(handler, WIDGET_ERROR_FAULT, handler->cbs.deleted.data); + handler->cbs.deleted.cb = NULL; + handler->cbs.deleted.data = NULL; + } + + if (handler->cbs.pinup.cb) { + handler->cbs.pinup.cb(handler, WIDGET_ERROR_FAULT, handler->cbs.pinup.data); + handler->cbs.pinup.cb = NULL; + handler->cbs.pinup.data = NULL; + } + + if (handler->cbs.group_changed.cb) { + handler->cbs.group_changed.cb(handler, WIDGET_ERROR_FAULT, handler->cbs.group_changed.data); + handler->cbs.group_changed.cb = NULL; + handler->cbs.group_changed.data = NULL; + } + + if (handler->cbs.period_changed.cb) { + handler->cbs.period_changed.cb(handler, WIDGET_ERROR_FAULT, handler->cbs.period_changed.data); + handler->cbs.period_changed.cb = NULL; + handler->cbs.period_changed.data = NULL; + } + + if (handler->cbs.size_changed.cb) { + handler->cbs.size_changed.cb(handler, WIDGET_ERROR_FAULT, handler->cbs.size_changed.data); + handler->cbs.size_changed.cb = NULL; + handler->cbs.size_changed.data = NULL; + } + + if (handler->cbs.gbar_created.cb) { + handler->cbs.gbar_created.cb(handler, WIDGET_ERROR_FAULT, handler->cbs.gbar_created.data); + handler->cbs.gbar_created.cb = NULL; + handler->cbs.gbar_created.data = NULL; + } + + if (handler->cbs.gbar_destroyed.cb) { + handler->cbs.gbar_destroyed.cb(handler, WIDGET_ERROR_FAULT, handler->cbs.gbar_destroyed.data); + handler->cbs.gbar_destroyed.cb = NULL; + handler->cbs.gbar_destroyed.data = NULL; + } + + if (handler->cbs.update_mode.cb) { + handler->cbs.update_mode.cb(handler, WIDGET_ERROR_FAULT, handler->cbs.update_mode.data); + handler->cbs.update_mode.cb = NULL; + handler->cbs.update_mode.data = NULL; + } + + if (handler->cbs.access_event.cb) { + handler->cbs.access_event.cb(handler, WIDGET_ACCESS_STATUS_ERROR, handler->cbs.access_event.data); + handler->cbs.access_event.cb = NULL; + handler->cbs.access_event.data = NULL; + } + + if (handler->cbs.key_event.cb) { + handler->cbs.key_event.cb(handler, WIDGET_KEY_STATUS_ERROR, handler->cbs.key_event.data); + handler->cbs.key_event.cb = NULL; + handler->cbs.key_event.data = NULL; + } + + dlist_remove_data(s_info.widget_list, handler); + + handler->state = WIDGET_STATE_DESTROYED; + if (_widget_common_unref(handler->common, handler) == 0) { + if (destroy_common) { + /*! + * \note + * Lock file should be deleted after all callbacks are processed. + */ + (void)widget_service_destroy_lock(handler->common->widget.lock); + handler->common->widget.lock = NULL; + _widget_destroy_common_handle(handler->common); + } + } + free(handler); + DbgPrint("Handler is released\n"); + return NULL; +} + +int _widget_send_delete(widget_h handler, int type, widget_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + int ret; + + if (handler->common->request.deleted) { + ErrPrint("Already in-progress\n"); + if (cb) { + cb(handler, WIDGET_ERROR_NONE, data); + } + return WIDGET_ERROR_RESOURCE_BUSY; + } + + if (!cb) { + cb = default_delete_cb; + } + + packet = packet_create("delete", "ssid", handler->common->pkgname, handler->common->id, type, handler->common->timestamp); + if (!packet) { + ErrPrint("Failed to build a param\n"); + if (cb) { + cb(handler, WIDGET_ERROR_FAULT, data); + } + + return WIDGET_ERROR_FAULT; + } + + cbinfo = _widget_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + ErrPrint("Failed to create cbinfo\n"); + if (cb) { + cb(handler, WIDGET_ERROR_FAULT, data); + } + + return WIDGET_ERROR_FAULT; + } + + ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo); + if (ret < 0) { + /*! + * Packet is destroyed by master_rpc_async_request. + */ + _widget_destroy_cb_info(cbinfo); + + if (cb) { + cb(handler, WIDGET_ERROR_FAULT, data); + } + } else { + handler->common->request.deleted = 1; + } + + return ret; +} + +int _widget_sync_widget_fb(struct widget_common *common) +{ + int ret; + + if (fb_type(_widget_get_widget_fb(common)) == WIDGET_FB_TYPE_FILE) { + (void)widget_service_acquire_lock(common->widget.lock); + ret = fb_sync(_widget_get_widget_fb(common), common->widget.last_damage.x, common->widget.last_damage.y, common->widget.last_damage.w, common->widget.last_damage.h); + (void)widget_service_release_lock(common->widget.lock); + } else { + ret = fb_sync(_widget_get_widget_fb(common), common->widget.last_damage.x, common->widget.last_damage.y, common->widget.last_damage.w, common->widget.last_damage.h); + } + + return ret; +} + +int _widget_sync_gbar_fb(struct widget_common *common) +{ + int ret; + + if (fb_type(_widget_get_gbar_fb(common)) == WIDGET_FB_TYPE_FILE) { + (void)widget_service_acquire_lock(common->gbar.lock); + ret = fb_sync(_widget_get_gbar_fb(common), common->gbar.last_damage.x, common->gbar.last_damage.y, common->gbar.last_damage.w, common->gbar.last_damage.h); + (void)widget_service_release_lock(common->gbar.lock); + } else { + ret = fb_sync(_widget_get_gbar_fb(common), common->gbar.last_damage.x, common->gbar.last_damage.y, common->gbar.last_damage.w, common->gbar.last_damage.h); + } + + return ret; +} + +struct widget_common *_widget_find_sharable_common_handle(const char *pkgname, const char *content, int w, int h, const char *cluster, const char *category) +{ + struct dlist *l; + struct widget_common *common; + + if (!conf_shared_content()) { + /*! + * Shared content option is turnned off. + */ + return NULL; + } + + dlist_foreach(s_info.widget_common_list, l, common) { + if (common->state != WIDGET_STATE_CREATE) { + continue; + } + + if (strcmp(common->pkgname, pkgname)) { + continue; + } + + if (strcmp(common->cluster, cluster)) { + DbgPrint("Cluster mismatched\n"); + continue; + } + + if (strcmp(common->category, category)) { + DbgPrint("Category mismatched\n"); + continue; + } + + if (common->content && content) { + if (strcmp(common->content, content)) { + DbgPrint("%s Content ([%s] <> [%s])\n", common->pkgname, common->content, content); + continue; + } + } else { + int c1_len; + int c2_len; + + /*! + * \note + * We assumes "" (ZERO length string) to NULL + */ + c1_len = common->content ? strlen(common->content) : 0; + c2_len = content ? strlen(content) : 0; + if (c1_len != c2_len) { + DbgPrint("%s Content %p <> %p\n", common->pkgname, common->content, content); + continue; + } + } + + if (common->request.size_changed) { + DbgPrint("Changing size\n"); + /*! + * \note + * Do not re-use resizing instance. + * We will not use predicted size. + */ + continue; + } + + if (common->request.created) { + DbgPrint("Creating now but re-use it (%s)\n", common->pkgname); + } + + if (common->widget.width != w || common->widget.height != h) { + DbgPrint("Size mismatched\n"); + continue; + } + + DbgPrint("common handle is found: %p\n", common); + return common; + } + + return NULL; +} + +widget_h _widget_find_widget_in_show(struct widget_common *common) +{ + struct dlist *l; + widget_h item; + + dlist_foreach(common->widget_list, l, item) { + if (item->visible == WIDGET_SHOW) { + DbgPrint("%s visibility is not changed\n", common->pkgname); + return item; + } + } + + return NULL; +} + +widget_h _widget_get_widget_nth(struct widget_common *common, int nth) +{ + widget_h item; + struct dlist *l; + + l = dlist_nth(common->widget_list, nth); + item = dlist_data(l); + + return item; +} + +int _widget_add_event_handler(widget_event_handler_cb widget_cb, void *data) +{ + struct event_info *info; + info = malloc(sizeof(*info)); + if (!info) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + info->handler = widget_cb; + info->user_data = data; + info->is_deleted = 0; + + s_info.event_list = dlist_append(s_info.event_list, info); + return WIDGET_ERROR_NONE; +} + +void *_widget_remove_event_handler(widget_event_handler_cb widget_cb) +{ + struct event_info *info; + struct dlist *l; + + dlist_foreach(s_info.event_list, l, info) { + if (info->handler == widget_cb) { + void *data; + + data = info->user_data; + + if (s_info.event_state == INFO_STATE_CALLBACK_IN_PROCESSING) { + info->is_deleted = 1; + } else { + s_info.event_list = dlist_remove(s_info.event_list, l); + free(info); + } + + return data; + } + } + + return NULL; +} + +int _widget_add_fault_handler(widget_fault_handler_cb widget_cb, void *data) +{ + struct fault_info *info; + info = malloc(sizeof(*info)); + if (!info) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + info->handler = widget_cb; + info->user_data = data; + info->is_deleted = 0; + + s_info.fault_list = dlist_append(s_info.fault_list, info); + return WIDGET_ERROR_NONE; +} + +void *_widget_remove_fault_handler(widget_fault_handler_cb widget_cb) +{ + struct fault_info *info; + struct dlist *l; + + dlist_foreach(s_info.fault_list, l, info) { + if (info->handler == widget_cb) { + void *data; + + data = info->user_data; + + if (s_info.fault_state == INFO_STATE_CALLBACK_IN_PROCESSING) { + info->is_deleted = 1; + } else { + s_info.fault_list = dlist_remove(s_info.fault_list, l); + free(info); + } + + return data; + } + } + + return NULL; +} + +struct cb_info *_widget_create_cb_info(widget_ret_cb cb, void *data) +{ + struct cb_info *info; + + info = malloc(sizeof(*info)); + if (!info) { + ErrPrint("Heap: %d\n", errno); + return NULL; + } + + info->cb = cb; + info->data = data; + return info; +} + +void _widget_destroy_cb_info(struct cb_info *info) +{ + free(info); +} + +/* End of a file */ diff --git a/widget_viewer/widget_viewer.pc.in b/widget_viewer/widget_viewer.pc.in new file mode 100644 index 0000000..8e78cb2 --- /dev/null +++ b/widget_viewer/widget_viewer.pc.in @@ -0,0 +1,12 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: widget-viewer +Description: Support development of the widget Viewer +Version: @VERSION@ +Requires: widget_service +Libs: -L${libdir} -lwidget_viewer +Cflags: -I${includedir} +cppflags: -I${includedir} diff --git a/widget_viewer_evas/CMakeLists.txt b/widget_viewer_evas/CMakeLists.txt new file mode 100644 index 0000000..cb4cd17 --- /dev/null +++ b/widget_viewer_evas/CMakeLists.txt @@ -0,0 +1,76 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(widget_viewer_evas C) + +SET(PREFIX "${CMAKE_INSTALL_PREFIX}") +SET(EXEC_PREFIX "\${prefix}") +SET(PROJECT_NAME "${PROJECT_NAME}") +SET(LIBDIR ${LIB_INSTALL_DIR}) +SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}") +SET(VERSION_MAJOR 1) +SET(VERSION "${VERSION_MAJOR}.0.0") +SET(EDJDIR "/usr/share/${PROJECT_NAME}/res/edje") +SET(IMGDIR "/usr/share/${PROJECT_NAME}/res/image") +SET(LOCALEDIR "/usr/share/${PROJECT_NAME}/res/locale") + +INCLUDE(FindPkgConfig) +pkg_check_modules(viewer_evas REQUIRED + dlog + widget_service + elementary + pkgmgr-info + capi-system-info +) + +SET(BUILD_SOURCE + src/widget_viewer_evas.c +) + +IF (X11_SUPPORT) +SET(BUILD_SOURCE + ${BUILD_SOURCE} + src/util_x11.c +) +ENDIF (X11_SUPPORT) + +IF (WAYLAND_SUPPORT) +SET(BUILD_SOURCE + ${BUILD_SOURCE} + src/util_wayland.c +) +ENDIF (WAYLAND_SUPPORT) + +FOREACH(flag ${viewer_evas_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline -g") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") + +ADD_DEFINITIONS("-DWIDGET_EVAS_RESOURCE_EDJ=\"${EDJDIR}/widget_viewer_evas.edj\"") +ADD_DEFINITIONS("-DWIDGET_EVAS_RESOURCE_PD=\"gbar\"") +ADD_DEFINITIONS("-DWIDGET_EVAS_RESOURCE_LB=\"widget\"") +ADD_DEFINITIONS("-DWIDGET_EVAS_RESOURCE_IMG=\"widget,image\"") +ADD_DEFINITIONS("-DWIDGET_EVAS_RESOURCE_PO=\"${LOCALEDIR}\"") +ADD_DEFINITIONS("-DPKGNAME=\"${PROJECT_NAME}\"") + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/widget_viewer/include) + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${BUILD_SOURCE}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION}) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${viewer_evas_LDFLAGS} "-lpthread" widget_viewer) + +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) +SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PROJECT_NAME}.pc") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${PROJECT_NAME}.h DESTINATION include/${PROJECT_NAME}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${PROJECT_NAME}_internal.h DESTINATION include/${PROJECT_NAME}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME "lib${PROJECT_NAME}") + +ADD_SUBDIRECTORY(res) diff --git a/widget_viewer_evas/LICENSE b/widget_viewer_evas/LICENSE new file mode 100644 index 0000000..571fe79 --- /dev/null +++ b/widget_viewer_evas/LICENSE @@ -0,0 +1,206 @@ +Flora License + +Version 1.1, April, 2013 + +http://floralicense.org/license/ + +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. + +"Tizen Certified Platform" shall mean a software platform that complies +with the standards set forth in the Tizen Compliance Specification +and passes the Tizen Compliance Tests as defined from time to time +by the Tizen Technical Steering Group and certified by the Tizen +Association or its designated agent. + +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 +solely as incorporated into a Tizen Certified Platform, 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 solely +as incorporated into a Tizen Certified Platform 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 pursuant to the copyright license +above, in any medium, with or without modifications, and in Source or +Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works + a copy of this License; and + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + 3. 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 + 4. 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 + and your own copyright statement or terms and conditions do not conflict + the conditions stated in the License including section 3. + +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 Flora License to your work + +To apply the Flora 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 Flora License, Version 1.1 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://floralicense.org/license/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT 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/widget_viewer_evas/doc/image/PD.png b/widget_viewer_evas/doc/image/PD.png new file mode 100644 index 0000000000000000000000000000000000000000..ebb7367b5531567bb229e817f1e2b28834205a39 GIT binary patch literal 23224 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 literal 0 HcmV?d00001 diff --git a/widget_viewer_evas/doc/image/download_folder.png b/widget_viewer_evas/doc/image/download_folder.png new file mode 100644 index 0000000000000000000000000000000000000000..1e5e01bac5c8764c6341bb1836744abbc3bf871a GIT binary patch literal 34630 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≦hjK5g4oe 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%0DS(Dc>6os3pd^?Sei>l1>E0Y1X{VfH0u2R~2Pg#m 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

F2Xl(+2^y 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 literal 0 HcmV?d00001 diff --git a/widget_viewer_evas/doc/image/twitter.png b/widget_viewer_evas/doc/image/twitter.png new file mode 100644 index 0000000000000000000000000000000000000000..36bce257de85e2710e5f85c8c4b9f2d307efacd6 GIT binary patch literal 45791 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 + * @section CAPI_WIDGET_VIEWER_EVAS_MODULE_OVERVIEW Overview + * Tizen Platform supports development of Widget Viewer Application. + * Many kinds of widgets can be installed to the Tizen Platform enhanced devices. + * Also it could be used by user via some kinds of viewer applications. + * + * This document will show you what kinds of APIs are exist and how to use them. + * + * First of all, the Tizen Platform uses the EFL as a core UIFW. + * So this API set also based on the EFL. + */ diff --git a/widget_viewer_evas/include/util.h b/widget_viewer_evas/include/util.h new file mode 100644 index 0000000..2bb06dd --- /dev/null +++ b/widget_viewer_evas/include/util.h @@ -0,0 +1,29 @@ +/* + * Samsung API + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT 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 __WIDGET_VIEWER_UTIL_H +#define __WIDGET_VIEWER_UTIL_H + +extern int util_screen_size_get(int *w, int *h); +extern unsigned int util_replace_native_surface(struct widget *handle, int gbar, Evas_Object *content, unsigned int pixmap); +extern int util_set_native_surface(struct widget *handle, int gbar, Evas_Object *content, unsigned int pixmap, int skip_acquire); +extern unsigned int util_get_resource_id_of_native_surface(Evas_Native_Surface *surface); +extern void *util_display_get(void); + +#endif + +/* End of a file */ diff --git a/widget_viewer_evas/include/widget_viewer_evas.h b/widget_viewer_evas/include/widget_viewer_evas.h new file mode 100644 index 0000000..48540bd --- /dev/null +++ b/widget_viewer_evas/include/widget_viewer_evas.h @@ -0,0 +1,412 @@ +/* + * Samsung API + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT 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 __WIDGET_VIEWER_EVAS_H +#define __WIDGET_VIEWER_EVAS_H + +#include + +#include "widget_service.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @file widget_viewer_evas.h + * @brief This file declares API of libwidget-viewer-evas library + * @since_tizen 2.3.1 + */ + +/** + * @addtogroup CAPI_WIDGET_VIEWER_EVAS_MODULE + * @{ + */ + +/** + * @since_tizen 2.3.1 + * @brief Default refresh interval of widgets. + * @see #widget_viewer_evas_add_widget + * @see #widget_viewer_evas_get_period + */ +#define WIDGET_VIEWER_EVAS_DEFAULT_PERIOD -1.0f + +/** + * @since_tizen 2.3.1 + * @brief Event names for smart callback of widget events. You can listen some events from widget by calling evas_object_smart_callback_add. + * @see #widget_evas_event_info_s + * @see evas_object_smart_callback_add + */ +#define WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED "widget,create,aborted" /**< Widget creation is aborted */ +#define WIDGET_SMART_SIGNAL_WIDGET_CREATED "widget,created" /**< Widget is created */ +#define WIDGET_SMART_SIGNAL_WIDGET_RESIZE_ABORTED "widget,resize,aborted" /**< Resizing widget is aborted */ +#define WIDGET_SMART_SIGNAL_WIDGET_RESIZED "widget,resized" /**< Widget is resized */ +#define WIDGET_SMART_SIGNAL_WIDGET_FAULTED "widget,faulted" /**< Widget has faulted */ +#define WIDGET_SMART_SIGNAL_UPDATED "updated" /**< Widget content is updated */ +#define WIDGET_SMART_SIGNAL_EXTRA_INFO_UPDATED "info,updated" /**< Widget extra info is updated */ +#define WIDGET_SMART_SIGNAL_PROVIDER_DISCONNECTED "provider,disconnected" /**< Provider is disconnected */ +#define WIDGET_SMART_SIGNAL_CONTROL_SCROLLER "control,scroller" /**< Control Scroller */ +#define WIDGET_SMART_SIGNAL_WIDGET_DELETED "widget,deleted" /**< Widget is deleted */ +#define WIDGET_SMART_SIGNAL_PERIOD_CHANGED "widget,period,changed" /**< Period is changed */ + +/** + * @since_tizen 2.3.1 + * @brief Data structure which will be sent as a parameter of smart callback for signals WIDGET_SMART_SIGNAL_XXX + * @see #WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED + * @see #WIDGET_SMART_SIGNAL_WIDGET_CREATED + * @see #WIDGET_SMART_SIGNAL_WIDGET_RESIZE_ABORTED + * @see #WIDGET_SMART_SIGNAL_WIDGET_RESIZED + * @see #WIDGET_SMART_SIGNAL_WIDGET_FAULTED + * @see #WIDGET_SMART_SIGNAL_UPDATED + * @see #WIDGET_SMART_SIGNAL_EXTRA_INFO_UPDATED + * @see #WIDGET_SMART_SIGNAL_PROVIDER_DISCONNECTED + * @see #WIDGET_SMART_SIGNAL_CONTROL_SCROLLER + * @see #WIDGET_SMART_SIGNAL_WIDGET_DELETED + * @see #WIDGET_SMART_SIGNAL_PERIOD_CHANGED + */ +typedef struct widget_evas_event_info { + const char *widget_app_id; /**< Widget application id */ + widget_event_type_e event; /**< Event type for detail event information - WIDGET_EVENT_XXX, refer the widget_serivce.h */ + int error; /**< Error type - WIDGET_ERROR_XXX, refer the widget_errno.h */ +} widget_evas_event_info_s; + +/** + * @brief Enumerations for setting visibility status of a widget. + * @since_tizen 2.3.1 + * @see #widget_viewer_evas_freeze_visibility + */ +typedef enum widget_visibility_status { + WIDGET_VISIBILITY_STATUS_SHOW_FIXED = 1, /**< Visibility of the widget will be fixed as 'SHOW'*/ + WIDGET_VISIBILITY_STATUS_HIDE_FIXED = 2 /**< Visibility of the widget will be fixed as 'HIDE'*/ +} widget_visibility_status_e; + +/** + * @brief Configuration keys + * @since_tizen 2.3.1 + * @see #widget_viewer_evas_set_option + */ +typedef enum widget_evas_conf { + WIDGET_VIEWER_EVAS_MANUAL_PAUSE_RESUME = 0x0001, /**< Visibility will be changed manually. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_USE_FIXED_SIZE = 0x0008, /**< Widget will be resized to specific size only. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_EASY_MODE = 0x0010, /**< Easy mode on/off. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_SCROLL_X = 0x0020, /**< Box will be scrolled from left to right vice versa. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_SCROLL_Y = 0x0040, /**< Box will be scrolled from top to bottom vice versa. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_EVENT_AUTO_FEED = 0x0080, /**< Feeds event automatically from the master provider. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_DELAYED_RESUME = 0x0100, /**< Delaying the pause/resume when it is automatically changed. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_SENSITIVE_MOVE = 0x0200, /**< Force feeds mouse up event if the box is moved. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_AUTO_RENDER_SELECTION = 0x0400, /**< Select render automatically, if a box moved, do not sync using animator, or use the animator. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_DIRECT_UPDATE = 0x0800, /**< Enable direct update path. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_USE_RENDER_ANIMATOR = 0x1000, /**< Use the render animator or not. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_SKIP_ACQUIRE = 0x2000, /**< Even if the viewer cannot get acquired resource id, try to update using default one. 1 : on, 0 : off */ + WIDGET_VIEWER_EVAS_UNKNOWN = 0xFFFF +} widget_evas_conf_e; + +/** + * @brief Initializes the widget system + * @since_tizen 2.3.1 + * @param[in] win Window object + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_NONE If success + * @retval #WIDGET_ERROR_INVALID_PARAMETER + * @retval #WIDGET_ERROR_PERMISSION_DENIED Permission denied + * @see #widget_viewer_evas_fini + */ +extern int widget_viewer_evas_init(Evas_Object *win); + +/** + * @brief Finalizes the widget system + * @since_tizen 2.3.1 + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_NONE If success + * @retval #WIDGET_ERROR_FAULT Unrecoverable error occurred + * @see #widget_viewer_evas_init + */ +extern int widget_viewer_evas_fini(void); + +/** + * @brief Creates a new widget object + * @since_tizen 2.3.1 + * @param[in] parent Evas Object of parent + * @param[in] widget_id widget id + * @param[in] content_info Contents that will be given to the widget instance + * @param[in] period Update period (@c WIDGET_DEFAULT_PERIOD can be used for this; this argument will be used to specify the period of updating contents of a widget) + * @return Widget Object + * @retval NULL if it fails to create a new widget object and you can get the reason of failure using get_last_result() + * @see #widget_service_get_widget_id + */ +extern Evas_Object *widget_viewer_evas_add_widget(Evas_Object *parent, const char *widget_id, const char *content_info, double period); + +/** + * @brief Notifies the status of the viewer to all providers + * @details If you call this, all providers will gets "resumed" event. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_NONE if success + * @retval #WIDGET_ERROR_FAULT if it failed to send state (paused) info + * @retval #WIDGET_ERROR_PERMISSION_DENIED Permission denied + * @see widget_viewer_evas_notify_paused_status_of_viewer() + */ +extern int widget_viewer_evas_notify_resumed_status_of_viewer(void); + +/** + * @brief Notifies the status of the viewer to all providers + * @details If you call this, all providers will gets "paused" event. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_NONE if success + * @retval #WIDGET_ERROR_FAULT if it failed to send state (resumed) info + * @retval #WIDGET_ERROR_PERMISSION_DENIED Permission denied + * @see widget_viewer_evas_notify_resumed_status_of_viewer() + */ +extern int widget_viewer_evas_notify_paused_status_of_viewer(void); + +/** + * @brief Notifies the orientation of the viewer to all providers + * @details If you call this, all providers will gets "rotated" event. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] orientation orientation of viewer + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_NONE if success + * @retval #WIDGET_ERROR_FAULT if it failed to send state (resumed) info + * @retval #WIDGET_ERROR_PERMISSION_DENIED Permission denied + */ +extern int widget_viewer_evas_notify_orientation_of_viewer(int orientation); + +/** + * @brief Pauses given widget. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] widget a widget object + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_NONE if success + * @retval #WIDGET_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_ERROR_PERMISSION_DENIED Permission denied + * @retval #WIDGET_ERROR_FAULT if it failed to send state (resumed) info + */ +extern int widget_viewer_evas_pause_widget(Evas_Object *widget); + +/** + * @brief Resume given widget. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] widget a widget object + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_NONE if success + * @retval #WIDGET_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_ERROR_FAULT if it failed to send state (resumed) info + * @retval #WIDGET_ERROR_PERMISSION_DENIED Permission denied + */ +extern int widget_viewer_evas_resume_widget(Evas_Object *widget); + +/** + * @brief Changes the configurable values of widget system + * @since_tizen 2.3.1 + * @param[in] type Configuration item + * @param[in] value Its value + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_NONE if success + * @retval #WIDGET_ERROR_INVALID_PARAMETER Invalid argument + * @see #widget_evas_conf + */ +extern int widget_viewer_evas_set_option(widget_evas_conf_e type, int value); + +/** + * @brief Gets content string of widget + * @details This string can be used for creating contents of widget again after reboot a device or recovered from crash(abnormal status) + * @remarks Returned string should not be freed. + * @since_tizen 2.3.1 + * @param[in] widget a widget object + * @return content string to be recognize content of the widget + * @retval NULL if there is no specific content string. + * @post Returned string should not be freed + */ +extern const char *widget_viewer_evas_get_content_info(Evas_Object *widget); + +/** + * @brief Gets summarized string of the widget content for accessibility. + * @details If the accessibility feature is turned on, a viewer can use this text to describe the widget. + * @remarks Returned string should not be freed. + * @since_tizen 2.3.1 + * @param[in] widget a widget object + * @return title string to be used for summarizing the widget + * @retval NULL if there is no summarized text for content of given widget. + */ +extern const char *widget_viewer_evas_get_title_string(Evas_Object *widget); + +/** + * @brief Gets the id of the widget + * @remarks Returned string should not be freed. + * @since_tizen 2.3.1 + * @param[in] widget a widget object + * @return widget id + * @retval NULL if an error occurred and you can get the reason of failure using get_last_result() + */ +extern const char *widget_viewer_evas_get_widget_id(Evas_Object *widget); + +/** + * @brief Gets the update period of the widget. + * @since_tizen 2.3.1 + * @param[in] widget a widget object + * @return period the update period of the widget. + * @retval the update interval of the widget + */ +extern double widget_viewer_evas_get_period(Evas_Object *widget); + +/** + * @brief Cancels click event procedure. + * @details If you call this function after feed the mouse_down(or mouse_set) event, the widget will get ON_HOLD events.\n + * If a widget gets ON_HOLD event, it will not do anything even if you feed mouse_up(or mouse_unset) event.\n + * @since_tizen 2.3.1 + * @param[in] widget a widget object + * + */ +extern void widget_viewer_evas_cancel_click_event(Evas_Object *widget); + +/* + * @brief Hides the preview of the widget + * @remarks This function should be called right after create the widget object before resizing it + * @since_tizen 2.3.1 + * @param[in] widget a widget object + */ +extern void widget_viewer_evas_disable_preview(Evas_Object *widget); + +/** + * @brief Hides the help text of the widget + * @details While loading a box, hide the help text + * @remarks This function should be called right after create the widget object before resizing it + * @since_tizen 2.3.1 + * @param[in] widget a widget object + */ +extern void widget_viewer_evas_disable_overlay_text(Evas_Object *widget); + +/** + * @brief Hides the loading message of the widget + * @details if you disable it, there is no preview & help text while creating a widget object + * @remarks This function should be called right after create the widget object before resizing it + * @since_tizen 2.3.1 + * @param[in] widget a widget object + */ +extern void widget_viewer_evas_disable_loading(Evas_Object *widget); + +/** + * @brief Feeds the mouse_up event to the provider of the widget + * @details This is very similar with widget_viewer_evas_cancel_click(), but this will sends mouse_up event explicitly.\n + * Also feed the ON_HOLD event before feeds mouse_up event. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] widget a widget object + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_NONE if success + * @retval #WIDGET_ERROR_INVALID_PARAMETER Invalid argument + * @retval #WIDGET_ERROR_PERMISSION_DENIED Permission denied + */ +extern int widget_viewer_evas_feed_mouse_up_event(Evas_Object *widget); + +/** + * @brief Activate a widget in faulted state. + * @details A widget in faulted state MUST be activated before adding the widget. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] widget a widget object faulted + */ +extern void widget_viewer_evas_activate_faulted_widget(Evas_Object *widget); + +/** + * @brief Check whether the widget is faulted. + * @since_tizen 2.3.1 + * @param[in] widget a widget object + * @return faulted state of the widget and you can get the result state of this function by using get_last_result() + * @retval true for faulted state + * @retval false for not faulted state + */ +extern bool widget_viewer_evas_is_faulted(Evas_Object *widget); + +/** + * @brief Freezes visibility of the widget + * @details If you don't want to change the visibility automatically, freeze it.\n + * The visibility will not be changed even though a box disappeared(hidden)/displayed(shown) from/on the screen. + * @since_tizen 2.3.1 + * @param[in] widget a widget object + * @param[in] status a visibility status of the widget + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_NONE if success + * @retval #WIDGET_ERROR_INVALID_PARAMETER Invalid argument + * @see #widget_visibility_status_e + */ +extern int widget_viewer_evas_freeze_visibility(Evas_Object *widget, widget_visibility_status_e status); + +/** + * @brief Thaws visibility of the widget + * @details If you want to let the visibility change automatically again, call this function. + * @since_tizen 2.3.1 + * @param[in] widget a widget object + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_NONE if success + * @retval #WIDGET_ERROR_INVALID_PARAMETER Invalid argument + */ +extern int widget_viewer_evas_thaw_visibility(Evas_Object *widget); + +/** + * @brief Get the frozen state of visibility option. + * @since_tizen 2.3.1 + * @param[in] widget a widget object + * @return fixed state of visibility and you can get the result state of this function by using get_last_result() + * @retval true for frozen state + * @retval false for not frozen state + */ +extern bool widget_viewer_evas_is_visibility_frozen(Evas_Object *widget); + +/** + * @brief Validate the object, whether it is a widget object or not + * @since_tizen 2.3.1 + * @param[in] widget a widget object + * @return result of validation and you can get the result state of this function by using get_last_result() + * @retval true this is a widget + * @retval false this is not a widget + */ +extern bool widget_viewer_evas_is_widget(Evas_Object *widget); + +/** + * @brief Before delete a widget, set the deletion mode + * @since_tizen 2.3.1 + * @param[in] widget a widget object which will be deleted soon + * @param[in] flag Pass 1 if you delete this widget instance permanently, or pass 0 if you want to keep it and it will be re-created soon. + */ +extern void widget_viewer_evas_set_permanent_delete(Evas_Object *widget, int flag); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/* End of a file */ diff --git a/widget_viewer_evas/include/widget_viewer_evas_internal.h b/widget_viewer_evas/include/widget_viewer_evas_internal.h new file mode 100644 index 0000000..2e12237 --- /dev/null +++ b/widget_viewer_evas/include/widget_viewer_evas_internal.h @@ -0,0 +1,276 @@ +/* + * Samsung API + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT 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 __WIDGET_VIEWER_EVAS_INTERNAL_H +#define __WIDGET_VIEWER_EVAS_INTERNAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "widget_viewer_evas.h" +#include "widget_service_internal.h" + +#define WIDGET_SMART_SIGNAL_GBAR_DESTROYED "gbar,destroyed" /**< GBAR is destroyed */ +#define WIDGET_SMART_SIGNAL_GBAR_ABORTED "gbar,aborted" /**< GBAR creation is aborted */ +#define WIDGET_SMART_SIGNAL_GBAR_CREATED "gbar,created" /**< GBAR is created */ +#define WIDGET_SMART_SIGNAL_FLICKDOWN_CANCELLED "flickdown,cancelled" /**< Flick down is canceld */ + + +#define WIDGET_VIEWER_EVAS_SHARED_CONTENT 0x0002 /**< Multiple instances will share the content of one real instance */ +#define WIDGET_VIEWER_EVAS_SUPPORT_GBAR 0x0004 /**< GBAR will be used */ + +typedef enum widget_access_result { + WIDGET_ACCESS_RESULT_DONE = 0x00, + WIDGET_ACCESS_RESULT_FIRST = 0x01, + WIDGET_ACCESS_RESULT_LAST = 0x02, + WIDGET_ACCESS_RESULT_READ = 0x04, + WIDGET_ACCESS_RESULT_ERROR = 0x80, + WIDGET_ACCESS_RESULT_UNKNOWN = 0xFF +} widget_access_result_e; + +/** + * @since_tizen 2.3.1 + * @brief event type for evas raw event + */ +typedef enum widget_evas_raw_event_type { + WIDGET_VIEWER_EVAS_RAW_DELETE = 0x00, + WIDGET_VIEWER_EVAS_RAW_CREATE = 0x02, + WIDGET_VIEWER_EVAS_RAW_MAX = 0xff, +} widget_evas_raw_event_type_e; + +/** + * @since_tizen 2.3.1 + * @brief Options for each widget. + */ +typedef enum widget_option_widget_type { + WIDGET_OPTION_WIDGET_DELAYED_RESUME = 0x01, /**< 0: Follow the global configuration, 1: Disable the Delayed Pause Resume, 2: Enable the Delayed Pause Resume */ + WIDGET_OPTION_WIDGET_DISABLE_OVERLAY_ANIMATION = 0x02, /**< 0: Enable overlay animation, 1: Disable overlay animation */ + WIDGET_OPTION_WIDGET_MANUAL_OVERLAY_HIDE = 0x04, /**< 0: Automatically hidden by system, 1: Should be hidden by caller explicitly */ + WIDGET_OPTION_UNKNOWN = 0xFF +} widget_option_widget_e; + +/** + * @since_tizen 2.3.1 + * @brief Data structure for smart callback user parameter + */ +typedef struct widget_evas_raw_event_info { + const char *pkgname; + enum widget_evas_raw_event_type type; + int error; + Evas_Object *widget; +} widget_evas_raw_event_info_s; + +/** + * @brief Close the Glance Bar if it is opened + * @since_tizen 2.3.1 + * @param[in] widget widget object + * @return 0 on success, otherwise a negative error value + */ +extern int widget_viewer_evas_destroy_glance_bar(Evas_Object *widget); + +/** + * @brief Set the viewe port of given widget + * @since_tizen 2.3.1 + * @param[in] widget + * @param[in] x + * @param[in] y + * @param[in] w + * @param[in] h + * @return 0 on success, otherwise a negative error value + */ +extern int widget_viewer_evas_set_view_port(Evas_Object *widget, int x, int y, int w, int h); + +/** + * @brief Get the current view port of given widget + * @since_tizen 2.3.1 + * @param[in] widget + * @param[out] x + * @param[out] y + * @param[out] w + * @param[out] h + * @return 0 on success, otherwise a negative error value + */ +extern int widget_viewer_evas_get_view_port(Evas_Object *widget, int *x, int *y, int *w, int *h); + + +/** + * @brief Feeds accessibility events + * @since_tizen 2.3.1 + * @param[in] widget + * @param[in] type + * @param[in] info + * @param[in] ret_cb + * @param[in] dta + * @return 0 on success, otherwise a negative error value + */ +extern int widget_viewer_evas_feed_access_event(Evas_Object *widget, int type, void *info, void (*ret_cb)(Evas_Object *obj, int ret, void *data), void *data); + +/** + * @brief Dump a contents of widget to a given filename. + * @since_tizen 2.3.1 + * @param[in] widget widget object + * @param[in] filename Filename will be used for saving content of a widget + * @return 0 on success, otherwise a negative error value + */ +extern int widget_viewer_evas_dump_to_file(Evas_Object *widget, const char *filename); + + +/** + * @brief Subscribes an event for widgets only in a given cluster and sub-cluster. + * @details If you wrote a view-only client, + * you can receive the event of specific widgets which belong to a given cluster/category. + * But you cannot modify their attributes (such as size, ...). + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] cluster Cluster ("*" can be used for subscribe all cluster's widgets event; If you use the "*", value in the category will be ignored) + * @param[in] category Category ("*" can be used for subscribe widgets events of all category(sub-cluster) in a given "cluster") + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_ERROR_NONE Successfully requested + * @see widget_viewer_evas_unsubscribe_group() + */ +extern int widget_viewer_evas_subscribe_group(const char *cluster, const char *sub_cluster); + + +/** + * @brief Unsubscribes an event for the widgets, but you will receive already added widgets events. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] cluster Cluster("*" can be used for subscribe all cluster's widgets event; If you use the "*", value in the category will be ignored) + * @param[in] category Category ("*" can be used for subscribe all sub-cluster's widgets event in a given "cluster") + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_ERROR_NONE Successfully requested + * @see widget_subscribe_group() + */ +extern int widget_viewer_evas_unsubscribe_group(const char *cluster, const char *sub_cluster); + +/** + * @brief Subscribes events of widgets which is categorized by given "category" string. + * "category" is written in the XML file of each widget manifest file. + * After subscribe the category, the master will send created event for all created widgets, + * Also it will notify client when a new widget is created. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] category Category name + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_ERROR_NONE Successfully requested + * @see widget_viewer_evas_unsubscribe_category() + */ +extern int widget_viewer_evas_subscribe_category(const char *category); + +/** + * @brief Unsubscribes events of widgets. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] category Category name + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_ERROR_FAULT Unrecoverable error occurred + * @retval #WIDGET_ERROR_NONE Successfully requested + * @see widget_viewer_evas_subscribe_category() + */ +extern int widget_viewer_evas_unsubscribe_category(const char *category); + +/** + * @brief Callback function for handling raw event + * @since_tizen 2.3.1 + * @param[in] info + * @param[in] data + */ +typedef void (*raw_event_cb)(widget_evas_raw_event_info_s *info, void *data); + +/** + * @brief Register a callback function for subscribing raw event. + * @since_tizen 2.3.1 + * @param[in] type + * @param[in] cb + * @param[in] data + */ +extern int widget_viewer_evas_set_raw_event_callback(widget_evas_raw_event_type_e type, raw_event_cb cb, void *data); + +/** + * @brief Unregister a callback function for subscribing raw event. + * @since_tizen 2.3.1 + * @param[in] type + * @param[in] cb + * @param[in] data + * @return 0 on success, otherwise a negative error value + */ +extern int widget_viewer_evas_unset_raw_event_callback(widget_evas_raw_event_type_e type, raw_event_cb cb, void *data); + +extern int widget_viewer_evas_get_instance_id(Evas_Object *widget, char **instance_id); + +extern int widget_viewer_evas_set_widget_option(Evas_Object *widget, widget_option_widget_e option, int value); + +/** + * @brief Emits a text signal to the given widget + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @remarks + * This is an ASYNCHRONOUS API. + * This function is Asynchronous, so you will get the result from @a smart callback, if you failed to send a text signal, + * this function will returns proper error code. + * @param[in] widget a widget object + * @param[in] event_info.signal_name name of text signal + * @param[in] event_info.source source string + * @param[in] event_info.sx Start X + * @param[in] event_info.sy Start Y + * @param[in] event_info.ex End X + * @param[in] event_info.ey End Y + * @return 0 on success, otherwise a negative error value + * @retval #WIDGET_STATUS_ERROR_NONE Successfully emitted + * @retval #WIDGET_STATUS_ERROR_INVALID_PARAMETER Invalid parameters + * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred + * @see #widget_text_signal_s + * @see #WIDGET_TEXT_SIGNAL_NAME_EDIT_MODE_ON + * @see #WIDGET_TEXT_SIGNAL_NAME_EDIT_MODE_OFF + */ +extern int widget_viewer_evas_emit_text_signal(Evas_Object *widget, widget_text_signal_s event_info, void *data); + +/** + * @brief Set the preview image file + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] widget + * @param[in] preview + * @return #WIDGET_ERROR_NONE on success, otherwise a negative error value + */ +extern int widget_viewer_evas_set_preview_image(Evas_Object *widget, widget_size_type_e type, const char *preview); + +/** + * @brief Hide the overlay (preview) immeidiately. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/widget.viewer + * @param[in] widget + * @return #WIDGET_ERROR_NONE on success, otherwise negative error value + */ +extern int widget_viewer_evas_hide_overlay(Evas_Object *widget); + +#ifdef __cplusplus +} +#endif + +#endif /* __WIDGET_VIEWER_EVAS_INTERNAL_H */ diff --git a/widget_viewer_evas/res/CMakeLists.txt b/widget_viewer_evas/res/CMakeLists.txt new file mode 100644 index 0000000..26b87b9 --- /dev/null +++ b/widget_viewer_evas/res/CMakeLists.txt @@ -0,0 +1,13 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# install edj +ADD_CUSTOM_TARGET(widget_viewer_evas.edj + COMMAND edje_cc -id ${CMAKE_CURRENT_SOURCE_DIR}/images ${EDJE_CFLAGS} + ${CMAKE_CURRENT_SOURCE_DIR}/widget_viewer_evas.edc widget_viewer_evas.edj + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/widget_viewer_evas.edc +) +ADD_DEPENDENCIES(${PROJECT_NAME} widget_viewer_evas.edj) +INSTALL(FILES widget_viewer_evas.edj DESTINATION ${EDJDIR}) +INSTALL(FILES unknown.png DESTINATION ${IMGDIR}) + +ADD_SUBDIRECTORY(po) diff --git a/widget_viewer_evas/res/po/CMakeLists.txt b/widget_viewer_evas/res/po/CMakeLists.txt new file mode 100644 index 0000000..685aadd --- /dev/null +++ b/widget_viewer_evas/res/po/CMakeLists.txt @@ -0,0 +1,84 @@ +# for i18n + +SET(POFILES + ar.po + az.po + bg.po + bn.po + ca.po + cs.po + da.po + de.po + el_GR.po + en.po + en_PH.po + en_US.po + es_ES.po + es_US.po + et.po + eu.po + fa.po + fi.po + fr.po + fr_CA.po + ga.po + gl.po + gu.po + he.po + hi.po + hr.po + hu.po + hy.po + is.po + it_IT.po + ja_JP.po + ka.po + kk.po + kn.po + ko_KR.po + lt.po + lv.po + mk.po + ml.po + nb.po + nl.po + pl.po + pt_BR.po + pt_PT.po + ro.po + ru_RU.po + si.po + sk.po + sl.po + sr.po + sv.po + ta.po + te.po + th.po + tr_TR.po + uk.po + ur.po + uz.po + zh_CN.po + zh_HK.po + zh_TW.po +) + +SET(MSGFMT "/usr/bin/msgfmt") +FOREACH(pofile ${POFILES}) + SET(pofile ${CMAKE_CURRENT_SOURCE_DIR}/${pofile}) + MESSAGE(STATUS " ${pofile}") + GET_FILENAME_COMPONENT(absPofile ${pofile} ABSOLUTE) + GET_FILENAME_COMPONENT(lang ${absPofile} NAME_WE) + SET(moFile ${CMAKE_CURRENT_BINARY_DIR}/${lang}.mo) + ADD_CUSTOM_COMMAND( + OUTPUT ${moFile} + COMMAND ${MSGFMT} -o ${moFile} ${absPofile} + DEPENDS ${absPofile} + ) + INSTALL(FILES ${moFile} + DESTINATION ${LOCALEDIR}/${lang}/LC_MESSAGES RENAME ${PROJECT_NAME}.mo) + SET(moFiles ${moFiles} ${moFile}) +ENDFOREACH(pofile) + +ADD_CUSTOM_TARGET(po ALL DEPENDS ${moFiles}) diff --git a/widget_viewer_evas/res/po/ar.po b/widget_viewer_evas/res/po/ar.po new file mode 100644 index 0000000..45cb180 --- /dev/null +++ b/widget_viewer_evas/res/po/ar.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "جاري التحميل ..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "انقر للإنشاء" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "تفعيل" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "تعطيل" + +msgid "IDS_ST_BODY_NEW" +msgstr "جديد" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "إفتراضي" + +msgid "IDS_ST_BODY_MODE" +msgstr "النمط" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "يتم التعطيل..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "تم" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "تعديل" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "إنشاء" + +msgid "IDS_ST_HEADER_HELP" +msgstr "مساعدة" + +msgid "IDS_ST_BODY_RESET" +msgstr "إرجاع" + +msgid "IDS_ST_BODY_SIZE" +msgstr "الحجم" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "إضافة تطبيق مصغر" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "لا توجد مساحة كافية على الشاشة الرئيسية." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "تتعذر إضافة التطبيق المصغر" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "جاري التحميل ..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "يتعذر تحميل البيانات. انقر لإعادة المحاولة." + diff --git a/widget_viewer_evas/res/po/az.po b/widget_viewer_evas/res/po/az.po new file mode 100644 index 0000000..bf15afc --- /dev/null +++ b/widget_viewer_evas/res/po/az.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Yüklənir..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Yaratmaq üçün vur" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Qoş" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Söndür" + +msgid "IDS_ST_BODY_NEW" +msgstr "Yeni" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "İlkin təyin olunan" + +msgid "IDS_ST_BODY_MODE" +msgstr "Rejim" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Qeyri-aktiv edilmə..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Tamam" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Redaktə et" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Yarat" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Yardım" + +msgid "IDS_ST_BODY_RESET" +msgstr "Sıfırlansın" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Ölçü" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Piktoqram əlavə et" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Əsas ekranda kifayət qədər yer yoxdur." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Piktoqram əlavə etmək olmadı" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Yüklənir..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Məlumatları yükləmək mümkün deyil. Yenidən cəhd etmək üçün vurun" + diff --git a/widget_viewer_evas/res/po/bg.po b/widget_viewer_evas/res/po/bg.po new file mode 100644 index 0000000..5205184 --- /dev/null +++ b/widget_viewer_evas/res/po/bg.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Зареждане" + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Чукнете, за да създадете" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Разрешаване" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Забрани" + +msgid "IDS_ST_BODY_NEW" +msgstr "Ново" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "По подразбиране" + +msgid "IDS_ST_BODY_MODE" +msgstr "Режим" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Деактивиране..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Готово" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Редактир." + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Създай" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Помощ" + +msgid "IDS_ST_BODY_RESET" +msgstr "Нyлиране" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Размер" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Добавяне на уиджет" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Няма достатъчно място в началния екран." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Не може да се добави уиджет" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Зареждане" + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Данните не могат да се заредят. Чукнете, за да опитате отново." + diff --git a/widget_viewer_evas/res/po/bn.po b/widget_viewer_evas/res/po/bn.po new file mode 100644 index 0000000..5529b74 --- /dev/null +++ b/widget_viewer_evas/res/po/bn.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "লোড হচ্ছে..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "তৈরি করতে ট্যাপ করুন" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "সক্ষম" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "অক্ষম" + +msgid "IDS_ST_BODY_NEW" +msgstr "নতুন" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "ডিফল্ট" + +msgid "IDS_ST_BODY_MODE" +msgstr "মোড" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "অক্ষম হচ্ছে..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "সম্পন্ন" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "সম্পাদনা করুন" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "তৈরি করুন" + +msgid "IDS_ST_HEADER_HELP" +msgstr "সাহায্য" + +msgid "IDS_ST_BODY_RESET" +msgstr "রিসেট" + +msgid "IDS_ST_BODY_SIZE" +msgstr "আকার" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "উইজেট যোগ করুন" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "হোম স্ক্রিনে পর্যাপ্ত স্থান নেই।" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "উইজেট যোগ করতে অক্ষম" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "লোড হচ্ছে..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "তথ্য লোড করতে অক্ষম৷ পুনরায় চেষ্টা করতে ট্যাপ করুন৷" + diff --git a/widget_viewer_evas/res/po/ca.po b/widget_viewer_evas/res/po/ca.po new file mode 100644 index 0000000..0058983 --- /dev/null +++ b/widget_viewer_evas/res/po/ca.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Carregant..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Toqui per crear" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Activar" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Desactiv" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nova" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Predeterminat" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mode" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Deshabilitant..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Fet" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Editar" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Crea" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Ajuda" + +msgid "IDS_ST_BODY_RESET" +msgstr "Restablir" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Mida" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Afegir widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "No hi ha prou espai a la pantalla d'inici" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "No es pot afegir el widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Carregant..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "No es poden carregar les dades. Toqui per tornar-ho a intentar." + diff --git a/widget_viewer_evas/res/po/cs.po b/widget_viewer_evas/res/po/cs.po new file mode 100644 index 0000000..032edef --- /dev/null +++ b/widget_viewer_evas/res/po/cs.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Nahrávám..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Klepnutím vytvořit" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Povolit" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Vypnout" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nový" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Výchozí" + +msgid "IDS_ST_BODY_MODE" +msgstr "Režim" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Vypínání..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Hot." + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Upravit" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Vytvořit" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Nápověda" + +msgid "IDS_ST_BODY_RESET" +msgstr "Obnovit" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Velikost" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Přidat nástroj" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Nedostatek místa na domovské obrazovce." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Pomůcku nelze přidat" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Nahrávám..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Data nelze načíst. Klepnutím opakujte akci." + diff --git a/widget_viewer_evas/res/po/da.po b/widget_viewer_evas/res/po/da.po new file mode 100644 index 0000000..f34d1ce --- /dev/null +++ b/widget_viewer_evas/res/po/da.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Indlæser data ..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Tryk for at oprette" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Aktivér" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Deaktivér" + +msgid "IDS_ST_BODY_NEW" +msgstr "Ny" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Standard" + +msgid "IDS_ST_BODY_MODE" +msgstr "Tilstand" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Deaktiverer ..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Udført" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Redigér" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Opret" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Hjælp" + +msgid "IDS_ST_BODY_RESET" +msgstr "Nulstil" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Størrelse" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Tilføj widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Ikke nok plads på startskærmen." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Kan ikke tilføje widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Indlæser data ..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Kan ikke indlæse data. Tryk for at prøve igen." + diff --git a/widget_viewer_evas/res/po/de.po b/widget_viewer_evas/res/po/de.po new file mode 100644 index 0000000..0b875be --- /dev/null +++ b/widget_viewer_evas/res/po/de.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Lädt..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Zum Erstellen hier tippen" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Aktivieren" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Deaktivieren" + +msgid "IDS_ST_BODY_NEW" +msgstr "Neu" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Standard" + +msgid "IDS_ST_BODY_MODE" +msgstr "Modus" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Deaktivieren..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Fertig" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Bearbeiten" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Erstellen" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Hilfe" + +msgid "IDS_ST_BODY_RESET" +msgstr "Zurücksetzen" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Größe" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Hinzufügen von Widgets" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Kein ausreichender Platz auf Startbildschirm" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Hinzufügen nicht möglich" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Lädt..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Daten konnten nicht geladen werden. Für erneuten Versuch tippen" + diff --git a/widget_viewer_evas/res/po/el_GR.po b/widget_viewer_evas/res/po/el_GR.po new file mode 100644 index 0000000..6dfde0f --- /dev/null +++ b/widget_viewer_evas/res/po/el_GR.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Φόρτωση..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Πατήστε για δημιουργία" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Ενεργό" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Απενεργ." + +msgid "IDS_ST_BODY_NEW" +msgstr "Νέο" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Προεπιλογή" + +msgid "IDS_ST_BODY_MODE" +msgstr "Λειτουργία" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Απενεργοποίηση..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Τέλος" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Επεξεργ." + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Δημ/ργία" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Βοήθεια" + +msgid "IDS_ST_BODY_RESET" +msgstr "Επαναφορά" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Μέγεθος" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Προσθήκη widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Δεν υπάρχει αρκετός χώρος στην αρχική οθόνη." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Αδύνατη η προσθήκη widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Φόρτωση..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Δεν είναι δυνατή η φόρτωση δεδομένων. Πατήστε για να δοκιμάσετε ξανά." + diff --git a/widget_viewer_evas/res/po/en.po b/widget_viewer_evas/res/po/en.po new file mode 100644 index 0000000..2972ddf --- /dev/null +++ b/widget_viewer_evas/res/po/en.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Loading..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Tap to create" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Enable" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Disable" + +msgid "IDS_ST_BODY_NEW" +msgstr "New" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Default" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mode" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Disabling..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Done" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Edit" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Create" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Help" + +msgid "IDS_ST_BODY_RESET" +msgstr "Reset" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Size" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Add widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Not enough space on the home screen." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Unable to add widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Loading..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Unable to load data. Tap to retry." + diff --git a/widget_viewer_evas/res/po/en_PH.po b/widget_viewer_evas/res/po/en_PH.po new file mode 100644 index 0000000..2972ddf --- /dev/null +++ b/widget_viewer_evas/res/po/en_PH.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Loading..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Tap to create" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Enable" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Disable" + +msgid "IDS_ST_BODY_NEW" +msgstr "New" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Default" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mode" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Disabling..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Done" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Edit" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Create" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Help" + +msgid "IDS_ST_BODY_RESET" +msgstr "Reset" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Size" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Add widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Not enough space on the home screen." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Unable to add widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Loading..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Unable to load data. Tap to retry." + diff --git a/widget_viewer_evas/res/po/en_US.po b/widget_viewer_evas/res/po/en_US.po new file mode 100644 index 0000000..56a0542 --- /dev/null +++ b/widget_viewer_evas/res/po/en_US.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Loading..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Tap to create" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Turn on" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Turn off" + +msgid "IDS_ST_BODY_NEW" +msgstr "Add new" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Default" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mode" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Turning off..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Done" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Edit" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Create" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Help" + +msgid "IDS_ST_BODY_RESET" +msgstr "Reset" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Size" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Add widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Not enough space on the Home screen." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Unable to add widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Loading..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Unable to load data. Tap to retry." + diff --git a/widget_viewer_evas/res/po/es_ES.po b/widget_viewer_evas/res/po/es_ES.po new file mode 100644 index 0000000..c15b424 --- /dev/null +++ b/widget_viewer_evas/res/po/es_ES.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Cargando..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Pulse para crear" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Habilitar" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Desactivar" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nuevo" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Predeterminado" + +msgid "IDS_ST_BODY_MODE" +msgstr "Modo" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Desactivando..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Hecho" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Editar" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Crear" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Ayuda" + +msgid "IDS_ST_BODY_RESET" +msgstr "Restablecer" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Tamaño" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Añadir widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "No hay espacio suficiente en la pantalla de inicio" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "No se puede añadir el widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Cargando..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "No se pueden cargar datos. Pulse para volver a intentarlo." + diff --git a/widget_viewer_evas/res/po/es_US.po b/widget_viewer_evas/res/po/es_US.po new file mode 100644 index 0000000..9f8b672 --- /dev/null +++ b/widget_viewer_evas/res/po/es_US.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Cargando..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Pulse para crear" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Activar" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Desactivar" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nueva" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Predeterminado" + +msgid "IDS_ST_BODY_MODE" +msgstr "Método" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Desactivando..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Aceptar" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Editar" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Crear" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Ayuda" + +msgid "IDS_ST_BODY_RESET" +msgstr "Restablecer" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Tamaño" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Añadir widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "No hay espacio suficiente en la pantalla de inicio." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "No es posible añadir widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Cargando..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "No es posible cargar los datos. Pulse para intentarlo de nuevo." + diff --git a/widget_viewer_evas/res/po/et.po b/widget_viewer_evas/res/po/et.po new file mode 100644 index 0000000..5737dec --- /dev/null +++ b/widget_viewer_evas/res/po/et.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Laadimine..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Toksake loomiseks" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Luba" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Desaktiv." + +msgid "IDS_ST_BODY_NEW" +msgstr "Uus" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Vaikimisi" + +msgid "IDS_ST_BODY_MODE" +msgstr "Režiim" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Desaktiveerimine..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Valmis" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Redigeeri" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Loo" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Spikker" + +msgid "IDS_ST_BODY_RESET" +msgstr "Lähtesta" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Suurus" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Vidina lisamine" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Avaekraanil pole piisavalt ruumi." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Vidinat ei saa lisada" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Laadimine..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Andmeid ei saa laadida. Toksake, et proovida uuesti." + diff --git a/widget_viewer_evas/res/po/eu.po b/widget_viewer_evas/res/po/eu.po new file mode 100644 index 0000000..c1fafcd --- /dev/null +++ b/widget_viewer_evas/res/po/eu.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Kargatzen..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Ukitu sortzeko" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Gaitu" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Ezgaitu" + +msgid "IDS_ST_BODY_NEW" +msgstr "Berria" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Lehenetsia" + +msgid "IDS_ST_BODY_MODE" +msgstr "Modua" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Desgaitzen..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Egina" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Editatu" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Sortu" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Laguntza" + +msgid "IDS_ST_BODY_RESET" +msgstr "Berrezarri" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Tamaina" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Gehitu widgeta" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Ez dago nahikoa espazio pantaila nagusian" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Ezin da widgeta gehitu" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Kargatzen..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Ezin dira datuak kargatu. Ukitu berriz saiatzeko." + diff --git a/widget_viewer_evas/res/po/fa.po b/widget_viewer_evas/res/po/fa.po new file mode 100644 index 0000000..327c76a --- /dev/null +++ b/widget_viewer_evas/res/po/fa.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "در حال دانلود..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "برای ایجاد ضربه بزنید" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "فعال" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "غیر فعال" + +msgid "IDS_ST_BODY_NEW" +msgstr "جديد" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "پيش فرض" + +msgid "IDS_ST_BODY_MODE" +msgstr "حالت" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "در حال غیرفعال‌سازی..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "انجام شد" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "تصحيح" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "ايجاد" + +msgid "IDS_ST_HEADER_HELP" +msgstr "راهنما" + +msgid "IDS_ST_BODY_RESET" +msgstr "تنظیم مجدد" + +msgid "IDS_ST_BODY_SIZE" +msgstr "سايز" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "افزودن ويجت" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "فضای کافی در صفحه اصلی وجود ندارد." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "افزودن ویجت ممکن نیست" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "در حال دانلود..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "بارگیری داده ممکن نیست. برای امتحان مجدد ضربه بزنید." + diff --git a/widget_viewer_evas/res/po/fi.po b/widget_viewer_evas/res/po/fi.po new file mode 100644 index 0000000..fd4870d --- /dev/null +++ b/widget_viewer_evas/res/po/fi.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Ladataan..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Luo napauttamalla" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Päälle" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Ei käyt." + +msgid "IDS_ST_BODY_NEW" +msgstr "Uusi" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Oletus" + +msgid "IDS_ST_BODY_MODE" +msgstr "Tila" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Poistetaan käytöstä..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Valmis" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Muokkaa" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Luo" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Ohje" + +msgid "IDS_ST_BODY_RESET" +msgstr "Nollaa" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Koko" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Lisää pienoisohjelma" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Alkunäytössä ei ole tarpeeksi tilaa." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Pienoisohjelmaa ei voi lisätä" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Ladataan..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Tietoja ei voi ladata. Yritä napauttamalla uudelleen." + diff --git a/widget_viewer_evas/res/po/fr.po b/widget_viewer_evas/res/po/fr.po new file mode 100644 index 0000000..42910bd --- /dev/null +++ b/widget_viewer_evas/res/po/fr.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Chargement en cours." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Appuyez pour créer" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Activer" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Désactiv." + +msgid "IDS_ST_BODY_NEW" +msgstr "Nouveau" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Par défaut" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mode" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Désactivation..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "OK" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Modifier" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Créer" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Aide" + +msgid "IDS_ST_BODY_RESET" +msgstr "Réinitialiser" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Taille" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Ajouter un widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Espace insuffisant sur l'écran d'accueil" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Impossible d'ajouter le widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Chargement en cours." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Impossible de charger les données. Appuyez pour réessayer." + diff --git a/widget_viewer_evas/res/po/fr_CA.po b/widget_viewer_evas/res/po/fr_CA.po new file mode 100644 index 0000000..ca0356c --- /dev/null +++ b/widget_viewer_evas/res/po/fr_CA.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Chargement..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Touchez pour créer" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Activer" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Désactiver" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nouveau" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Par défaut" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mode" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Désactivation..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "OK" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Modifier" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Créer" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Aide" + +msgid "IDS_ST_BODY_RESET" +msgstr "Réinitialiser" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Taille" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Ajouter un widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Espace insuffisant sur l'écran d'accueil." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Impossible d'ajouter le widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Chargement..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Impossible de charger les données. Appuyez pour réessayer." + diff --git a/widget_viewer_evas/res/po/ga.po b/widget_viewer_evas/res/po/ga.po new file mode 100644 index 0000000..5f55c12 --- /dev/null +++ b/widget_viewer_evas/res/po/ga.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Ag lódáil..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Tapáil le cruthú" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Cumasaigh" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Díchumasú" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nua" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Réamhshocrú" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mód" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Á dhíchumasú..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Déanta" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "In eagar" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Cruthaigh" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Cuidiú" + +msgid "IDS_ST_BODY_RESET" +msgstr "Athshocraigh" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Méid" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Cuir giuirléid leis" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Níl go leor spáis ar an scáileán baile." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Ní féid. giuirléid a chur leis" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Ag lódáil..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Ní féidir sonraí a choinneáil. Tapáil le triail arís." + diff --git a/widget_viewer_evas/res/po/gl.po b/widget_viewer_evas/res/po/gl.po new file mode 100644 index 0000000..1311897 --- /dev/null +++ b/widget_viewer_evas/res/po/gl.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Cargando..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Toca para crear" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Activar" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Desactivar" + +msgid "IDS_ST_BODY_NEW" +msgstr "Novo" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Predeterminada" + +msgid "IDS_ST_BODY_MODE" +msgstr "Modo" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Desactivando..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Feito" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Editar" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Crear" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Axuda" + +msgid "IDS_ST_BODY_RESET" +msgstr "Restablecer" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Tamaño" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Engadir widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Non hai espazo suficiente na pantalla de inicio" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Non se pode engadir o widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Cargando..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Non se poden cargar datos. Toca para tentalo de novo." + diff --git a/widget_viewer_evas/res/po/gu.po b/widget_viewer_evas/res/po/gu.po new file mode 100644 index 0000000..406af58 --- /dev/null +++ b/widget_viewer_evas/res/po/gu.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "લોડિંગ..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "બનાવવા માટે ટેપ કરો" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "સક્ષમ કરો" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "અક્ષમ કરો" + +msgid "IDS_ST_BODY_NEW" +msgstr "નવું" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "મૂળભૂત" + +msgid "IDS_ST_BODY_MODE" +msgstr "મોડ" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "અક્ષમ કરી રહ્યું છે..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "પૂર્ણ" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "ફેરફાર કરો" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "બનાવો" + +msgid "IDS_ST_HEADER_HELP" +msgstr "મદદ" + +msgid "IDS_ST_BODY_RESET" +msgstr "રીસેટ કરો" + +msgid "IDS_ST_BODY_SIZE" +msgstr "કદ" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "વિજેટ ઉમેરો" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "હોમ સ્ક્રીન પર પૂરતી જગ્યા નથી." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "વિજેટ ઉમેરવામાં અસમર્થ" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "લોડિંગ..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "ડેટા લોડ કરવામાં અસમર્થ. ફરીથી પ્રયાસ કરવા માટે ટેપ કરો." + diff --git a/widget_viewer_evas/res/po/he.po b/widget_viewer_evas/res/po/he.po new file mode 100644 index 0000000..c87e1f2 --- /dev/null +++ b/widget_viewer_evas/res/po/he.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "טוען..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "הקש כדי ליצור" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "הפעל" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "השבת" + +msgid "IDS_ST_BODY_NEW" +msgstr "חדש" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "ברירת מחדל" + +msgid "IDS_ST_BODY_MODE" +msgstr "מצב GPS" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "משבית..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "סיום" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "ערוך" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "צור" + +msgid "IDS_ST_HEADER_HELP" +msgstr "עזרה" + +msgid "IDS_ST_BODY_RESET" +msgstr "איפוס" + +msgid "IDS_ST_BODY_SIZE" +msgstr "גודל" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "הוספת יישומון" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "אין די מקום במסך הבית." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "לא ניתן להוסיף יישומון" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "טוען..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "לא ניתן לטעון נתונים. הקש כדי לנסות שנית." + diff --git a/widget_viewer_evas/res/po/hi.po b/widget_viewer_evas/res/po/hi.po new file mode 100644 index 0000000..68ab8f8 --- /dev/null +++ b/widget_viewer_evas/res/po/hi.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "लोड हो रहा है..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "बनाने के लिए टैप करें" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "सक्षम" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "अक्षम करें" + +msgid "IDS_ST_BODY_NEW" +msgstr "नया" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "डिफॉल्ट" + +msgid "IDS_ST_BODY_MODE" +msgstr "मोड" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "अक्षम हो रहा है..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "पूर्ण" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "संपादन" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "बनाएँ" + +msgid "IDS_ST_HEADER_HELP" +msgstr "सहायता" + +msgid "IDS_ST_BODY_RESET" +msgstr "रीसेट" + +msgid "IDS_ST_BODY_SIZE" +msgstr "आकार" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "विजेट जोड़ें" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "होम स्क्रीन पर पर्याप्त स्थान नहीं है।" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "विजेट जोड़ने में असमर्थ" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "लोड हो रहा है..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "डाटा लोड करने में अक्षम। फिर से प्रयास करने हेतु टैप करें।" + diff --git a/widget_viewer_evas/res/po/hr.po b/widget_viewer_evas/res/po/hr.po new file mode 100644 index 0000000..b90f00e --- /dev/null +++ b/widget_viewer_evas/res/po/hr.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Učitavanje..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Pritisni za novi" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Uključi" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Isključi" + +msgid "IDS_ST_BODY_NEW" +msgstr "Novi" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Zadano" + +msgid "IDS_ST_BODY_MODE" +msgstr "Način" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Isključivanje..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "OK" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Uredi" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Novi" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Upute" + +msgid "IDS_ST_BODY_RESET" +msgstr "Poništavanje" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Veličina" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Dodavanje widgeta" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Nedovoljno prostora na početnom zaslonu." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Nije moguće dodati widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Učitavanje..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Nije moguće učitati podatke. Dodirnite radi ponavljanja." + diff --git a/widget_viewer_evas/res/po/hu.po b/widget_viewer_evas/res/po/hu.po new file mode 100644 index 0000000..6c47578 --- /dev/null +++ b/widget_viewer_evas/res/po/hu.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Betöltés..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Ér. meg a létrehozáshoz" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Engedélyezés" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Kikapcsol" + +msgid "IDS_ST_BODY_NEW" +msgstr "Új" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Alapértelmezett" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mód" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Letiltás..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Kész" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Szerk." + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Létrehoz" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Súgó" + +msgid "IDS_ST_BODY_RESET" +msgstr "Visszaállítás" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Méret" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Widget hozzáadása" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Nincs elég hely a kezdőképernyőn." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Nem adható hozzá a widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Betöltés..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Nem lehet betölteni az adatokat. Érintse meg az újabb próbálkozáshoz." + diff --git a/widget_viewer_evas/res/po/hy.po b/widget_viewer_evas/res/po/hy.po new file mode 100644 index 0000000..50b7266 --- /dev/null +++ b/widget_viewer_evas/res/po/hy.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Բեռնում է..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Թակել ստեղծելու համար" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Ակտիվացնլ" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Կասեցնել" + +msgid "IDS_ST_BODY_NEW" +msgstr "Նոր" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Լռելյայն" + +msgid "IDS_ST_BODY_MODE" +msgstr "Ռեժիմ" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Կասեցվում է..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Արված է" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Խմբագրել" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Ստեղծել" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Օգնություն" + +msgid "IDS_ST_BODY_RESET" +msgstr "Զրոյացնել" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Չափս" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Ավելացնել պատկերագիր" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Հիմնական էկրանի վրա բավարար տեղ չկա:" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Անհնար է ավելացնել պատկերագիր" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Բեռնում է..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Անհնար է տվյալներ բեռնել: Թակեք՝ նորից փորձելու համար" + diff --git a/widget_viewer_evas/res/po/is.po b/widget_viewer_evas/res/po/is.po new file mode 100644 index 0000000..4ac284e --- /dev/null +++ b/widget_viewer_evas/res/po/is.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Hleð..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Pikkaðu til að búa til" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Gera virkt" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Slökkva" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nýtt" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Sjálfgefið" + +msgid "IDS_ST_BODY_MODE" +msgstr "Stilling" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Slekk..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Lokið" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Breyta" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Búa til" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Hjálp" + +msgid "IDS_ST_BODY_RESET" +msgstr "Endurstilla" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Stærð" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Bæta við græju" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Of lítið pláss á heimaskjánum." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Ekki er hægt að bæta við græju" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Hleð..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Ekki tókst að hlaða gögn. Pikkaðu til að reyna aftur." + diff --git a/widget_viewer_evas/res/po/it_IT.po b/widget_viewer_evas/res/po/it_IT.po new file mode 100644 index 0000000..0b14cae --- /dev/null +++ b/widget_viewer_evas/res/po/it_IT.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Caricamento..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Toccate per creare" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Attiva" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Disattiva" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nuovo" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Predefinito" + +msgid "IDS_ST_BODY_MODE" +msgstr "Modalità" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Disattivazione in corso..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Fatto" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Modif." + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Crea" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Guida" + +msgid "IDS_ST_BODY_RESET" +msgstr "Ripristina" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Dimensioni" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Aggiungi widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Spazio insufficiente sulla schermata iniziale." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Impossibile aggiungere widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Caricamento..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Impossibile caricare i dati. Toccate per riprovare." + diff --git a/widget_viewer_evas/res/po/ja_JP.po b/widget_viewer_evas/res/po/ja_JP.po new file mode 100644 index 0000000..0bb5388 --- /dev/null +++ b/widget_viewer_evas/res/po/ja_JP.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "読み込み中..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "作成" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "有効" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "無効" + +msgid "IDS_ST_BODY_NEW" +msgstr "新規" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "標準" + +msgid "IDS_ST_BODY_MODE" +msgstr "モード" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "無効にしています..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "完了" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "編集" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "作成" + +msgid "IDS_ST_HEADER_HELP" +msgstr "ヘルプ" + +msgid "IDS_ST_BODY_RESET" +msgstr "リセット" + +msgid "IDS_ST_BODY_SIZE" +msgstr "サイズ" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "ウィジェットを追加" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "ホーム画面に十分なスペースがありません。" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "ウィジェットの追加不可" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "読み込み中..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "データをロードできません。タップして再度実行してください。" + diff --git a/widget_viewer_evas/res/po/ka.po b/widget_viewer_evas/res/po/ka.po new file mode 100644 index 0000000..a24425d --- /dev/null +++ b/widget_viewer_evas/res/po/ka.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "იტვირთება..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "დააკაკუნეთ და შეიქმნება" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "ჩართვა" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "გამორთვა" + +msgid "IDS_ST_BODY_NEW" +msgstr "ახალი" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "ნაგულისხმევი" + +msgid "IDS_ST_BODY_MODE" +msgstr "რეჟიმი" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "ითიშება..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "შესრულდა" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "შესწორება" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "შექმნა" + +msgid "IDS_ST_HEADER_HELP" +msgstr "დახმარება" + +msgid "IDS_ST_BODY_RESET" +msgstr "გადატვირთვა" + +msgid "IDS_ST_BODY_SIZE" +msgstr "ზომა" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "ვიჯეტის დამატება" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "საწყის ეკრანზე არ არის საკმარისი ადგილი." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "ვიჯეტის დამატება შეუძლებელია" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "იტვირთება..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "მონაცემთა ჩატვირთვა შეუძლებელია. შეეხეთ და გაიმეორეთ მცდელობა" + diff --git a/widget_viewer_evas/res/po/kk.po b/widget_viewer_evas/res/po/kk.po new file mode 100644 index 0000000..16445f2 --- /dev/null +++ b/widget_viewer_evas/res/po/kk.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Жазылуда..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Жасау үшін түртіңіз" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Қосу" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Өшіру" + +msgid "IDS_ST_BODY_NEW" +msgstr "Жаңа" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Өздігінен" + +msgid "IDS_ST_BODY_MODE" +msgstr "Артқы камера" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Өшірілуде..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Дайын" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Өзгерту" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Құру" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Көмек" + +msgid "IDS_ST_BODY_RESET" +msgstr "Алып тастау" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Өлшемі" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Виджет қосу" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Бастапқы экранда бос орын жеткіліксіз." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Виджет қосу мүмкін емес" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Жазылуда..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Деректерді жүктеу мүмкін емес. Қайталау үшін түртіңіз" + diff --git a/widget_viewer_evas/res/po/kn.po b/widget_viewer_evas/res/po/kn.po new file mode 100644 index 0000000..837a8c0 --- /dev/null +++ b/widget_viewer_evas/res/po/kn.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "ಲೋಡಿಂಗ್..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "ರಚಿಸಲು ತಟ್ಟಿ" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "ಶಕ್ತಗೊಳಿಸು" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "ನಿಶಕ್ತ" + +msgid "IDS_ST_BODY_NEW" +msgstr "ಹೊಸ" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "ಡಿಫಾಲ್ಟ್" + +msgid "IDS_ST_BODY_MODE" +msgstr "ಮೊಡ್" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "ನಿಶಕ್ತಗೊಳಿಸಲಾಗುತ್ತಿದೆ..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "ಮಾಡಿದೆ" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "ಸಂಪಾದಿಸು" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "ರಚಿಸಿರಿ" + +msgid "IDS_ST_HEADER_HELP" +msgstr "ಸಹಾಯ" + +msgid "IDS_ST_BODY_RESET" +msgstr "ಮರುಹೊಂದಿಸು" + +msgid "IDS_ST_BODY_SIZE" +msgstr "ಗಾತ್ರ" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "ವಿಜೆಟ್ ಸೇರಿಸಿ" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ಸಾಕಷ್ಟು ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "ವಿಜೆಟ್ ಸೇರಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "ಲೋಡಿಂಗ್..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "ಡೇಟಾ ಲೋಡ್ ಮಾಡಲು ಅಸಮರ್ಥ. ಮರುಪ್ರಯತ್ನಿಸಲು ಒತ್ತಿ." + diff --git a/widget_viewer_evas/res/po/ko_KR.po b/widget_viewer_evas/res/po/ko_KR.po new file mode 100644 index 0000000..4d12d80 --- /dev/null +++ b/widget_viewer_evas/res/po/ko_KR.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "불러오는 중..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "새 진동패턴 추가" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "실행" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "해제" + +msgid "IDS_ST_BODY_NEW" +msgstr "추가" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "기본" + +msgid "IDS_ST_BODY_MODE" +msgstr "모드" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "해제 중..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "완료" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "편집" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "추가" + +msgid "IDS_ST_HEADER_HELP" +msgstr "도움말" + +msgid "IDS_ST_BODY_RESET" +msgstr "초기화" + +msgid "IDS_ST_BODY_SIZE" +msgstr "크기" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "위젯 추가" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "홈 화면에 빈 공간이 없습니다." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "위젯을 추가할 수 없음" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "불러오는 중..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "데이터를 불러올 수 없습니다. 다시 시도하려면 누르세요." + diff --git a/widget_viewer_evas/res/po/lt.po b/widget_viewer_evas/res/po/lt.po new file mode 100644 index 0000000..d4a36da --- /dev/null +++ b/widget_viewer_evas/res/po/lt.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Įkeliama..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Bakstelėkite ir sukurkite" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Įjungti" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Išjungti" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nauja" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Numatytoji" + +msgid "IDS_ST_BODY_MODE" +msgstr "Režimas" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Išjungiama..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Atlikta" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Redaguoti" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Kurti" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Pagalba" + +msgid "IDS_ST_BODY_RESET" +msgstr "Atstatyti" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Dydis" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Pridėti valdiklį" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Nepakanka vietos pradžios ekrane." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Neįmanoma pridėti valdiklio" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Įkeliama..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Neįmanoma įkelti duomenų. Bakstelėkite ir bandykite dar kartą." + diff --git a/widget_viewer_evas/res/po/lv.po b/widget_viewer_evas/res/po/lv.po new file mode 100644 index 0000000..e0b551f --- /dev/null +++ b/widget_viewer_evas/res/po/lv.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Ielādē..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Pieskar., lai izveidotu" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Aktivizēt" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Deaktiviz." + +msgid "IDS_ST_BODY_NEW" +msgstr "Jaunāks" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Noklusējums" + +msgid "IDS_ST_BODY_MODE" +msgstr "Režīms" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Deaktivizē..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Gatavs" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Rediģēt" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Izveidot" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Palīdzība" + +msgid "IDS_ST_BODY_RESET" +msgstr "Atiestatīt" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Lielums" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Pievienot logrīku" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Sākuma ekrānā nepietiek vietas." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Nevar pievienot logrīku" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Ielādē..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Nevar ielādēt datus. Pieskarieties, lai mēģinātu vēlreiz." + diff --git a/widget_viewer_evas/res/po/mk.po b/widget_viewer_evas/res/po/mk.po new file mode 100644 index 0000000..038feef --- /dev/null +++ b/widget_viewer_evas/res/po/mk.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Активирање..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Допрете за нова" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Вклучи" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Исклучи" + +msgid "IDS_ST_BODY_NEW" +msgstr "Нова" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Основно" + +msgid "IDS_ST_BODY_MODE" +msgstr "Режим" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Се исклучува..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Готово" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Измени" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Ново" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Помош" + +msgid "IDS_ST_BODY_RESET" +msgstr "Ресетирај" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Големина" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Додај виџет" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Нема доволно место на почетниот екран." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Не може да се додаде виџет" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Активирање..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Не можат да се вчитаат податоци. Допрете за повторен обид." + diff --git a/widget_viewer_evas/res/po/ml.po b/widget_viewer_evas/res/po/ml.po new file mode 100644 index 0000000..087b5e5 --- /dev/null +++ b/widget_viewer_evas/res/po/ml.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "ലോഡ്‌ ചെയ്യുന്നു..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "സൃഷ്ടിക്കുക" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "പ്രാപ്‌തം" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "നിഷ്ക്രിയമാക്കുക" + +msgid "IDS_ST_BODY_NEW" +msgstr "പുതിയ" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "സ്ഥിരസ്ഥിതി" + +msgid "IDS_ST_BODY_MODE" +msgstr "രീതി" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "അപ്രാപ്തമാക്കുന്നു..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "ചെയ്തു" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "എഡിറ്റുചെ" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "സൃഷ്‌ടിക്കുക" + +msgid "IDS_ST_HEADER_HELP" +msgstr "സഹായം" + +msgid "IDS_ST_BODY_RESET" +msgstr "പുനഃസജ്ജമാക്കുക" + +msgid "IDS_ST_BODY_SIZE" +msgstr "വലുപ്പം" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "വിജറ്റ് ചേർ‌ക്കുക" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "ഹോം സ്ക്രീനില്‍ ആവശ്യമായ സ്ഥലമില്ല." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "വിജറ്റ് ചേര്‍‌ക്കാനാവില്ല" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "ലോഡ്‌ ചെയ്യുന്നു..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "ഡാറ്റ ലോഡുചെയ്യാന്‍ കഴിയുന്നില്ല. വീണ്ടും ശ്രമിക്കുന്നതിന് ടാപ്പുചെയ്യുക" + diff --git a/widget_viewer_evas/res/po/nb.po b/widget_viewer_evas/res/po/nb.po new file mode 100644 index 0000000..d471533 --- /dev/null +++ b/widget_viewer_evas/res/po/nb.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Åpner..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Trykk for å opprette" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Aktiver" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Deaktiver" + +msgid "IDS_ST_BODY_NEW" +msgstr "Ny" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Standard" + +msgid "IDS_ST_BODY_MODE" +msgstr "Modus" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Deaktiverer..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "OK" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Rediger" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Opprett" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Hjelp" + +msgid "IDS_ST_BODY_RESET" +msgstr "Nullstill" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Størrelse" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Legg til widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Ikke nok plass på dette startskjermbildet." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Kan ikke legge til widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Åpner..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Kan ikke laste data. Trykk for å prøve på nytt." + diff --git a/widget_viewer_evas/res/po/nl.po b/widget_viewer_evas/res/po/nl.po new file mode 100644 index 0000000..832a9f6 --- /dev/null +++ b/widget_viewer_evas/res/po/nl.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Laden..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Tik om te maken" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Aanzetten" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Uitzetten" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nieuw" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Standaard" + +msgid "IDS_ST_BODY_MODE" +msgstr "Stand" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Uitschakelen..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Gereed" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Bewerken" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Nieuw" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Help" + +msgid "IDS_ST_BODY_RESET" +msgstr "Resetten" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Grootte" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Widget toevoegen" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Niet genoeg ruimte op het startscherm." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Kan widget niet toevoegen" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Laden..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Kan gegevens niet laden. Tik om opnieuw te proberen." + diff --git a/widget_viewer_evas/res/po/pl.po b/widget_viewer_evas/res/po/pl.po new file mode 100644 index 0000000..458c9f3 --- /dev/null +++ b/widget_viewer_evas/res/po/pl.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Ładuję..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Dotknij, aby utworzyć" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Włącz" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Wyłącz" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nowe" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Domyślnie" + +msgid "IDS_ST_BODY_MODE" +msgstr "Tryb" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Wyłączanie..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Gotowe" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Edytuj" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Utwórz" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Pomoc" + +msgid "IDS_ST_BODY_RESET" +msgstr "Wyzeruj" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Rozmiar" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Dodawanie widgetu" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Brak miejsca na ekranie głównym." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Nie można dodać widgetu" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Ładuję..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Nie można załadować danych. Dotknij, aby spróbować ponownie." + diff --git a/widget_viewer_evas/res/po/pt_BR.po b/widget_viewer_evas/res/po/pt_BR.po new file mode 100644 index 0000000..fa08643 --- /dev/null +++ b/widget_viewer_evas/res/po/pt_BR.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Carregando..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Toque para criar" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Ativar" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Desativar" + +msgid "IDS_ST_BODY_NEW" +msgstr "Novo" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Padrão" + +msgid "IDS_ST_BODY_MODE" +msgstr "Modo" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Desativando..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "OK" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Editar" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Criar" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Ajuda" + +msgid "IDS_ST_BODY_RESET" +msgstr "Zerar" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Tamanho" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Adicionar widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Sem espaço suficiente na tela de início." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Impossível adicionar widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Carregando..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Não é possível carregar os dados. Toque para tentar novamente." + diff --git a/widget_viewer_evas/res/po/pt_PT.po b/widget_viewer_evas/res/po/pt_PT.po new file mode 100644 index 0000000..99b1e50 --- /dev/null +++ b/widget_viewer_evas/res/po/pt_PT.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "A carregar..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Tocar para criar" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Activar" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Desactivar" + +msgid "IDS_ST_BODY_NEW" +msgstr "Novo" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Padrão" + +msgid "IDS_ST_BODY_MODE" +msgstr "Modo" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "A desactivar..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Concluir" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Editar" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Criar" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Ajuda" + +msgid "IDS_ST_BODY_RESET" +msgstr "Repor" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Tamanho" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Adicionar widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Espaço insuficiente no ecrã principal." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Impossível adicionar widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "A carregar..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Impossível carregar dados. Toque para tentar novamente." + diff --git a/widget_viewer_evas/res/po/ro.po b/widget_viewer_evas/res/po/ro.po new file mode 100644 index 0000000..b5e4634 --- /dev/null +++ b/widget_viewer_evas/res/po/ro.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Încărcare..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Atingeţi pentru a crea" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Activare" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Dezactiv." + +msgid "IDS_ST_BODY_NEW" +msgstr "Nou" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Implicit" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mod" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Se dezactivează..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Efectuat" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Editare" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Creare" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Ajutor" + +msgid "IDS_ST_BODY_RESET" +msgstr "Reiniţializare" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Dimensiune" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Adăugare widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Spaţiu insuficient în ecranul de pornire" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Widgetul nu poate fi adăugat" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Încărcare..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Datele nu pot fi încărcate. Atingeţi pentru a reîncerca." + diff --git a/widget_viewer_evas/res/po/ru_RU.po b/widget_viewer_evas/res/po/ru_RU.po new file mode 100644 index 0000000..d7bad09 --- /dev/null +++ b/widget_viewer_evas/res/po/ru_RU.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Загрузка..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Нажмите для создания" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Включить" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Выключить" + +msgid "IDS_ST_BODY_NEW" +msgstr "Создать" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "По умолчанию" + +msgid "IDS_ST_BODY_MODE" +msgstr "Режим" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Отключение..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Готово" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Изменить" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Создать" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Справка" + +msgid "IDS_ST_BODY_RESET" +msgstr "Сброс" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Размер" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Добавить виджет" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Недостаточно места на главном экране." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Не удалось добавить виджет" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Загрузка..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Не удалось загрузить данные. Коснитесь для повтора" + diff --git a/widget_viewer_evas/res/po/si.po b/widget_viewer_evas/res/po/si.po new file mode 100644 index 0000000..53d79ff --- /dev/null +++ b/widget_viewer_evas/res/po/si.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "ප්‍රෙව්ශනය කරමින්..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "සෑදීමට තට්ටු කරන්න" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "සක්‍රිය ක." + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "අක්‍රිය ක." + +msgid "IDS_ST_BODY_NEW" +msgstr "නව" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "පෙරනිමිය" + +msgid "IDS_ST_BODY_MODE" +msgstr "ප්‍රකාරය" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "අබල කෙරෙමින්..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "නිමයි" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "සංස්කරණය ක." + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "සාදන්න" + +msgid "IDS_ST_HEADER_HELP" +msgstr "සහාය" + +msgid "IDS_ST_BODY_RESET" +msgstr "නැවත සකසන්න" + +msgid "IDS_ST_BODY_SIZE" +msgstr "ප්‍රමාණය" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "විජෙට්ටුව එක් කිරීම" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "මුල් තිරයේ ප්‍රමාණවත් ඉඩක් නොමැත." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "විජෙට්ටුව එක් කළ නොහැක" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "ප්‍රෙව්ශනය කරමින්..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "දත්ත ප්‍රවේශනය කිරීමට නොහැකිය. යළි උත්සාහ කිරීමට තට්ටු කරන්න" + diff --git a/widget_viewer_evas/res/po/sk.po b/widget_viewer_evas/res/po/sk.po new file mode 100644 index 0000000..b38d01a --- /dev/null +++ b/widget_viewer_evas/res/po/sk.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Načítava sa..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Ťuknutím môžete vytvoriť" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Povoliť" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Vypnúť" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nová" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Predvolený" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mód" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Vypína sa..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Hotovo" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Upraviť" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Vytvoriť" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Pomocník" + +msgid "IDS_ST_BODY_RESET" +msgstr "Vynulovať" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Veľkosť" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Pridanie miniaplikácie" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Nedostatok miesta na domovskej obrazovke." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Miniaplikácia sa nedá pridať" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Načítava sa..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Nemožno načítať údaje. Ťuknutím to môžete skúsiť znova." + diff --git a/widget_viewer_evas/res/po/sl.po b/widget_viewer_evas/res/po/sl.po new file mode 100644 index 0000000..7757f15 --- /dev/null +++ b/widget_viewer_evas/res/po/sl.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Nalaganje..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Pritisnite, da ustvarite" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Omogoči" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Onemogoči" + +msgid "IDS_ST_BODY_NEW" +msgstr "Novo" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Privzeto" + +msgid "IDS_ST_BODY_MODE" +msgstr "Način" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Onemogočanje ..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Končano" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Urejanje" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Ustvari" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Pomoč" + +msgid "IDS_ST_BODY_RESET" +msgstr "Ponastavi" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Velikost" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Dodajanje pripomočka" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Na domačen zaslonu ni dovolj prostora." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Pripomočka ni mogoče dodati" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Nalaganje..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Podatkov ni mogoče naložiti. Pritisnite, da poskusite znova." + diff --git a/widget_viewer_evas/res/po/sr.po b/widget_viewer_evas/res/po/sr.po new file mode 100644 index 0000000..cbfc951 --- /dev/null +++ b/widget_viewer_evas/res/po/sr.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Učitavanje..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Kucni za kreiranje" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Omogući" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Onemogući" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nova" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Podrazumevano" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mod" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Onemogućavanje..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Gotovo" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Izmeni" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Kreiraj" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Pomoć" + +msgid "IDS_ST_BODY_RESET" +msgstr "Resetuj" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Veličina" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Dodaj widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Nema dovoljno prostora na početnom ekranu." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Nije moguće dodati widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Učitavanje..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Učitavanje podataka nije moguće. Kucni za ponovni pokušaj." + diff --git a/widget_viewer_evas/res/po/sv.po b/widget_viewer_evas/res/po/sv.po new file mode 100644 index 0000000..00020c1 --- /dev/null +++ b/widget_viewer_evas/res/po/sv.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Laddar..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Tryck för att skapa" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Aktivera" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Inaktivera" + +msgid "IDS_ST_BODY_NEW" +msgstr "Nytt" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Standard" + +msgid "IDS_ST_BODY_MODE" +msgstr "Läge" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Inaktiverar ..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Klar" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Redigera" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Skapa" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Hjälp" + +msgid "IDS_ST_BODY_RESET" +msgstr "Återställ" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Storlek" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Lägg till widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Det finns inte tillräckligt med utrymme på hemskärmen." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Widgeten lades inte till" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Laddar..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Det går inte att läsa in data. Tryck om du vill försöka igen." + diff --git a/widget_viewer_evas/res/po/ta.po b/widget_viewer_evas/res/po/ta.po new file mode 100644 index 0000000..5e67f8f --- /dev/null +++ b/widget_viewer_evas/res/po/ta.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "லோடிங்..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "உருவாக்க டேப் செய்க" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "செயல்படுத்துக" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "செயல்நீக்கு" + +msgid "IDS_ST_BODY_NEW" +msgstr "புதிய" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "டீஃபால்ட்" + +msgid "IDS_ST_BODY_MODE" +msgstr "முறை" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "செயல்நீக்குகிறது..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "முடிந்தது" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "திருத்துக" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "உருவாக்குக" + +msgid "IDS_ST_HEADER_HELP" +msgstr "உதவி" + +msgid "IDS_ST_BODY_RESET" +msgstr "ரீசெட்" + +msgid "IDS_ST_BODY_SIZE" +msgstr "அளவு" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "விட்ஜெட்டைச் சேர்க்கவும்" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "முகப்புத் திரையில் போதுமான இடம் இல்லை." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "விட்ஜெட்டைச் சேர்க்க இயலவில்லை" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "லோடிங்..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "தரவை ஏற்ற இயலவில்லை. மீண்டும் முயலவென டேப் செய்க." + diff --git a/widget_viewer_evas/res/po/te.po b/widget_viewer_evas/res/po/te.po new file mode 100644 index 0000000..4ab0f2f --- /dev/null +++ b/widget_viewer_evas/res/po/te.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "లోడ్ అవుతోంది..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "సృష్టించడానికి ట్యాప్" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "ఎనేబుల్ చేయి" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "నిలిపివేయి" + +msgid "IDS_ST_BODY_NEW" +msgstr "కొత్త" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "డీఫాల్ట్" + +msgid "IDS_ST_BODY_MODE" +msgstr "మోడ్" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "నిలిపివేస్తోంది..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "పూర్తి" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "సవరించు" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "రూపొందించు" + +msgid "IDS_ST_HEADER_HELP" +msgstr "సహాయం" + +msgid "IDS_ST_BODY_RESET" +msgstr "రీసెట్" + +msgid "IDS_ST_BODY_SIZE" +msgstr "పరిమాణం" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "విడ్జెట్‌ను జోడించండి" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "హోమ్ స్క్రీన్‌లో తగినంత ఖాళీ లేదు." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "విడ్జెట్‌ను జోడించడం సాధ్యం కాదు" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "లోడ్ అవుతోంది..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "డేటాను లోడ్ చేయడం సాధ్యం కాదు. మళ్లీ ప్రయత్నించడానికి ట్యాప్ చేయండి." + diff --git a/widget_viewer_evas/res/po/th.po b/widget_viewer_evas/res/po/th.po new file mode 100644 index 0000000..14d217a --- /dev/null +++ b/widget_viewer_evas/res/po/th.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "โหลด..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "สัมผัส​เพื่อ​สร้าง" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "เปิดใช้งาน" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "ปิด​ใช้​งาน" + +msgid "IDS_ST_BODY_NEW" +msgstr "ใหม่" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "พื้นฐาน" + +msgid "IDS_ST_BODY_MODE" +msgstr "โหมด" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "กำลังปิดใช้งาน..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "เรียบร้อย" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "แก้ไข" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "สร้าง" + +msgid "IDS_ST_HEADER_HELP" +msgstr "วิธี​ใช้" + +msgid "IDS_ST_BODY_RESET" +msgstr "รีเซ็ท" + +msgid "IDS_ST_BODY_SIZE" +msgstr "ขนาด" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "เพิ่ม Widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "ที่ว่างบนหน้าจอหลักไม่พอ" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "ไม่สามารถเพิ่ม Widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "โหลด..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "ไม่สามารถโหลดข้อมูลได้ สัมผัสเพื่อลองอีกครั้ง" + diff --git a/widget_viewer_evas/res/po/tr_TR.po b/widget_viewer_evas/res/po/tr_TR.po new file mode 100644 index 0000000..66dbead --- /dev/null +++ b/widget_viewer_evas/res/po/tr_TR.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Yükleniyor..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Oluşturmak için dokunun" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Etkinleştir" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Devre dışı" + +msgid "IDS_ST_BODY_NEW" +msgstr "Yeni" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Varsayılan" + +msgid "IDS_ST_BODY_MODE" +msgstr "Mod" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Devre dışı bırakılıyor..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Tamam" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Düzenle" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Oluştur" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Yardım" + +msgid "IDS_ST_BODY_RESET" +msgstr "Sıfırla" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Boyut" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Widget ekle" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Ana sayfa ekranında yeterli yer yok." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Widget eklenemiyor" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Yükleniyor..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Veri yüklenemiyor. Tekrar denemek için dokunun." + diff --git a/widget_viewer_evas/res/po/uk.po b/widget_viewer_evas/res/po/uk.po new file mode 100644 index 0000000..a5bf0b2 --- /dev/null +++ b/widget_viewer_evas/res/po/uk.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Завантаження..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Натисніть, щоб створити" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Увімкнути" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "Вимкнути" + +msgid "IDS_ST_BODY_NEW" +msgstr "Нове" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Стандартний" + +msgid "IDS_ST_BODY_MODE" +msgstr "Режим" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "Вимкнення..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "Готово" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Редагувати" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Створити" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Довідка" + +msgid "IDS_ST_BODY_RESET" +msgstr "Скинути" + +msgid "IDS_ST_BODY_SIZE" +msgstr "Розмір" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Додавання віджета" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Недостатньо місця на головному екрані." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Неможливо додати віджет" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Завантаження..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Неможливо завантажити дані. Натисніть, щоб спробувати ще раз" + diff --git a/widget_viewer_evas/res/po/ur.po b/widget_viewer_evas/res/po/ur.po new file mode 100644 index 0000000..98ec573 --- /dev/null +++ b/widget_viewer_evas/res/po/ur.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "لوڈنگ..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "تخلیق کرنے کے لئے تھپکیں" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "فعال" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "نااہل کریں" + +msgid "IDS_ST_BODY_NEW" +msgstr "نیا" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "ڈیفالٹ" + +msgid "IDS_ST_BODY_MODE" +msgstr "موڈ" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "غیر فعال کر رہا ہے..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "مکمل" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "تدوین کریں" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "تخلیق" + +msgid "IDS_ST_HEADER_HELP" +msgstr "مدد" + +msgid "IDS_ST_BODY_RESET" +msgstr "دوبارہ سیٹ" + +msgid "IDS_ST_BODY_SIZE" +msgstr "سائز" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "وجیٹ شامل کریں" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "ہوم اسکرین پر کافی جگہ نہیں ہے۔" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "وجیٹ شامل کرنے سے قاصر" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "لوڈنگ..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "ڈیٹا لوڈ کرنے سے قاصر۔ پھرکوشش کرنے کے لئے تھپتھپائیں۔" + diff --git a/widget_viewer_evas/res/po/uz.po b/widget_viewer_evas/res/po/uz.po new file mode 100644 index 0000000..12738d7 --- /dev/null +++ b/widget_viewer_evas/res/po/uz.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "Yuklanmoqda..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "Yaratish uchun cherting" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "Yoqish" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "O‘chirish" + +msgid "IDS_ST_BODY_NEW" +msgstr "Yangi" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "Birlamchi" + +msgid "IDS_ST_BODY_MODE" +msgstr "Rejim" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "O‘chirilmoqda..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "OK" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "Tahrirlash" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "Yaratish" + +msgid "IDS_ST_HEADER_HELP" +msgstr "Yordam" + +msgid "IDS_ST_BODY_RESET" +msgstr "Qayta yuklash" + +msgid "IDS_ST_BODY_SIZE" +msgstr "O‘lcham" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "Vidjet qo‘shish" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "Asosiy ekranda bo‘sh joy yetarli emas." + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "Vidjetni qo‘shib bo‘lmaydi" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "Yuklanmoqda..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "Ma’lumotni yuklab bo‘lmaydi. Qayta urinib ko‘rish uchun cherting" + diff --git a/widget_viewer_evas/res/po/zh_CN.po b/widget_viewer_evas/res/po/zh_CN.po new file mode 100644 index 0000000..71e43f0 --- /dev/null +++ b/widget_viewer_evas/res/po/zh_CN.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "载入中…" + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "点击以创建" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "启动" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "禁用" + +msgid "IDS_ST_BODY_NEW" +msgstr "新建" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "默认" + +msgid "IDS_ST_BODY_MODE" +msgstr "模式" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "正在禁用..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "完成" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "编辑" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "新建" + +msgid "IDS_ST_HEADER_HELP" +msgstr "帮助" + +msgid "IDS_ST_BODY_RESET" +msgstr "重置" + +msgid "IDS_ST_BODY_SIZE" +msgstr "大小" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "添加小组件" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "主屏上空间不足。" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "无法添加小组件" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "载入中…" + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "无法载入数据。轻敲以重试。" + diff --git a/widget_viewer_evas/res/po/zh_HK.po b/widget_viewer_evas/res/po/zh_HK.po new file mode 100644 index 0000000..a874a98 --- /dev/null +++ b/widget_viewer_evas/res/po/zh_HK.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "正在載入..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "輕觸以建立" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "啟用" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "關閉" + +msgid "IDS_ST_BODY_NEW" +msgstr "新的" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "預設" + +msgid "IDS_ST_BODY_MODE" +msgstr "模式" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "正在停用..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "完成" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "編輯" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "建立" + +msgid "IDS_ST_HEADER_HELP" +msgstr "說明" + +msgid "IDS_ST_BODY_RESET" +msgstr "重設" + +msgid "IDS_ST_BODY_SIZE" +msgstr "大小" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "加入 Widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "主螢幕空間不足。" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "無法加入 Widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "正在載入..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "無法載入數據。輕觸以重試。" + diff --git a/widget_viewer_evas/res/po/zh_TW.po b/widget_viewer_evas/res/po/zh_TW.po new file mode 100644 index 0000000..ad9e807 --- /dev/null +++ b/widget_viewer_evas/res/po/zh_TW.po @@ -0,0 +1,57 @@ +msgid "IDS_ST_POP_LOADING_ING" +msgstr "正在載入..." + +msgid "IDS_ST_BUTTON_TAP_TO_CREATE" +msgstr "輕觸以建立" + +msgid "IDS_ST_BUTTON_ENABLE" +msgstr "啟用" + +msgid "IDS_ST_BUTTON_DISABLE" +msgstr "停用" + +msgid "IDS_ST_BODY_NEW" +msgstr "新增" + +msgid "IDS_ST_BODY_MYTHEME_DEFAULT" +msgstr "預設" + +msgid "IDS_ST_BODY_MODE" +msgstr "模式" + +msgid "IDS_ST_BODY_DISABLING_ING" +msgstr "正在停用..." + +msgid "IDS_HS_BUTTON_DONE" +msgstr "完成" + +msgid "IDS_HS_BUTTON_EDIT_ABB" +msgstr "編輯" + +msgid "IDS_ST_BODY_MYTHEME_CREATE" +msgstr "建立" + +msgid "IDS_ST_HEADER_HELP" +msgstr "說明" + +msgid "IDS_ST_BODY_RESET" +msgstr "重設" + +msgid "IDS_ST_BODY_SIZE" +msgstr "大小" + +msgid "IDS_HS_HEADER_ADD_WIDGET" +msgstr "新增 widget" + +msgid "IDS_HS_BODY_NOT_ENOUGH_SPACE_ON_THE_HOME_SCREEN" +msgstr "主螢幕空間不足。" + +msgid "IDS_HS_HEADER_UNABLE_TO_ADD_WIDGET_ABB" +msgstr "無法新增 widget" + +msgid "IDS_ST_BODY_LOADING_ING" +msgstr "正在載入..." + +msgid "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" +msgstr "無法載入資料。輕觸以重試。" + diff --git a/widget_viewer_evas/res/unknown.png b/widget_viewer_evas/res/unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..535db6063ad8e69e355c808507480f46ab0ea5bc GIT binary patch literal 19568 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

e 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 +#include + +#include +#include + +int util_screen_size_get(int *x, int *y) +{ + *x = 0; + *y = 0; + + return 0; +} + +unsigned int util_replace_native_surface(struct widget *handle, int gbar, Evas_Object *content, unsigned int pixmap) +{ + return 0u; +} + +int util_set_native_surface(struct widget *handle, int gbar, Evas_Object *content, unsigned int pixmap, int skip_acquire) +{ + return 1; +} + +unsigned int util_get_resource_id_of_native_surface(Evas_Native_Surface *surface) +{ + return 0u; +} + +void *util_display_get(void) +{ + return NULL; +} + +/* End of a file */ diff --git a/widget_viewer_evas/src/util_x11.c b/widget_viewer_evas/src/util_x11.c new file mode 100644 index 0000000..b614a1c --- /dev/null +++ b/widget_viewer_evas/src/util_x11.c @@ -0,0 +1,107 @@ +#include +#include + +#include + +#include + +#include +#include + +#include "debug.h" + +int util_screen_size_get(int *w, int *h) +{ + int _w; + int _h; + + if (!w) { + w = &_w; + } + + if (!h) { + h = &_h; + } + + ecore_x_window_size_get(0, w, h); + return 0; +} + +unsigned int util_replace_native_surface(struct widget *handle, int gbar, Evas_Object *content, unsigned int pixmap) +{ + Evas_Native_Surface *old_surface; + Evas_Native_Surface surface; + unsigned int old_pixmap = 0u; + + surface.version = EVAS_NATIVE_SURFACE_VERSION; + surface.type = EVAS_NATIVE_SURFACE_X11; + surface.data.x11.pixmap = pixmap; + + old_surface = evas_object_image_native_surface_get(content); + if (!old_surface) { + surface.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get()); + + evas_object_image_native_surface_set(content, &surface); + + DbgPrint("Created: %u\n", surface.data.x11.pixmap); + } else { + old_pixmap = old_surface->data.x11.pixmap; + + if (old_pixmap != pixmap) { + surface.data.x11.visual = old_surface->data.x11.visual; + evas_object_image_native_surface_set(content, &surface); + DbgPrint("Replaced: %u (%u)\n", pixmap, old_pixmap); + } else { + DbgPrint("Same resource, reuse it [%u]\n", pixmap); + old_pixmap = 0u; + } + } + + return old_pixmap; +} + +int util_set_native_surface(struct widget *handle, int gbar, Evas_Object *content, unsigned int pixmap, int skip_acquire) +{ + Evas_Native_Surface *old_surface; + Evas_Native_Surface surface; + int is_first = 0; + + surface.version = EVAS_NATIVE_SURFACE_VERSION; + surface.type = EVAS_NATIVE_SURFACE_X11; + surface.data.x11.pixmap = (unsigned int)pixmap; + + old_surface = evas_object_image_native_surface_get(content); + if (!old_surface) { + surface.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get()); + evas_object_image_native_surface_set(content, &surface); + + is_first = 1; + } else { + unsigned int old_pixmap = 0u; + old_pixmap = old_surface->data.x11.pixmap; + surface.data.x11.visual = old_surface->data.x11.visual; + evas_object_image_native_surface_set(content, &surface); + + if (old_pixmap) { + if (!skip_acquire) { + widget_viewer_release_resource_id(handle, gbar, old_pixmap); + } + } + + is_first = 0; + } + + return is_first; +} + +unsigned int util_get_resource_id_of_native_surface(Evas_Native_Surface *surface) +{ + return surface ? surface->data.x11.pixmap : 0u; +} + +void *util_display_get(void) +{ + return ecore_x_display_get(); +} + +/* End of a file */ diff --git a/widget_viewer_evas/src/widget_viewer_evas.c b/widget_viewer_evas/src/widget_viewer_evas.c new file mode 100644 index 0000000..4e5efc2 --- /dev/null +++ b/widget_viewer_evas/src/widget_viewer_evas.c @@ -0,0 +1,8280 @@ +/* + * Samsung API + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT 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 +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "util.h" + +#if defined(LOG_TAG) +#undef LOG_TAG +#endif +#define LOG_TAG "WIDGET_EVAS" +#include + +#include "widget_viewer_evas.h" +#include "widget_viewer_evas_internal.h" + +#if !defined(WIDGET_COUNT_OF_SIZE_TYPE) + #define WIDGET_COUNT_OF_SIZE_TYPE 13 +#endif + +#if !defined(SECURE_LOGD) +#define SECURE_LOGD LOGD +#endif + +#if !defined(SECURE_LOGW) +#define SECURE_LOGW LOGW +#endif + +#if !defined(SECURE_LOGE) +#define SECURE_LOGE LOGE +#endif + +#if !defined(S_) +#define S_(str) dgettext("sys_string", str) +#endif + +#if !defined(T_) +#define T_(str) dgettext(PKGNAME, str) +#endif + +#if !defined(N_) +#define N_(str) (str) +#endif + +#if !defined(_) +#define _(str) gettext(str) +#endif + + +#if !defined(DbgPrint) +#define DbgPrint(format, arg...) SECURE_LOGD(format, ##arg) +#endif + +#if !defined(ErrPrint) +#define ErrPrint(format, arg...) SECURE_LOGE(format, ##arg) +#endif + +#if !defined(WarnPrint) +#define WarnPrint(format, arg...) SECURE_LOGW(format, ##arg) +#endif + +#if !defined(WIDGET_VIEWER_EVAS_RESOURCE_EDJ) +#define WIDGET_VIEWER_EVAS_RESOURCE_EDJ "/usr/share/widget_viewer_evas/res/edje/widget_viewer_evas.edj" +#endif + +#if !defined(WIDGET_VIEWER_EVAS_UNKNOWN) +#define WIDGET_VIEWER_EVAS_UNKNOWN "/usr/share/widget_viewer_evas/res/image/unknown.png" +#endif + +#if !defined(WIDGET_VIEWER_EVAS_RESOURCE_GBAR) +#define WIDGET_VIEWER_EVAS_RESOURCE_GBAR "gbar" +#endif + +#if !defined(WIDGET_VIEWER_EVAS_RESOURCE_LB) +#define WIDGET_VIEWER_EVAS_RESOURCE_LB "widget" +#endif + +#if !defined(WIDGET_VIEWER_EVAS_RESOURCE_IMG) +#define WIDGET_VIEWER_EVAS_RESOURCE_IMG "widget,image" +#endif + +#if !defined(WIDGET_VIEWER_EVAS_RESOURCE_OVERLAY_LOADING) +#define WIDGET_VIEWER_EVAS_RESOURCE_OVERLAY_LOADING "overlay" +#endif + +#define DEFAULT_OVERLAY_COUNTER 2 +#define DEFAULT_OVERLAY_WAIT_TIME 1.0f +#define RESEVED_AREA_FOR_GBAR_EFFECT 100 + +#define WIDGET_CLASS_NAME "widget" + +#define WIDGET_KEEP_BUFFER -2 + +#define DEFAULT_CLUSTER "user,created" +#define DEFAULT_CATEGORY "default" + +/** + * @note + * Supported touch devices are limited to 32. + * Because of count of bits of integer type. (32 bits) + */ +#define MAX_DEVICE 32 + +#define IS_PRESSED(info, device) (((device) < MAX_DEVICE) ? (((info)->pressed & (0x01 << (device))) == (0x01 << (device))) : 0) + +/** + * @note + * Short-Circuit + */ +#define SET_PRESSED(info, device) ((void)(((device) < MAX_DEVICE) && (((info)->pressed |= (0x01 << (device)))))) +#define SET_RELEASED(info, device) ((void)(((device) < MAX_DEVICE) && (((info)->pressed &= (~(0x01 << (device))))))) + +/*! + * \note + * Enable this to apply shadow effect to image object (for text widget) + * #define SUPPORT_IMAGE_EFFECT + */ + +int errno; + +/*! + * \note + * Detect click event if the pointer does moved in this region (x , y < 5 pixels) + */ +#define CLICK_REGION WIDGET_CONF_CLICK_REGION + +static struct { + Evas_Smart_Class sc; + Evas_Smart *smart; + Eina_List *list; + struct { + Eina_List *delete_list; + Eina_List *create_list; + } raw_event; + int screen_width; + int screen_height; + + union _conf { + struct _field { + unsigned int user_view_port:1; + unsigned int force_to_buffer:1; + unsigned int support_gbar:1; + unsigned int manual_pause_resume:1; + unsigned int use_fixed_size:1; + unsigned int easy_mode:1; + unsigned int is_scroll_x:1; + unsigned int is_scroll_y:1; + unsigned int auto_feed:1; + unsigned int delayed_resume:1; + unsigned int sensitive_move:1; + unsigned int render_animator:1; + unsigned int auto_render_selector:1; + unsigned int skip_acquire:1; + + unsigned int reserved:18; + } field; + unsigned int mask; + } conf; + + Evas_Object *win; + Ecore_Animator *renderer; + Eina_List *widget_dirty_objects; + Eina_List *gbar_dirty_objects; + Eina_List *subscribed_category_list; + Eina_List *subscribed_group_list; + + int initialized; +} s_info = { + .sc = EVAS_SMART_CLASS_INIT_NAME_VERSION(WIDGET_CLASS_NAME), + .smart = NULL, + .list = NULL, + .raw_event = { + .delete_list = NULL, + .create_list = NULL, + }, + .conf = { + .mask = 0, + }, + .screen_width = 720, + .screen_height = 1280, + .win = NULL, + .renderer = NULL, + .widget_dirty_objects = NULL, + .gbar_dirty_objects = NULL, + .subscribed_category_list = NULL, + .subscribed_group_list = NULL, + .initialized = 0, +}; + +struct subscribe_group { + char *cluster; + char *sub_cluster; +}; + +struct subscribe_category { + char *category; +}; + +struct access_ret_cb_data { + Evas_Object *obj; + void (*ret_cb)(Evas_Object *, int, void *); + void *data; +}; + +struct acquire_data { + struct widget_data *data; + Evas_Object *content; + int w; + int h; +}; + +enum CANCEL_CLICK { + CANCEL_DISABLED = 0x0, + CANCEL_USER = 0x01, + CANCEL_PROCESSED = 0x02 +}; + +struct preview_info { + widget_size_type_e type; + char *preview; +}; + +struct widget_data { + enum { + WIDGET_DATA_CREATED = 0x00beef00, + WIDGET_DATA_DELETED = 0x0d0e0a0d, + } state; + struct widget *handle; + Evas *e; + Evas_Object *stage; /*!< Do not resize this directly, it should be resized via XX_update_geometry */ + Evas_Object *parent; + + Evas_Object *widget_layout; /*!< Layout of widget content part */ + Evas_Object *gbar_layout; /*!< Layout of GBAR content part */ + + Evas_Object *widget; /*!< Container object */ + + struct view_port { + int x; + int y; + int w; + int h; + } view_port; + + char *widget_id; + char *content; + char *cluster; + char *category; + double period; + + void *widget_fb; + void *gbar_fb; + + unsigned int gbar_pixmap; + unsigned int widget_pixmap; + + unsigned int *gbar_extra; + unsigned int *widget_extra; + int gbar_extra_cnt; + int widget_extra_cnt; + + int widget_latest_idx; /* -1 = primary buffer, 0 ~ = extra buffer */ + int gbar_latest_idx; /* -1 = primary buffer, 0 ~ = extra buffer */ + + struct _down { + int x; + int y; + + struct _geo { + int x; + int y; + } geo; + + int is_gbar; + } down; + + int x[MAX_DEVICE]; + int y[MAX_DEVICE]; + + int widget_width; + int widget_height; + int fixed_width; + int fixed_height; + widget_size_type_e size_type; + unsigned int pressed; /**< Mouse is pressed */ + + union { + struct { + unsigned int touch_effect:1; /**< Requires to play touch effect */ + unsigned int mouse_event:1; /**< Requires to feed mouse event */ + unsigned int scroll_x:1; /**< */ + unsigned int scroll_y:1; + unsigned int faulted:1; + unsigned int flick_down:1; + unsigned int gbar_created:1; + + unsigned int created:1; + unsigned int deleted:1; + unsigned int widget_pixmap_acquire_requested:1; + unsigned int gbar_pixmap_acquire_requested:1; + unsigned int cancel_scroll_x:1; + unsigned int cancel_scroll_y:1; + unsigned int cancel_click:2; + unsigned int disable_preview:1; + unsigned int disable_loading:1; + unsigned int disable_text:1; + unsigned int widget_overlay_loaded:1; + unsigned int gbar_overlay_loaded:1; + + unsigned int freeze_visibility:1; + + unsigned int widget_dirty:1; + unsigned int gbar_dirty:1; + + unsigned int send_delete:1; + unsigned int permanent_delete:1; + + unsigned int delayed_resume:2; + unsigned int initial_resumed:1; + + unsigned int disabled_overlay_animation:1; + unsigned int extra_info_updated:1; + + unsigned int hide_overlay_manually:1; + + unsigned int reserved: 1; + } field; /* Do we really have the performance loss because of bit fields? */ + + unsigned int flags; + } is; + + int refcnt; + int overlay_update_counter; + Ecore_Timer *overlay_timer; + widget_visibility_status_e freezed_visibility; + + Eina_List *gbar_script_object_list; + Eina_List *widget_script_object_list; + + Ecore_Timer *delayed_resume_timer; + + Eina_List *preview_list; +}; + +struct script_object { + char *id; + Evas_Object *obj; + Evas_Object *parent; /* Swallowee object : Before delete 'obj', it should be unswallowed from this object */ +}; + +enum EFFECT_MASK { + EFFECT_NONE = 0x0, + EFFECT_WIDTH = 0x01, + EFFECT_HEIGHT = 0x02, + EFFECT_BOTH = 0x03, + EFFECT_MOVE = 0x10 +}; + +struct animation_data { + Ecore_Timer *timer; + Evas_Object *obj; + + unsigned int effect_mask; + int w; + int h; + int x; + int y; +}; + +struct raw_event_cbdata { + void (*cb)(struct widget_evas_raw_event_info *info, void *data); + void *data; +}; + +struct image_option { + int orient; + int aspect; + enum { + FILL_DISABLE, + FILL_IN_SIZE, + FILL_OVER_SIZE, + FILL_FIT_SIZE + } fill; + + struct shadow { + int enabled; + int angle; + int offset; + int softness; + int color; + } shadow; + + int width; + int height; +}; + +static int widget_fault_handler(enum widget_fault_type fault, const char *pkgname, const char *filename, const char *funcname, void *data); +static int widget_event_handler(struct widget *handle, enum widget_event_type event, void *data); + +static int widget_system_created(struct widget *handle, struct widget_data *data); +static void __widget_created_cb(struct widget *handle, int ret, void *cbdata); +static void __widget_overlay_loading(struct widget_data *data); +static void __widget_overlay_faulted(struct widget_data *data); +static void __widget_overlay_disable(struct widget_data *data, int no_timer, int ignore_update_count); + +static void gbar_overlay_loading(struct widget_data *data); +static void gbar_overlay_disable(struct widget_data *data); + +static void update_widget_geometry(struct acquire_data *acquire_data); +static void update_gbar_geometry(struct acquire_data *acquire_data); +static void update_stage_geometry(struct acquire_data *acquire_data); +static void animator_del_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info); + +static void remove_widget_dirty_object_list(struct widget_data *data); +static void remove_gbar_dirty_object_list(struct widget_data *data); +static void append_widget_dirty_object_list(struct widget_data *data, int idx); +static void append_gbar_dirty_object_list(struct widget_data *data, int idx); +static void __widget_event_widget_updated(struct widget_data *data); +static void __widget_event_gbar_updated(struct widget_data *data); + +static inline bool is_widget_feature_enabled(void) +{ + static bool feature = false; + static bool retrieved = false; + + if (retrieved == false) { + int ret; + + ret = system_info_get_platform_bool("http://tizen.org/feature/shell.appwidget", &feature); + if (ret != SYSTEM_INFO_ERROR_NONE) { + ErrPrint("system_info: %d\n", ret); + } else { + retrieved = true; + } + } + + return feature; +} + +static char *get_preview_image(struct widget_data *data, widget_size_type_e type) +{ + Eina_List *l; + struct preview_info *info; + char *preview; + + EINA_LIST_FOREACH(data->preview_list, l, info) { + if (info->type == type) { + preview = strdup(info->preview); + if (!preview) { + ErrPrint("strdup: %d\n", errno); + } + return preview; + } + } + + return widget_service_get_preview_image_path(data->widget_id, type); +} + +static struct widget_data *get_smart_data(Evas_Object *widget) +{ + if (widget && evas_object_smart_type_check(widget, WIDGET_CLASS_NAME)) { + struct widget_data *data; + + data = evas_object_smart_data_get(widget); + if (data) { + if (data->state == WIDGET_DATA_CREATED) { + return data; + } + + ErrPrint("smart data is not valid\n"); + } else { + ErrPrint("smart data is not exists\n"); + } + } + + return NULL; +} + +static struct widget_data *get_smart_data_from_handle(widget_h handle) +{ + Evas_Object *widget; + + widget = widget_viewer_get_data(handle); + if (!widget) { + return NULL; + } + + return get_smart_data(widget); +} + +static Evas_Object *find_script_object(struct widget_data *data, int gbar, const char *id) +{ + Eina_List *script_object_list; + struct script_object *so; + Eina_List *l; + + if (gbar) { + if (!data->gbar_layout) { + return NULL; + } + + script_object_list = data->gbar_script_object_list; + } else { + if (!data->widget_layout) { + return NULL; + } + + script_object_list = data->widget_script_object_list; + } + + if (!id) { + so = eina_list_nth(script_object_list, 0); + return so ? so->obj : NULL; + } + + EINA_LIST_FOREACH(script_object_list, l, so) { + if (so->id && !strcmp(so->id, id)) { + return so->obj; + } + } + + return NULL; +} + +static void gbar_script_del_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + struct widget_data *data = cbdata; + Eina_List *l; + Eina_List *n; + struct script_object *so; + + EINA_LIST_FOREACH_SAFE(data->gbar_script_object_list, l, n, so) { + if (so->obj == obj) { + data->gbar_script_object_list = eina_list_remove(data->gbar_script_object_list, so); + free(so->id); + free(so); + break; + } + } +} + +static void __widget_script_del_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + struct widget_data *data = cbdata; + Eina_List *l; + Eina_List *n; + struct script_object *so; + + EINA_LIST_FOREACH_SAFE(data->widget_script_object_list, l, n, so) { + if (so->obj == obj) { + data->widget_script_object_list = eina_list_remove(data->widget_script_object_list, so); + free(so->id); + free(so); + break; + } + } +} + +static void script_signal_forwarder(void *cbdata, Evas_Object *obj, const char *signal_name, const char *source) +{ + struct widget_data *data = cbdata; + struct widget_text_signal event_info = { + .signal_name = signal_name, + .source = source, + .geometry = { + .sx = 0.0f, + .sy = 0.0f, + .ex = 1.0f, + .ey = 1.0f, + } + }; + + widget_viewer_emit_text_signal(data->handle, &event_info, NULL, NULL); +} + +static int append_script_object(struct widget_data *data, int gbar, const char *id, Evas_Object *parent, Evas_Object *child) +{ + struct script_object *so; + + so = malloc(sizeof(*so)); + if (!so) { + ErrPrint("malloc: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + if (id) { + so->id = strdup(id); + if (!so->id) { + ErrPrint("strdup: %d\n", errno); + free(so); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + } else { + so->id = NULL; + } + + so->obj = child; + so->parent = parent; + + if (gbar) { + data->gbar_script_object_list = eina_list_append(data->gbar_script_object_list, so); + evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, gbar_script_del_cb, data); + } else { + data->widget_script_object_list = eina_list_append(data->widget_script_object_list, so); + evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, __widget_script_del_cb, data); + } + + elm_object_signal_callback_add(child, "*", "*", script_signal_forwarder, data); + return WIDGET_ERROR_NONE; +} + +static inline void reset_scroller(struct widget_data *data) +{ + Evas_Object *scroller; + int height = 0; + int width = 0; + + if (!data->widget_layout) { + return; + } + + scroller = elm_object_part_content_get(data->widget_layout, "scroller"); + if (!scroller) { + return; + } + + if (s_info.conf.field.is_scroll_x) { + height = data->widget_height >> 1; + } + + if (s_info.conf.field.is_scroll_y) { + width = data->widget_width >> 1; + } + + elm_scroller_region_show(scroller, width, height, data->widget_width, data->widget_height); +} + +static int invoke_raw_event_callback(enum widget_evas_raw_event_type type, const char *pkgname, Evas_Object *widget, int error) +{ + struct widget_evas_raw_event_info info; + struct raw_event_cbdata *cbdata; + Eina_List *l; + Eina_List *n; + int cnt = 0; + + info.pkgname = pkgname; + info.widget = widget; + info.error = error; + info.type = type; + + switch (type) { + case WIDGET_VIEWER_EVAS_RAW_DELETE: + EINA_LIST_FOREACH_SAFE(s_info.raw_event.delete_list, l, n, cbdata) { + if (cbdata->cb) { + cbdata->cb(&info, cbdata->data); + cnt++; + } + } + break; + case WIDGET_VIEWER_EVAS_RAW_CREATE: + EINA_LIST_FOREACH_SAFE(s_info.raw_event.create_list, l, n, cbdata) { + if (cbdata->cb) { + cbdata->cb(&info, cbdata->data); + cnt++; + } + } + break; + default: + break; + } + + return cnt; +} + +static widget_size_type_e find_size_type(struct widget_data *data, int w, int h) +{ + int cnt = WIDGET_COUNT_OF_SIZE_TYPE; + int i; + int *_w = NULL; + int *_h = NULL; + widget_size_type_e type = WIDGET_SIZE_TYPE_UNKNOWN; + int find; + int ret_type = WIDGET_SIZE_TYPE_UNKNOWN; + int delta; + + if (widget_service_get_supported_sizes(data->widget_id, &cnt, &_w, &_h) < 0) { + ErrPrint("No available sizes: %s\n", data->widget_id); + return WIDGET_SIZE_TYPE_UNKNOWN; + } + + find = 0x7FFFFFFF; + for (i = 0; i < cnt; i++) { + widget_service_get_size_type(_w[i], _h[i], &type); + + if (!s_info.conf.field.easy_mode) { + switch (type) { + case WIDGET_SIZE_TYPE_EASY_1x1: + case WIDGET_SIZE_TYPE_EASY_3x1: + case WIDGET_SIZE_TYPE_EASY_3x3: + continue; + default: + break; + } + } else { + switch (type) { + case WIDGET_SIZE_TYPE_EASY_1x1: + case WIDGET_SIZE_TYPE_EASY_3x1: + case WIDGET_SIZE_TYPE_EASY_3x3: + break; + default: + continue; + } + } + + delta = abs(_w[i] - w) + abs(_h[i] - h); + if (delta < find) { + find = delta; + ret_type = type; + } + } + + free(_w); + free(_h); + + return ret_type; +} + +static Eina_Bool effect_animator_cb(void *_data) +{ + struct animation_data *data = _data; + int w; + int h; + int x; + int y; + int move_x = 0; + int move_y = 0; + + evas_object_geometry_get(data->obj, &x, &y, &w, &h); + if (data->w == w && data->h == h) { + evas_object_event_callback_del(data->obj, EVAS_CALLBACK_DEL, animator_del_cb); + evas_object_data_del(data->obj, "animation"); + free(data); + return ECORE_CALLBACK_CANCEL; + } + + if (data->effect_mask & EFFECT_WIDTH) { + if (w < data->w) { + if (data->w - w > RESEVED_AREA_FOR_GBAR_EFFECT) { + w += 20; + move_x = 20; + } else if (data->w - w > 10) { + w += 8; + move_x = 8; + } else { + w++; + move_x = 1; + } + } else if (w > data->w) { + if (w - data->w > RESEVED_AREA_FOR_GBAR_EFFECT) { + w -= 20; + move_x = -20; + } else if (w - data->w > 10) { + w -= 8; + move_x = -8; + } else { + w--; + move_x = -1; + } + } + } else { + w = data->w; + } + + if (data->effect_mask & EFFECT_HEIGHT) { + if (h < data->h) { + if (data->h - h > RESEVED_AREA_FOR_GBAR_EFFECT) { + h += 20; + move_y = 20; + } else if (data->h - h > 10) { + h += 8; + move_y = 8; + } else { + h++; + move_y = 1; + } + } else if (h > data->h) { + if (h - data->h > RESEVED_AREA_FOR_GBAR_EFFECT) { + h -= 20; + move_y = -20; + } else if (h - data->h > 10) { + h -= 8; + move_y = -8; + } else { + h--; + move_y = -1; + } + } + } else { + h = data->h; + } + + if (data->effect_mask & EFFECT_MOVE) { + if (move_x) { + x -= move_x; + } + if (move_y) { + y -= move_y; + } + evas_object_move(data->obj, x, y); + } + + evas_object_resize(data->obj, w, h); + return ECORE_CALLBACK_RENEW; +} + +static void animator_del_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + struct animation_data *data; + + data = evas_object_data_del(obj, "animation"); + if (data) { + ecore_timer_del(data->timer); + free(data); + } +} + +static void effect_size_get(Evas_Object *obj, int *w, int *h) +{ + struct animation_data *data; + + data = evas_object_data_get(obj, "animation"); + if (data) { + *w = data->w; + *h = data->h; + } else { + evas_object_geometry_get(obj, NULL, NULL, w, h); + } +} + +static void effect_resize(Evas_Object *obj, int w, int h, unsigned int effect_mask) +{ + struct animation_data *data; + int ow; + int oh; + int ox; + int oy; + + evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); + + data = evas_object_data_get(obj, "animation"); + if (data) { + if (ow == w && oh == h) { + evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, animator_del_cb); + evas_object_data_del(obj, "animation"); + free(data); + return; + } + /*! + * \note + * Update to new size + */ + data->w = w; + data->h = h; + return; + } else if (ow == w && oh == h) { + return; + } + + data = malloc(sizeof(*data)); + if (!data) { + ErrPrint("Heap: %d\n", errno); + return; + } + + data->obj = obj; + data->w = w; + data->h = h; + data->x = ox; + data->y = oy; + data->effect_mask = effect_mask; + + data->timer = ecore_timer_add(1.0f/60.0f, effect_animator_cb, data); + if (!data->timer) { + free(data); + return; + } + + evas_object_data_set(obj, "animation", data); + evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, animator_del_cb, data); +} + +struct widget_data *widget_ref(struct widget_data *data) +{ + data->refcnt++; + return data; +} + +static void dump_handle_list(void) +{ + Eina_List *l = NULL; + Eina_List *n; + Evas_Object *widget; + struct widget_data *data; + + DbgPrint("============== DUMP ==============="); + EINA_LIST_FOREACH_SAFE(s_info.list, l, n, widget) { + data = evas_object_smart_data_get(widget); + if (!data) { + continue; + } + + DbgPrint("data[%p] %s (%s)\n", data, data->widget_id, data->is.field.faulted ? "faulted" : "loaded"); + } + DbgPrint("==================================="); +} + +struct widget_data *widget_unref(struct widget_data *data) +{ + Eina_List *l; + Eina_List *n; + struct preview_info *info; + + data->refcnt--; + DbgPrint("refcnt: %d (%s)\n", data->refcnt, data->widget_id); + if (data->refcnt != 0) { + return data; + } + + DbgPrint("Destroy widget data %p(%s)\n", data, data->widget_id); + free(data->content); + free(data->widget_id); + free(data->cluster); + free(data->category); + + EINA_LIST_FOREACH_SAFE(data->preview_list, l, n, info) { + free(info->preview); + free(info); + } + + if (data->overlay_timer) { + ecore_timer_del(data->overlay_timer); + data->overlay_timer = NULL; + } + + if (data->stage) { + DbgPrint("Remove Stage\n"); + evas_object_del(data->stage); + } + + if (data->widget_layout) { + Evas_Object *content; + + content = elm_object_part_content_unset(data->widget_layout, "widget,content"); + if (content) { + Evas_Object *front; + + front = elm_object_part_content_unset(content, "front,content"); + if (front) { + DbgPrint("Front image object is deleted\n"); + evas_object_del(front); + } + + DbgPrint("Content object deleted\n"); + evas_object_del(content); + } + + content = elm_object_part_content_unset(data->widget_layout, "overlay,content"); + if (content) { + DbgPrint("Overlay is deleted\n"); + evas_object_del(content); + } + + + DbgPrint("Remove WIDGET Layout\n"); + evas_object_del(data->widget_layout); + } + + if (data->gbar_layout) { + Evas_Object *content; + content = elm_object_part_content_get(data->gbar_layout, "gbar,content"); + if (content) { + Evas_Object *overlay; + overlay = elm_object_part_content_unset(content, "overlay,content"); + if (overlay) { + DbgPrint("Overlay is deleted\n"); + evas_object_del(overlay); + } + } + DbgPrint("Remove GBAR Layout\n"); + evas_object_del(data->gbar_layout); + } + + if (data->widget_fb) { + widget_viewer_release_buffer(data->widget_fb); + data->widget_fb = NULL; + } + + if (data->gbar_fb) { + widget_viewer_release_buffer(data->gbar_fb); + data->gbar_fb = NULL; + } + + data->state = WIDGET_DATA_DELETED; + free(data); + dump_handle_list(); + return NULL; +} + +static void gbar_multi_down_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Multi_Down *down = event_info; + struct widget_data *data = cbdata; + struct widget_mouse_event_info minfo; + Evas_Coord x, y, w, h; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + SET_PRESSED(data, down->device); + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + if (data->size_type != WIDGET_SIZE_TYPE_UNKNOWN && !s_info.conf.field.use_fixed_size) { + minfo.ratio_w = (double)data->fixed_width / (double)w; + minfo.ratio_h = (double)data->fixed_height / (double)h; + } else { + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + } + minfo.device = down->device; + + if (s_info.conf.field.auto_feed) { + minfo.x = (double)x; + minfo.y = (double)y; + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_SET, &minfo); + } else { + minfo.x = (double)(down->canvas.x - x); + minfo.y = (double)(down->canvas.y - y); + + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_ENTER, &minfo); + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_DOWN, &minfo); + } + + if (data->is.field.cancel_click == CANCEL_USER) { + minfo.x = (double)(down->canvas.x - x); + minfo.y = (double)(down->canvas.y - y); + + minfo.device = 0; + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_ON_HOLD, &minfo); + data->is.field.cancel_click = CANCEL_PROCESSED; + } +} + +static void gbar_down_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Down *down = event_info; + struct widget_data *data = cbdata; + struct widget_mouse_event_info minfo; + Evas_Coord x, y, w, h; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + evas_object_geometry_get(obj, &data->down.geo.x, &data->down.geo.y, &w, &h); + x = data->down.geo.x; + y = data->down.geo.y; + data->down.is_gbar = 1; + + data->x[0] = data->down.x = down->canvas.x; + data->y[0] = data->down.y = down->canvas.y; + SET_PRESSED(data, 0); + if (s_info.conf.field.auto_render_selector) { + DbgPrint("Change to direct render\n"); + s_info.conf.field.render_animator = 0; + } + + /** + * In case of the GBar, + * There is no pre-defined size set. + * Every time its size will be notified to the provider app. + * So we don't need to handling the scale info of it. + */ + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + minfo.device = 0; + + if (s_info.conf.field.auto_feed) { + minfo.x = (double)x; + minfo.y = (double)y; + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_SET, &minfo); + } else { + minfo.x = (double)(down->canvas.x - x); + minfo.y = (double)(down->canvas.y - y); + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_ENTER, &minfo); + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_DOWN, &minfo); + } +} + +static void gbar_multi_move_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Multi_Move *move = event_info; + struct widget_data *data = cbdata; + Evas_Coord x, y, w, h; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (!IS_PRESSED(data, move->device)) { + return; + } + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + /** + * @note + * In this case, the ON_HOLD event is already sent. + * We don't need to check the cancel_state. + */ + if (!s_info.conf.field.auto_feed) { + struct widget_mouse_event_info minfo; + + minfo.x = (double)(move->cur.canvas.x - x); + minfo.y = (double)(move->cur.canvas.y - y); + + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + minfo.device = move->device; + + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_MOVE, &minfo); + + if (s_info.conf.field.auto_render_selector) { + DbgPrint("Change to direct render\n"); + s_info.conf.field.render_animator = 0; + } + } +} + +static void gbar_move_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Move *move = event_info; + struct widget_data *data = cbdata; + Evas_Coord x, y, w, h; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (!IS_PRESSED(data,0)) { + return; + } + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + data->x[0] = move->cur.canvas.x; + data->y[0] = move->cur.canvas.y; + + if (data->is.field.cancel_click == CANCEL_USER || !s_info.conf.field.auto_feed) { + struct widget_mouse_event_info minfo; + + minfo.x = (double)(move->cur.canvas.x - x); + minfo.y = (double)(move->cur.canvas.y - y); + + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + minfo.device = 0; + + if (!s_info.conf.field.auto_feed) { + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_MOVE, &minfo); + } + + if (data->is.field.cancel_click == CANCEL_USER) { + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_ON_HOLD, &minfo); + data->is.field.cancel_click = CANCEL_PROCESSED; + } + + if (s_info.conf.field.auto_render_selector) { + DbgPrint("Change to direct render\n"); + s_info.conf.field.render_animator = 0; + } + } +} + +static void __widget_pixmap_del_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + struct widget_data *data = cbdata; + + if (data->widget_pixmap) { + if (!s_info.conf.field.skip_acquire) { + widget_viewer_release_resource_id(data->handle, 0, data->widget_pixmap); + } + data->widget_pixmap = 0; + } + + if (data->widget_extra) { + int idx; + + for (idx = 0; idx < widget_viewer_get_option(WIDGET_OPTION_EXTRA_BUFFER_CNT); idx++) { + if (data->widget_extra[idx] != 0u) { + if (!s_info.conf.field.skip_acquire) { + if (widget_viewer_release_resource_id(data->handle, 0, data->widget_extra[idx]) < 0) { + ErrPrint("Failed to release %u\n", data->widget_extra[idx]); + } + } + data->widget_extra[idx] = 0u; + } + } + + free(data->widget_extra); + data->widget_extra = NULL; + } +} + +static void gbar_pixmap_del_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + struct widget_data *data = cbdata; + + if (data->gbar_pixmap) { + if (!s_info.conf.field.skip_acquire) { + widget_viewer_release_resource_id(data->handle, 1, data->gbar_pixmap); + } + data->gbar_pixmap = 0; + } + + if (data->gbar_extra) { + int idx; + + for (idx = 0; idx < widget_viewer_get_option(WIDGET_OPTION_EXTRA_BUFFER_CNT); idx++) { + if (data->gbar_extra[idx] != 0u) { + if (!s_info.conf.field.skip_acquire) { + if (widget_viewer_release_resource_id(data->handle, 0, data->gbar_extra[idx]) < 0) { + ErrPrint("Failed to release %u\n", data->gbar_extra[idx]); + } + } + data->gbar_extra[idx] = 0u; + } + } + + free(data->gbar_extra); + data->gbar_extra = NULL; + } +} + +static void gbar_multi_up_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Multi_Up *up = event_info; + struct widget_data *data = cbdata; + Evas_Coord x, y, w, h; + struct widget_mouse_event_info minfo; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (!IS_PRESSED(data, up->device)) { + return; + } + + SET_RELEASED(data, up->device); + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + minfo.device = up->device; + + if (s_info.conf.field.auto_feed) { + /** + * @note + * UNSET will subtract object.x and object.y by master + * so we just send original touch position based on screen + */ + minfo.x = (double)up->canvas.x; + minfo.y = (double)up->canvas.y; + + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_UNSET, &minfo); + } else { + minfo.x = (double)(up->canvas.x - x); + minfo.y = (double)(up->canvas.y - y); + + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_UP, &minfo); + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_LEAVE, &minfo); + } +} + +static void gbar_up_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Up *up = event_info; + struct widget_data *data = cbdata; + Evas_Coord x, y, w, h; + struct widget_mouse_event_info minfo; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (!IS_PRESSED(data, 0)) { + return; + } + + SET_RELEASED(data, 0); + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + minfo.device = 0; + + /** + * @note + * If the object is moved, we should send ON_HOLD event. + */ + if (data->down.geo.x != x || data->down.geo.y != y || data->is.field.cancel_click == CANCEL_USER) { + if (data->is.field.cancel_click != CANCEL_PROCESSED) { + minfo.x = (double)(up->canvas.x - x); + minfo.y = (double)(up->canvas.y - y); + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_ON_HOLD, &minfo); + data->is.field.cancel_click = CANCEL_PROCESSED; + } + } + + if (s_info.conf.field.auto_feed) { + /** + * @note + * UNSET will subtract object.x and object.y by master + * so we just send original touch position based on screen + */ + minfo.x = (double)up->canvas.x; + minfo.y = (double)up->canvas.y; + + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_UNSET, &minfo); + } else { + minfo.x = (double)(up->canvas.x - x); + minfo.y = (double)(up->canvas.y - y); + + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_UP, &minfo); + widget_viewer_feed_mouse_event(data->handle, WIDGET_GBAR_MOUSE_LEAVE, &minfo); + } + + data->is.field.cancel_click = CANCEL_DISABLED; +} + +static void smart_callback_call(struct widget_data *data, const char *signal, void *cbdata) +{ + if (data->is.field.deleted || !data->widget) { + DbgPrint("widget is deleted, ignore smart callback call\n"); + return; + } + + evas_object_smart_callback_call(data->widget, signal, cbdata); +} + +static void __widget_multi_down_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Multi_Down *down = event_info; + struct widget_data *data = cbdata; + Evas_Coord x, y, w, h; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + data->x[down->device] = down->canvas.x; + data->y[down->device] = down->canvas.y; + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + /** + * @note + * If the multi-touch started, + * GBar will not be created. + */ + if (s_info.conf.field.support_gbar && data->is.field.flick_down) { + struct widget_evas_event_info info; + + DbgPrint("Flick down is canceled\n"); + data->is.field.flick_down = 0; + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_GBAR_CREATED; + info.error = WIDGET_ERROR_CANCELED; + + smart_callback_call(data, WIDGET_SMART_SIGNAL_FLICKDOWN_CANCELLED, &info); + } + + if (s_info.conf.field.auto_render_selector) { + DbgPrint("Change to direct render\n"); + s_info.conf.field.render_animator = 0; + } + + SET_PRESSED(data, down->device); + + if (data->handle && !data->is.field.faulted) { + struct widget_mouse_event_info minfo; + + if (!s_info.conf.field.use_fixed_size) { + minfo.ratio_w = (double)data->fixed_width / (double)w; + minfo.ratio_h = (double)data->fixed_height / (double)h; + } else { + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + } + minfo.device = down->device; + + if (s_info.conf.field.auto_feed && data->is.field.mouse_event) { + minfo.x = (double)data->down.geo.x; + minfo.y = (double)data->down.geo.y; + DbgPrint("[%d] %lfx%lf (%lfx%lf), %dx%d %dx%d\n", minfo.device, minfo.x, minfo.y, minfo.ratio_w, minfo.ratio_h, data->fixed_width, data->fixed_height, w, h); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_SET, &minfo); + } else { + minfo.x = (double)(data->x[down->device] - x); + minfo.y = (double)(data->y[down->device] - y); + + DbgPrint("[%d] %lfx%lf (%lfx%lf)\n", minfo.device, minfo.x, minfo.y, minfo.ratio_w, minfo.ratio_h); + + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_ENTER, &minfo); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_DOWN, &minfo); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_MOVE, &minfo); + } + + /** + * @note + * Send the ON_HOLD event if the multi-touch events are triggered. + */ + if (data->is.field.cancel_click != CANCEL_PROCESSED) { + DbgPrint("ON_HOLD send\n"); + minfo.x = (double)(data->x[0] - x); + minfo.y = (double)(data->y[0] - y); + minfo.device = 0; + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_ON_HOLD, &minfo); + data->is.field.cancel_click = CANCEL_PROCESSED; + } + } +} + +static void __widget_down_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Down *down = event_info; + struct widget_data *data = cbdata; + Evas_Coord x, y, w, h; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (s_info.conf.field.support_gbar && !data->is.field.gbar_created) { + data->is.field.flick_down = 1; + } + + data->down.x = data->x[0] = down->canvas.x; + data->down.y = data->y[0] = down->canvas.y; + data->down.is_gbar = 0; + data->is.field.scroll_x = 0; + data->is.field.scroll_y = 0; + data->is.field.cancel_scroll_x = 0; + data->is.field.cancel_scroll_y = 0; + + if (s_info.conf.field.auto_render_selector) { + DbgPrint("Change to direct render\n"); + s_info.conf.field.render_animator = 0; + } + + evas_object_geometry_get(obj, &data->down.geo.x, &data->down.geo.y, &w, &h); + x = data->down.geo.x; + y = data->down.geo.y; + + if (s_info.conf.field.sensitive_move && (data->down.geo.x != data->view_port.x || data->down.geo.y != data->view_port.y)) { + SET_RELEASED(data, 0); + if (s_info.conf.field.auto_render_selector) { + DbgPrint("Change to render animator\n"); + s_info.conf.field.render_animator = 1; + } + return; + } + + SET_PRESSED(data, 0); + + if (data->handle && !data->is.field.faulted) { + struct widget_mouse_event_info minfo; + + if (!s_info.conf.field.use_fixed_size) { + minfo.ratio_w = (double)data->fixed_width / (double)w; + minfo.ratio_h = (double)data->fixed_height / (double)h; + } else { + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + } + minfo.device = 0; + + if (s_info.conf.field.auto_feed && data->is.field.mouse_event) { + minfo.x = (double)x; + minfo.y = (double)y; + DbgPrint("%lfx%lf (%lfx%lf), %dx%d %dx%d\n", minfo.x, minfo.y, minfo.ratio_w, minfo.ratio_h, data->fixed_width, data->fixed_height, w, h); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_SET, &minfo); + } else { + minfo.x = (double)(data->x[0] - x); + minfo.y = (double)(data->y[0] - y); + + DbgPrint("%lfx%lf (%lfx%lf)\n", minfo.x, minfo.y, minfo.ratio_w, minfo.ratio_h); + + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_ENTER, &minfo); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_DOWN, &minfo); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_MOVE, &minfo); + } + } +} + +static void __widget_destroy_gbar_cb(struct widget *handle, int ret, void *cbdata) +{ + struct widget_data *data = cbdata; + Evas_Object *gbar_content; + struct widget_evas_event_info info; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + data->is.field.gbar_created = 0; + + info.error = ret; + info.event = WIDGET_EVENT_GBAR_DESTROYED; + info.widget_app_id = data->widget_id; + smart_callback_call(data, WIDGET_SMART_SIGNAL_GBAR_DESTROYED, &info); + + DbgPrint("ret: %d\n", ret); + gbar_content = elm_object_part_content_unset(data->gbar_layout, "gbar,content"); + if (gbar_content) { + Evas_Native_Surface *surface; + unsigned int pixmap; + widget_type_e widget_type; + + widget_viewer_get_type(data->handle, 1, &widget_type); + + switch (widget_type) { + case WIDGET_CONTENT_TYPE_RESOURCE_ID: + if (!s_info.conf.field.force_to_buffer) { + surface = evas_object_image_native_surface_get(gbar_content); + if (!surface) { + ErrPrint("surface is NULL\n"); + evas_object_del(gbar_content); + break; + } + + pixmap = util_get_resource_id_of_native_surface(surface); + evas_object_del(gbar_content); + + if (!s_info.conf.field.skip_acquire) { + widget_viewer_release_resource_id(data->handle, 1, (int)pixmap); + } + + if (pixmap == data->gbar_pixmap) { + data->gbar_pixmap = 0; + } + break; + } + case WIDGET_CONTENT_TYPE_BUFFER: + if (data->gbar_fb) { + widget_viewer_release_buffer(data->gbar_fb); + data->gbar_fb = NULL; + } + evas_object_del(gbar_content); + break; + case WIDGET_CONTENT_TYPE_TEXT: + break; + case WIDGET_CONTENT_TYPE_UIFW: + break; + case WIDGET_CONTENT_TYPE_INVALID: + default: + break; + } + } + + if (data->gbar_layout) { + evas_object_del(data->gbar_layout); + data->gbar_layout = NULL; + } + + remove_gbar_dirty_object_list(data); + widget_unref(data); +} + +static void gbar_animation_done_cb(void *cbdata, Evas_Object *obj, const char *signal_name, const char *source) +{ + Evas_Object *rect; + struct widget_data *data = cbdata; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + rect = elm_object_part_content_unset(obj, "overlay,content"); + if (rect) { + evas_object_del(rect); + } +} + +static void gbar_create_buffer_object(struct widget_data *data) +{ + Evas_Object *gbar_content; + + gbar_content = elm_object_part_content_get(data->gbar_layout, "gbar,content"); + if (!gbar_content) { + gbar_content = evas_object_image_filled_add(data->e); + if (!gbar_content) { + ErrPrint("Failed to create an image object\n"); + } else { + evas_object_image_colorspace_set(gbar_content, EVAS_COLORSPACE_ARGB8888); + evas_object_image_alpha_set(gbar_content, EINA_TRUE); + + elm_object_part_content_set(data->gbar_layout, "gbar,content", gbar_content); + } + } +} + +static int do_text_update_color(Evas_Object *layout, const char *part, const char *data) +{ + int ret; + int r[3], g[3], b[3], a[3]; + ret = sscanf(data, "%d %d %d %d %d %d %d %d %d %d %d %d", + r, g, b, a, /* OBJECT */ + r + 1, g + 1, b + 1, a + 1, /* OUTLINE */ + r + 2, g + 2, b + 2, a + 2); /* SHADOW */ + if (ret != 12) { + DbgPrint("part[%s] rgba[%s]\n", part, data); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + ret = edje_object_color_class_set(elm_layout_edje_get(layout), part, + r[0], g[0], b[0], a[0], /* OBJECT */ + r[1], g[1], b[1], a[1], /* OUTLINE */ + r[2], g[2], b[2], a[2]); /* SHADOW */ + + return WIDGET_ERROR_NONE; +} + +static void update_focus_chain(Evas_Object *parent, Evas_Object *ao) +{ + const Eina_List *list; + + list = elm_object_focus_custom_chain_get(parent); + if (!eina_list_data_find(list, ao)) { + DbgPrint("Append again to the focus chain\n"); + elm_object_focus_custom_chain_append(parent, ao, NULL); + } +} + +static void activate_cb(void *data, Evas_Object *part_obj, Elm_Object_Item *item) +{ + Evas *e; + int x; + int y; + int w; + int h; + double timestamp; + + e = evas_object_evas_get(part_obj); + evas_object_geometry_get(part_obj, &x, &y, &w, &h); + x += w / 2; + y += h / 2; + +#if defined(_USE_ECORE_TIME_GET) + timestamp = ecore_time_get(); +#else + struct timeval tv; + if (gettimeofday(&tv, NULL) < 0) { + ErrPrint("Failed to get time\n"); + timestamp = 0.0f; + } else { + timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f); + } +#endif + + DbgPrint("Cursor is on %dx%d\n", x, y); + evas_event_feed_mouse_move(e, x, y, timestamp * 1000, NULL); + evas_event_feed_mouse_down(e, 1, EVAS_BUTTON_NONE, (timestamp + 0.01f) * 1000, NULL); + evas_event_feed_mouse_move(e, x, y, (timestamp + 0.02f) * 1000, NULL); + evas_event_feed_mouse_up(e, 1, EVAS_BUTTON_NONE, (timestamp + 0.03f) * 1000, NULL); +} + +static int do_text_update_access(Evas_Object *parent, Evas_Object *layout, const char *part, const char *text, const char *option) +{ + Evas_Object *edje_part; + + elm_object_part_text_set(layout, part, text ? text : ""); + + edje_part = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(layout), part); + if (edje_part) { + Evas_Object *ao; + char *utf8; + + ao = evas_object_data_get(edje_part, "ao"); + if (!ao) { + ao = elm_access_object_register(edje_part, parent); + if (!ao) { + ErrPrint("Unable to register an access object(%s)\n", part); + return WIDGET_ERROR_NONE; + } + + evas_object_data_set(edje_part, "ao", ao); + elm_access_activate_cb_set(ao, activate_cb, NULL); + elm_object_focus_custom_chain_append(parent, ao, NULL); + + DbgPrint("[%s] Register access info: (%s) to, %p\n", part, text, parent); + } + + if (!text || !strlen(text)) { + /*! + * \note + * Delete callback will be called + */ + DbgPrint("[%s] Remove access object(%p)\n", part, ao); + elm_access_object_unregister(ao); + + return WIDGET_ERROR_NONE; + } + + utf8 = elm_entry_markup_to_utf8(text); + if ((!utf8 || !strlen(utf8))) { + free(utf8); + /*! + * \note + * Delete callback will be called + */ + DbgPrint("[%s] Remove access object(%p)\n", part, ao); + elm_access_object_unregister(ao); + + return WIDGET_ERROR_NONE; + } + + elm_access_info_set(ao, ELM_ACCESS_INFO, utf8); + free(utf8); + + update_focus_chain(parent, ao); + } else { + ErrPrint("Unable to get text part[%s]\n", part); + } + + return WIDGET_ERROR_NONE; +} + +static void parse_aspect(struct image_option *img_opt, const char *value, int len) +{ + while (len > 0 && *value == ' ') { + value++; + len--; + } + + if (len < 4) { + return; + } + + img_opt->aspect = !strncasecmp(value, "true", 4); + DbgPrint("Parsed ASPECT: %d (%s)\n", img_opt->aspect, value); +} + +static void parse_orient(struct image_option *img_opt, const char *value, int len) +{ + while (len > 0 && *value == ' ') { + value++; + len--; + } + + if (len < 4) { + return; + } + + img_opt->orient = !strncasecmp(value, "true", 4); + DbgPrint("Parsed ORIENT: %d (%s)\n", img_opt->orient, value); +} + +static void parse_size(struct image_option *img_opt, const char *value, int len) +{ + int width; + int height; + char *buf; + + while (len > 0 && *value == ' ') { + value++; + len--; + } + + buf = strndup(value, len); + if (!buf) { + ErrPrint("Heap: %d\n", errno); + return; + } + + if (sscanf(buf, "%dx%d", &width, &height) == 2) { + img_opt->width = width; + img_opt->height = height; + DbgPrint("Parsed size : %dx%d (%s)\n", width, height, buf); + } else { + DbgPrint("Invalid size tag[%s]\n", buf); + } + + free(buf); +} + +static void parse_shadow(struct image_option *img_opt, const char *value, int len) +{ + int angle; + int offset; + int softness; + int color; + + if (sscanf(value, "%d,%d,%d,%x", &angle, &offset, &softness, &color) != 4) { + ErrPrint("Invalid shadow [%s]\n", value); + } else { + img_opt->shadow.enabled = 1; + img_opt->shadow.angle = angle; + img_opt->shadow.offset = offset; + img_opt->shadow.softness = softness; + img_opt->shadow.color = color; + } +} + +static void parse_fill(struct image_option *img_opt, const char *value, int len) +{ + while (len > 0 && *value == ' ') { + value++; + len--; + } + + if (!strncasecmp(value, "in-size", len)) { + img_opt->fill = FILL_IN_SIZE; + } else if (!strncasecmp(value, "over-size", len)) { + img_opt->fill = FILL_OVER_SIZE; + } else if (!strncasecmp(value, "fit-size", len)) { + img_opt->fill = FILL_FIT_SIZE; + } else { + img_opt->fill = FILL_DISABLE; + } + + DbgPrint("Parsed FILL: %d (%s)\n", img_opt->fill, value); +} + +static inline void parse_image_option(const char *option, struct image_option *img_opt) +{ + const char *ptr; + const char *cmd; + const char *value; + struct { + const char *cmd; + void (*handler)(struct image_option *img_opt, const char *value, int len); + } cmd_list[] = { + { + .cmd = "aspect", /* Keep the aspect ratio */ + .handler = parse_aspect, + }, + { + .cmd = "orient", /* Keep the orientation value: for the rotated images */ + .handler = parse_orient, + }, + { + .cmd = "fill", /* Fill the image to its container */ + .handler = parse_fill, /* Value: in-size, over-size, disable(default) */ + }, + { + .cmd = "size", + .handler = parse_size, + }, + { + .cmd = "shadow", + .handler = parse_shadow, + }, + }; + enum { + STATE_START, + STATE_TOKEN, + STATE_DATA, + STATE_IGNORE, + STATE_ERROR, + STATE_END + } state; + int idx; + int tag; + + if (!option || !*option) { + return; + } + + state = STATE_START; + /*! + * \note + * GCC 4.7 warnings uninitialized idx and tag value. + * But it will be initialized by the state machine. :( + * Anyway, I just reset idx and tag for reducing the GCC4.7 complains. + */ + idx = 0; + tag = 0; + cmd = NULL; + value = NULL; + + for (ptr = option; state != STATE_END; ptr++) { + switch (state) { + case STATE_START: + if (*ptr == '\0') { + state = STATE_END; + continue; + } + + if (isalpha(*ptr)) { + state = STATE_TOKEN; + ptr--; + } + tag = 0; + idx = 0; + + cmd = cmd_list[tag].cmd; + break; + case STATE_IGNORE: + if (*ptr == '=') { + state = STATE_DATA; + value = ptr; + } else if (*ptr == '\0') { + state = STATE_END; + } + break; + case STATE_TOKEN: + if (cmd[idx] == '\0' && (*ptr == ' ' || *ptr == '\t' || *ptr == '=')) { + if (*ptr == '=') { + value = ptr; + state = STATE_DATA; + } else { + state = STATE_IGNORE; + } + idx = 0; + } else if (*ptr == '\0') { + state = STATE_END; + } else if (cmd[idx] == *ptr) { + idx++; + } else { + ptr -= (idx + 1); + + tag++; + if (tag == sizeof(cmd_list) / sizeof(cmd_list[0])) { + tag = 0; + state = STATE_ERROR; + } else { + cmd = cmd_list[tag].cmd; + } + idx = 0; + } + break; + case STATE_DATA: + if (*ptr == ';' || *ptr == '\0') { + cmd_list[tag].handler(img_opt, value + 1, idx); + state = *ptr ? STATE_START : STATE_END; + } else { + idx++; + } + break; + case STATE_ERROR: + if (*ptr == ';') { + state = STATE_START; + } else if (*ptr == '\0') { + state = STATE_END; + } + break; + default: + break; + } + } +} + +static inline void apply_shadow_effect(struct image_option *img_opt, Evas_Object *img) +{ +#if defined(SUPPORT_IMAGE_EFFECT) + ea_effect_h *ea_effect; + + if (!img_opt->shadow.enabled) { + return; + } + + ea_effect = ea_image_effect_create(); + if (!ea_effect) { + return; + } + + /* -90, 2, 4, 0x99000000 */ + ea_image_effect_add_outer_shadow(ea_effect, img_opt->shadow.angle, img_opt->shadow.offset, img_opt->shadow.softness, img_opt->shadow.color); + ea_object_image_effect_set(img, ea_effect); + + ea_image_effect_destroy(ea_effect); +#endif +} + +static Evas_Object *crop_image(Evas_Object *img, const char *path, int part_w, int part_h, int w, int h, struct image_option *img_opt) +{ + Ecore_Evas *ee; + Evas *e; + Evas_Object *src_img; + Evas_Coord rw, rh; + const void *data; + Evas_Load_Error err; + Evas_Object *_img; + + ee = ecore_evas_buffer_new(part_w, part_h); + if (!ee) { + ErrPrint("Failed to create a EE\n"); + return img; + } + + ecore_evas_alpha_set(ee, EINA_TRUE); + + e = ecore_evas_get(ee); + if (!e) { + ErrPrint("Unable to get Evas\n"); + ecore_evas_free(ee); + return img; + } + + src_img = evas_object_image_filled_add(e); + if (!src_img) { + ErrPrint("Unable to add an image\n"); + ecore_evas_free(ee); + return img; + } + + evas_object_image_alpha_set(src_img, EINA_TRUE); + evas_object_image_colorspace_set(src_img, EVAS_COLORSPACE_ARGB8888); + evas_object_image_smooth_scale_set(src_img, EINA_TRUE); + evas_object_image_load_orientation_set(src_img, img_opt->orient); + evas_object_image_file_set(src_img, path, NULL); + err = evas_object_image_load_error_get(src_img); + if (err != EVAS_LOAD_ERROR_NONE) { + ErrPrint("Load error: %s\n", evas_load_error_str(err)); + evas_object_del(src_img); + ecore_evas_free(ee); + return img; + } + evas_object_image_size_get(src_img, &rw, &rh); + evas_object_image_fill_set(src_img, 0, 0, rw, rh); + evas_object_resize(src_img, w, h); + evas_object_move(src_img, -(w - part_w) / 2, -(h - part_h) / 2); + evas_object_show(src_img); + + data = ecore_evas_buffer_pixels_get(ee); + if (!data) { + ErrPrint("Unable to get pixels\n"); + evas_object_del(src_img); + ecore_evas_free(ee); + return img; + } + + e = evas_object_evas_get(img); + _img = evas_object_image_filled_add(e); + if (!_img) { + evas_object_del(src_img); + ecore_evas_free(ee); + return img; + } + + evas_object_image_colorspace_set(_img, EVAS_COLORSPACE_ARGB8888); + evas_object_image_smooth_scale_set(_img, EINA_TRUE); + evas_object_image_alpha_set(_img, EINA_TRUE); + evas_object_image_data_set(_img, NULL); + evas_object_image_size_set(_img, part_w, part_h); + evas_object_resize(_img, part_w, part_h); + evas_object_image_data_copy_set(_img, (void *)data); + evas_object_image_fill_set(_img, 0, 0, part_w, part_h); + evas_object_image_data_update_add(_img, 0, 0, part_w, part_h); + + evas_object_del(src_img); + ecore_evas_free(ee); + + evas_object_del(img); + return _img; +} + +static int do_text_update_text(Evas_Object *parent, Evas_Object *layout, const char *part, const char *text) +{ + Evas_Object *edje_part; + + DbgPrint("Part[%s], Text[%s]\n", part, text); + elm_object_part_text_set(layout, part, text ? text : ""); + + edje_part = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(layout), part); + if (edje_part) { + Evas_Object *ao; + char *utf8; + + ao = evas_object_data_get(edje_part, "ao"); + if (!ao) { + ao = elm_access_object_register(edje_part, parent); + if (!ao) { + ErrPrint("Unable to register an access object(%s)\n", part); + return WIDGET_ERROR_NONE; + } + + evas_object_data_set(edje_part, "ao", ao); + elm_access_activate_cb_set(ao, activate_cb, NULL); + elm_object_focus_custom_chain_append(parent, ao, NULL); + + DbgPrint("[%s] Register access info: (%s) to, %p\n", part, text, parent); + } + + if (!text || !strlen(text)) { + /*! + * \note + * Delete callback will be called + */ + DbgPrint("[%s] Remove access object(%p)\n", part, ao); + elm_access_object_unregister(ao); + + return WIDGET_ERROR_NONE; + } + + utf8 = elm_entry_markup_to_utf8(text); + if ((!utf8 || !strlen(utf8))) { + free(utf8); + /*! + * \note + * Delete callback will be called + */ + DbgPrint("[%s] Remove access object(%p)\n", part, ao); + elm_access_object_unregister(ao); + + return WIDGET_ERROR_NONE; + } + + elm_access_info_set(ao, ELM_ACCESS_INFO, utf8); + free(utf8); + + update_focus_chain(parent, ao); + } else { + ErrPrint("Unable to get text part[%s]\n", part); + } + + return WIDGET_ERROR_NONE; +} + +static int do_text_update_image(Evas_Object *layout, const char *part, const char *data, const char *option) +{ + Evas_Object *content; + Evas_Load_Error err; + Evas_Coord w; + Evas_Coord h; + struct image_option img_opt = { + .aspect = 0, + .orient = 0, + .fill = FILL_DISABLE, + .width = -1, + .height = -1, + .shadow = { + .enabled = 0, + }, + }; + + content = elm_object_part_content_unset(layout, part); + if (content) { + evas_object_del(content); + } + + if (!data || !strlen(data) || access(data, R_OK) != 0) { + ErrPrint("Skip image: %s, deleted\n", part); + return WIDGET_ERROR_NONE; + } + + content = evas_object_image_add(evas_object_evas_get(layout)); + if (!content) { + ErrPrint("Failed to add an image object\n"); + return WIDGET_ERROR_FAULT; + } + + evas_object_image_preload(content, EINA_FALSE); + parse_image_option(option, &img_opt); + evas_object_image_load_orientation_set(content, img_opt.orient); + + evas_object_image_file_set(content, data, NULL); + err = evas_object_image_load_error_get(content); + if (err != EVAS_LOAD_ERROR_NONE) { + ErrPrint("Load error: %s\n", evas_load_error_str(err)); + evas_object_del(content); + return WIDGET_ERROR_IO_ERROR; + } + + apply_shadow_effect(&img_opt, content); + + evas_object_image_size_get(content, &w, &h); + if (img_opt.aspect) { + if (img_opt.fill == FILL_OVER_SIZE) { + Evas_Coord part_w; + Evas_Coord part_h; + + if (img_opt.width >= 0 && img_opt.height >= 0) { + part_w = img_opt.width; + part_h = img_opt.height; + } else { + part_w = 0; + part_h = 0; + edje_object_part_geometry_get(elm_layout_edje_get(layout), part, NULL, NULL, &part_w, &part_h); + } + DbgPrint("Original %dx%d (part: %dx%d)\n", w, h, part_w, part_h); + + if (part_w > w || part_h > h) { + double fw; + double fh; + + fw = (double)part_w / (double)w; + fh = (double)part_h / (double)h; + + if (fw > fh) { + w = part_w; + h = (double)h * fw; + } else { + h = part_h; + w = (double)w * fh; + } + } + + if (!part_w || !part_h || !w || !h) { + evas_object_del(content); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + content = crop_image(content, data, part_w, part_h, w, h, &img_opt); + } else if (img_opt.fill == FILL_IN_SIZE) { + Evas_Coord part_w; + Evas_Coord part_h; + + if (img_opt.width >= 0 && img_opt.height >= 0) { + part_w = img_opt.width * elm_config_scale_get(); + part_h = img_opt.height * elm_config_scale_get(); + } else { + part_w = 0; + part_h = 0; + edje_object_part_geometry_get(elm_layout_edje_get(layout), part, NULL, NULL, &part_w, &part_h); + } + DbgPrint("Original %dx%d (part: %dx%d)\n", w, h, part_w, part_h); + + if (w > part_w || h > part_h) { + double fw; + double fh; + + fw = (double)part_w / (double)w; + fh = (double)part_h / (double)h; + + if (fw > fh) { + h = part_h; + w = (double)w * fh; + } else { + w = part_w; + h = (double)h * fw; + } + } + + if (!part_w || !part_h || !w || !h) { + evas_object_del(content); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + content = crop_image(content, data, part_w, part_h, w, h, &img_opt); + } else if (img_opt.fill == FILL_FIT_SIZE) { + Evas_Coord part_w; + Evas_Coord part_h; + double fw; + double fh; + + if (img_opt.width >= 0 && img_opt.height >= 0) { + part_w = img_opt.width * elm_config_scale_get(); + part_h = img_opt.height * elm_config_scale_get(); + } else { + part_w = 0; + part_h = 0; + edje_object_part_geometry_get(elm_layout_edje_get(layout), part, NULL, NULL, &part_w, &part_h); + } + DbgPrint("Original %dx%d (part: %dx%d)\n", w, h, part_w, part_h); + + fw = (double)part_w / (double)w; + fh = (double)part_h / (double)h; + + if (fw < fh) { + h = part_h; + w = (double)w * fh; + } else { + w = part_w; + h = (double)h * fw; + } + + if (!part_w || !part_h || !w || !h) { + evas_object_del(content); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + content = crop_image(content, data, part_w, part_h, w, h, &img_opt); + } else { + evas_object_image_fill_set(content, 0, 0, w, h); + evas_object_size_hint_fill_set(content, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_aspect_set(content, EVAS_ASPECT_CONTROL_BOTH, w, h); + } + + apply_shadow_effect(&img_opt, content); + } else { + if (img_opt.width >= 0 && img_opt.height >= 0) { + w = img_opt.width; + h = img_opt.height; + DbgPrint("Using given image size: %dx%d\n", w, h); + } + + evas_object_image_fill_set(content, 0, 0, w, h); + evas_object_size_hint_fill_set(content, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_image_filled_set(content, EINA_TRUE); + } + + + /*! + * \note + * object will be shown by below statement automatically + */ + DbgPrint("%s part swallow image %p (%dx%d)\n", part, content, w, h); + elm_object_part_content_set(layout, part, content); + + /*! + * \note + * This object is not registered as an access object. + * So the developer should add it to access list manually, using DESC_ACCESS block. + */ + return WIDGET_ERROR_NONE; +} + +static int do_text_update_script(struct widget_data *data, int gbar, Evas_Object *layout, const char *id, const char *part, const char *file, const char *group) +{ + Evas_Object *content; + int ret; + + content = elm_object_part_content_unset(layout, part); + if (content) { + evas_object_del(content); + } + + if (!file || !strlen(file) || access(file, R_OK) != 0) { + ErrPrint("path: %s (%d), Delete old object\n", file, errno); + return WIDGET_ERROR_NONE; + } + + content = elm_layout_add(layout); + if (!content) { + return WIDGET_ERROR_FAULT; + } + + if (elm_layout_file_set(content, file, group) == EINA_FALSE) { + evas_object_del(content); + return WIDGET_ERROR_FAULT; + } + + ret = append_script_object(data, gbar, id, layout, content); + if (ret != WIDGET_ERROR_NONE) { + evas_object_del(content); + return ret; + } + + elm_object_part_content_set(layout, part, content); + /** + * @note + * Do we need to send all script event to the provider? + * + * elm_object_signal_callback_add(obj, "*", "*", script_signal_cb, handle); + */ + return WIDGET_ERROR_NONE; +} + +static int do_text_operate_access(Evas_Object *layout, const char *part, const char *operation, const char *option) +{ + Elm_Access_Action_Info action_info; + int ret; + + memset(&action_info, 0, sizeof(action_info)); + + /* OPERATION is defined in libwidget package */ + if (!strcasecmp(operation, "set,hl")) { + if (part) { + Evas_Object *content; + Evas_Coord x; + Evas_Coord y; + Evas_Coord w; + Evas_Coord h; + + content = elm_object_part_content_get(layout, part); + if (!content) { + ErrPrint("Invalid part: %s\n", part); + return WIDGET_ERROR_NONE; + } + + evas_object_geometry_get(content, &x, &y, &w, &h); + + action_info.x = x + w / 2; + action_info.y = x + h / 2; + } else if (option && sscanf(option, "%dx%d", &action_info.x, &action_info.y) == 2) { + } else { + ErrPrint("Insufficient info for HL\n"); + return WIDGET_ERROR_NONE; + } + + DbgPrint("TXxTY: %dx%d\n", action_info.x, action_info.y); + ret = elm_access_action(layout, ELM_ACCESS_ACTION_HIGHLIGHT, &action_info); + if (ret == EINA_FALSE) { + ErrPrint("Action error\n"); + } + } else if (!strcasecmp(operation, "unset,hl")) { + ret = elm_access_action(layout, ELM_ACCESS_ACTION_UNHIGHLIGHT, &action_info); + if (ret == EINA_FALSE) { + ErrPrint("Action error\n"); + } + } else if (!strcasecmp(operation, "next,hl")) { + action_info.highlight_cycle = (!!option) && (!!strcasecmp(option, "no,cycle")); + + ret = elm_access_action(layout, ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, &action_info); + if (ret == EINA_FALSE) { + ErrPrint("Action error\n"); + } + } else if (!strcasecmp(operation, "prev,hl")) { + action_info.highlight_cycle = EINA_TRUE; + ret = elm_access_action(layout, ELM_ACCESS_ACTION_HIGHLIGHT_PREV, &action_info); + if (ret == EINA_FALSE) { + ErrPrint("Action error\n"); + } + } else if (!strcasecmp(operation, "reset,focus")) { + DbgPrint("Reset Focus\n"); + elm_object_focus_custom_chain_set(layout, NULL); + } + return WIDGET_ERROR_NONE; +} + +static int gbar_text_update_begin(widget_h handle) +{ + struct widget_data *data; + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + DbgPrint("Begin text update: [%s]\n", data->widget_id); + + return WIDGET_ERROR_NONE; +} + +static int gbar_text_update_end(widget_h handle) +{ + struct widget_data *data; + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + DbgPrint("End text update: [%s]\n", data->widget_id); + + return WIDGET_ERROR_NONE; +} + +static int gbar_text_update_text(widget_h handle, const char *id, const char *part, const char *data) +{ + struct widget_data *widget_data; + Evas_Object *layout; + + widget_data = get_smart_data_from_handle(handle); + if (!widget_data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(widget_data, 1, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_update_text(widget_data->parent, layout, part, data); +} + +static int gbar_text_update_image(widget_h handle, const char *id, const char *part, const char *data, const char *option) +{ + struct widget_data *widget_data; + Evas_Object *layout; + + widget_data = get_smart_data_from_handle(handle); + if (!widget_data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(widget_data, 1, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_update_image(layout, part, data, option); +} + +static int gbar_text_update_script(widget_h handle, const char *id, const char *new_id, const char *part, const char *file, const char *group) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 1, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_update_script(data, 1, layout, new_id, part, file, group); +} + +static int gbar_text_update_signal(widget_h handle, const char *id, const char *signal_name, const char *signal) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 1, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + elm_object_signal_emit(layout, signal, signal_name); + return WIDGET_ERROR_NONE; +} + +static int gbar_text_update_drag(widget_h handle, const char *id, const char *part, double dx, double dy) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 1, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + edje_object_part_drag_value_set(elm_layout_edje_get(layout), part, dx, dy); + return WIDGET_ERROR_NONE; +} + +static int gbar_text_update_info_size(widget_h handle, const char *id, int w, int h) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 1, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + DbgPrint("Resize to %dx%d\n", w, h); + evas_object_resize(layout, w, h); + + return WIDGET_ERROR_NONE; +} + +static int gbar_text_update_info_category(widget_h handle, const char *id, const char *category) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 1, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + DbgPrint("Update category: %s\n", category); + + return WIDGET_ERROR_NONE; +} + +static int gbar_text_update_access(widget_h handle, const char *id, const char *part, const char *text, const char *option) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 1, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_update_access(data->parent, layout, part, text, option); +} + +static int gbar_text_operate_access(widget_h handle, const char *id, const char *part, const char *operation, const char *option) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 1, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_operate_access(layout, part, operation, option); +} + +static int gbar_text_update_color(widget_h handle, const char *id, const char *part, const char *data) +{ + struct widget_data *widget_data; + Evas_Object *layout; + + widget_data = get_smart_data_from_handle(handle); + if (!widget_data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(widget_data, 1, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_update_color(layout, part, data); +} + +static void gbar_create_text_object(struct widget_data *data) +{ + Evas_Object *gbar_content; + + gbar_content = elm_object_part_content_get(data->gbar_layout, "gbar,content"); + if (!gbar_content) { + char *script_file; + char *script_group; + struct widget_script_operators operator = { + .update_begin = gbar_text_update_begin, + .update_end = gbar_text_update_end, + + .update_text = gbar_text_update_text, + .update_image = gbar_text_update_image, + .update_script = gbar_text_update_script, + .update_signal = gbar_text_update_signal, + .update_drag = gbar_text_update_drag, + .update_info_size = gbar_text_update_info_size, + .update_info_category = gbar_text_update_info_category, + .update_access = gbar_text_update_access, + .operate_access = gbar_text_operate_access, + .update_color = gbar_text_update_color, + }; + int ret; + + gbar_content = elm_layout_add(data->gbar_layout); + if (!gbar_content) { + ErrPrint("Failed to create a layout object\n"); + return; + } + + script_file = widget_service_get_gbar_script_path(data->widget_id); + script_group = widget_service_get_gbar_script_group(data->widget_id); + if (!script_file || !script_group) { + ErrPrint("Invalid script info ([%s] - [%s])\n", script_file, script_group); + free(script_file); + free(script_group); + evas_object_del(gbar_content); + return; + } + + if (access(script_file, R_OK) != 0) { + ErrPrint("Unable to access [%s] - %d\n", script_file, errno); + free(script_file); + free(script_group); + evas_object_del(gbar_content); + return; + } + + ret = elm_layout_file_set(gbar_content, script_file, script_group); + DbgPrint("Load (%s)(%s)\n", script_file, script_group); + free(script_file); + free(script_group); + if (ret == EINA_FALSE) { + ErrPrint("Failed to load an edje file\n"); + evas_object_del(gbar_content); + return; + } + + if (widget_viewer_set_text_handler(data->handle, 1, &operator) != WIDGET_ERROR_NONE) { + ErrPrint("Failed to set text handler for [%s]\n", data->widget_id); + evas_object_del(gbar_content); + return; + } + + ret = append_script_object(data, 1, NULL, NULL, gbar_content); + if (ret != WIDGET_ERROR_NONE) { + ErrPrint("Failed to append this to script object list\n"); + evas_object_del(gbar_content); + return; + } + + elm_object_part_content_set(data->gbar_layout, "gbar,content", gbar_content); + } +} + +static void gbar_create_pixmap_object(struct widget_data *data) +{ + Evas_Object *gbar_content; + + gbar_content = elm_object_part_content_get(data->gbar_layout, "gbar,content"); + if (!gbar_content) { + gbar_content = evas_object_image_filled_add(data->e); + if (!gbar_content) { + ErrPrint("Failed to create an image object\n"); + return; + } + + evas_object_image_colorspace_set(gbar_content, EVAS_COLORSPACE_ARGB8888); + evas_object_image_alpha_set(gbar_content, EINA_TRUE); + elm_object_part_content_set(data->gbar_layout, "gbar,content", gbar_content); + + evas_object_event_callback_add(gbar_content, EVAS_CALLBACK_MOUSE_DOWN, gbar_down_cb, data); + evas_object_event_callback_add(gbar_content, EVAS_CALLBACK_MOUSE_MOVE, gbar_move_cb, data); + evas_object_event_callback_add(gbar_content, EVAS_CALLBACK_MOUSE_UP, gbar_up_cb, data); + + evas_object_event_callback_add(gbar_content, EVAS_CALLBACK_MULTI_DOWN, gbar_multi_down_cb, data); + evas_object_event_callback_add(gbar_content, EVAS_CALLBACK_MULTI_MOVE, gbar_multi_move_cb, data); + evas_object_event_callback_add(gbar_content, EVAS_CALLBACK_MULTI_UP, gbar_multi_up_cb, data); + + evas_object_event_callback_add(gbar_content, EVAS_CALLBACK_DEL, gbar_pixmap_del_cb, data); + } +} + +static void __widget_create_gbar_cb(struct widget *handle, int ret, void *cbdata) +{ + struct widget_data *data = cbdata; + struct widget_evas_event_info info; + widget_type_e widget_type; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (ret != WIDGET_ERROR_NONE) { + DbgPrint("Create GBAR: 0x%X\n", ret); + info.error = ret; + info.event = WIDGET_EVENT_GBAR_CREATED; + info.widget_app_id = data->widget_id; + smart_callback_call(data, WIDGET_SMART_SIGNAL_GBAR_ABORTED, &info); + widget_unref(data); + return; + } + + if (data->is.field.deleted) { + /** + * Evas Object is deleted. + * Do not proceed this process anymore and destroy GBAR too + */ + if (widget_viewer_destroy_glance_bar(data->handle, NULL, NULL) != WIDGET_ERROR_NONE) { + DbgPrint("widget_viewer_destroy_glance_bar failed\n"); + } + return; + } + + DbgPrint("GBAR is created\n"); + + if (!data->gbar_layout) { + data->gbar_layout = elm_layout_add(data->parent); + if (!data->gbar_layout) { + ErrPrint("Failed to add an edje\n"); + info.error = WIDGET_ERROR_FAULT; + info.event = WIDGET_EVENT_GBAR_CREATED; + info.widget_app_id = data->widget_id; + smart_callback_call(data, WIDGET_SMART_SIGNAL_GBAR_ABORTED, &info); + + ret = widget_viewer_destroy_glance_bar(data->handle, __widget_destroy_gbar_cb, widget_ref(data)); + if (ret < 0) { + /*! + * \note + * PREVENT detect this. but it is FALSE POSITIVE + * + * widget_ref will increase the refcnt of data. + * and it is called when calling the widget_destroy_glance_bar function (via the last param) + * So this function call will not release the data. + */ + widget_unref(data); + } + + widget_unref(data); + return; + } + + if (elm_layout_file_set(data->gbar_layout, WIDGET_VIEWER_EVAS_RESOURCE_EDJ, WIDGET_VIEWER_EVAS_RESOURCE_GBAR) == EINA_FALSE) { + ErrPrint("Failed to load edje object: %s(%s)\n", WIDGET_VIEWER_EVAS_RESOURCE_EDJ, WIDGET_VIEWER_EVAS_RESOURCE_GBAR); + evas_object_del(data->gbar_layout); + data->gbar_layout = NULL; + + info.error = WIDGET_ERROR_IO_ERROR; + info.event = WIDGET_EVENT_GBAR_CREATED; + info.widget_app_id = data->widget_id; + smart_callback_call(data, WIDGET_SMART_SIGNAL_GBAR_ABORTED, &info); + + ret = widget_viewer_destroy_glance_bar(data->handle, __widget_destroy_gbar_cb, widget_ref(data)); + if (ret < 0) { + /*! + * \note + * PREVENT detect this. but it is FALSE POSITIVE + * + * widget_ref will increase the refcnt of data. + * and it is called when calling the widget_destroy_glance_bar function (via the last param) + * So this function call will not release the data. + */ + widget_unref(data); + } + + widget_unref(data); + return; + } + + evas_object_smart_member_add(data->gbar_layout, data->widget); + evas_object_clip_set(data->gbar_layout, data->stage); + elm_object_signal_callback_add(data->gbar_layout, "finished", "animation", gbar_animation_done_cb, data); + evas_object_show(data->gbar_layout); + } + gbar_overlay_loading(data); + + widget_viewer_get_type(data->handle, 1, &widget_type); + + switch (widget_type) { + case WIDGET_CONTENT_TYPE_RESOURCE_ID: + if (!s_info.conf.field.force_to_buffer) { + gbar_create_pixmap_object(data); + break; + } + case WIDGET_CONTENT_TYPE_BUFFER: + gbar_create_buffer_object(data); + break; + case WIDGET_CONTENT_TYPE_TEXT: + gbar_create_text_object(data); + break; + case WIDGET_CONTENT_TYPE_UIFW: + ErrPrint("Not implemented - TYPE_UIFW for GBAR\n"); + default: + info.error = WIDGET_ERROR_INVALID_PARAMETER; + info.event = WIDGET_EVENT_GBAR_CREATED; + info.widget_app_id = data->widget_id; + ret = widget_viewer_destroy_glance_bar(data->handle, __widget_destroy_gbar_cb, widget_ref(data)); + if (ret < 0) { + /*! + * \note + * PREVENT detect this. but it is FALSE POSITIVE + * + * widget_ref will increase the refcnt of data. + * and it is called when calling the widget_destroy_glance_bar function (via the last param) + * So this function call will not release the data. + */ + data = widget_unref(data); + } + ErrPrint("Failed to create a GBAR, unknown type\n"); + if (data) { + smart_callback_call(data, WIDGET_SMART_SIGNAL_GBAR_ABORTED, &info); + data = widget_unref(data); + } + return; + } + + data->is.field.gbar_created = 1; + info.error = WIDGET_ERROR_NONE; + info.event = WIDGET_EVENT_GBAR_CREATED; + info.widget_app_id = data->widget_id; + smart_callback_call(data, WIDGET_SMART_SIGNAL_GBAR_CREATED, &info); + widget_unref(data); +} + +static void update_scroll_flag(struct widget_data *data, int x, int y) +{ + if (s_info.conf.field.is_scroll_x && !s_info.conf.field.is_scroll_y) { + if (!data->is.field.scroll_x && abs(y - data->down.y) > CLICK_REGION && (abs(x - data->down.x) <= CLICK_REGION)) { + data->is.field.cancel_scroll_x = 1; + } + } + + if (s_info.conf.field.is_scroll_y && !s_info.conf.field.is_scroll_x) { + if (!data->is.field.scroll_y && abs(x - data->down.x) > CLICK_REGION && (abs(y - data->down.y) <= CLICK_REGION)) { + data->is.field.cancel_scroll_y = 1; + } + } + + data->is.field.scroll_x = s_info.conf.field.is_scroll_x && (!!(data->is.field.scroll_x || (abs(x - data->down.x) > CLICK_REGION))); + data->is.field.scroll_y = s_info.conf.field.is_scroll_y && (!!(data->is.field.scroll_y || (abs(y - data->down.y) > CLICK_REGION))); + data->is.field.scroll_x = !data->is.field.cancel_scroll_x && data->is.field.scroll_x; + data->is.field.scroll_y = !data->is.field.cancel_scroll_y && data->is.field.scroll_y; +} + +static void __widget_multi_up_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Multi_Up *up = event_info; + struct widget_data *data = cbdata; + Evas_Coord x, y, w, h; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (s_info.conf.field.auto_render_selector) { + DbgPrint("Change to render animator\n"); + s_info.conf.field.render_animator = 1; + } + + if (!IS_PRESSED(data, up->device)) { + return; + } + + SET_RELEASED(data, up->device); + + if (data->handle && !data->is.field.faulted) { + struct widget_mouse_event_info minfo; + + data->x[up->device] = up->canvas.x; + data->y[up->device] = up->canvas.y; + + evas_object_geometry_get(data->widget, &x, &y, &w, &h); + + if (data->size_type != WIDGET_SIZE_TYPE_UNKNOWN && !s_info.conf.field.use_fixed_size) { + minfo.ratio_w = (double)data->fixed_width / (double)w; + minfo.ratio_h = (double)data->fixed_height / (double)h; + DbgPrint("Width: %d/%d - Height: %d/%d\n", data->fixed_width, w, data->fixed_height, h); + } else { + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + } + DbgPrint("Ratio: %lfx%lf\n", minfo.ratio_w, minfo.ratio_h); + minfo.device = up->device; + + if (s_info.conf.field.auto_feed && data->is.field.mouse_event) { + /** + * @note + * UNSET will subtract object.x and object.y by master + * so we just send original touch position based on screen + */ + minfo.x = (double)data->x[up->device]; + minfo.y = (double)data->y[up->device]; + DbgPrint("X,Y = %lfx%lf\n", minfo.x, minfo.y); + + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_UNSET, &minfo); + } else { + /* We have to keep the first position of touch down */ + minfo.x = (double)(data->x[up->device] - x); + minfo.y = (double)(data->y[up->device] - y); + + DbgPrint("%lfx%lf (%lfx%lf)\n", minfo.x, minfo.y, minfo.ratio_w, minfo.ratio_h); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_UP, &minfo); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_LEAVE, &minfo); + } + } +} + +static void __widget_up_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Up *up = event_info; + struct widget_evas_event_info info; + struct widget_data *data = cbdata; + Evas_Coord x, y, w, h; + int ret = 0; + widget_size_type_e size_type; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (!IS_PRESSED(data, 0)) { + return; + } + + update_scroll_flag(data, up->canvas.x, up->canvas.y); + + data->x[0] = up->canvas.x; + data->y[0] = up->canvas.y; + SET_RELEASED(data, 0); + + if (s_info.conf.field.auto_render_selector) { + DbgPrint("Change to render animator\n"); + s_info.conf.field.render_animator = 1; + } + + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_GBAR_CREATED; + + if (s_info.conf.field.support_gbar && data->is.field.flick_down && (data->y[0] - data->down.y) < CLICK_REGION) { + DbgPrint("Flick down is canceled\n"); + data->is.field.flick_down = 0; + info.error = WIDGET_ERROR_CANCELED; + smart_callback_call(data, WIDGET_SMART_SIGNAL_FLICKDOWN_CANCELLED, &info); + } + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + if (data->is.field.flick_down) { + data->is.field.flick_down = 0; + if (!data->handle || data->is.field.faulted || !widget_viewer_has_glance_bar(data->handle)) { + if (!data->is.field.gbar_created && s_info.conf.field.support_gbar) { + elm_object_signal_emit(data->widget_layout, "tilt", "content"); + } + DbgPrint("Flick down is canceled\n"); + info.error = WIDGET_ERROR_CANCELED; + smart_callback_call(data, WIDGET_SMART_SIGNAL_FLICKDOWN_CANCELLED, &info); + } else if (s_info.conf.field.support_gbar && !data->is.field.gbar_created) { + double rx; + double ry; + int gbar_w; + int gbar_h; + + if (widget_viewer_get_glance_bar_size(data->handle, &gbar_w, &gbar_h) != WIDGET_ERROR_NONE) { + gbar_w = 0; + gbar_h = 0; + } + + elm_object_signal_emit(data->widget_layout, "move,down", "content"); + + rx = ((double)x + (double)w / 2.0f) / (double)s_info.screen_width; + DbgPrint("x[%d], w[%d], rx[%lf]\n", x, w, rx); + /* 0.0 0.125 0.25 0.375 0.5 0.625 0.75 0.875 1.0 */ + widget_viewer_get_size_type(data->handle, &size_type); + switch (size_type) { + case WIDGET_SIZE_TYPE_1x1: + if (rx < 0.25f) { + rx = 0.125f; + } else if (rx < 0.5f) { + rx = 0.375f; + } else if (rx < 0.75f) { + rx = 0.625f; + } else if (rx < 1.0f) { + rx = 0.875f; + } + break; + case WIDGET_SIZE_TYPE_2x1: + case WIDGET_SIZE_TYPE_2x2: + if (rx < 0.5f) { + rx = 0.25f; + } else if (rx < 0.625f) { + rx = 0.5f; + } else { + rx = 0.75f; + } + break; + default: + rx = 0.5f; + break; + } + + if (y + h + gbar_h <= s_info.screen_height) { + ry = 0.0f; + } else { + ry = 1.0f; + } + + DbgPrint("converted rx[%lf], ry[%lf]\n", rx, ry); + + ret = widget_viewer_create_glance_bar(data->handle, rx, ry, __widget_create_gbar_cb, widget_ref(data)); + if (ret < 0) { + widget_unref(data); + DbgPrint("Flick down is canceled\n"); + info.error = WIDGET_ERROR_CANCELED; + smart_callback_call(data, WIDGET_SMART_SIGNAL_FLICKDOWN_CANCELLED, &info); + } + DbgPrint("Create GBAR: %d (%lfx%lf)\n", ret, rx, ry); + } + } + + if (data->handle && !data->is.field.faulted) { + struct widget_mouse_event_info minfo; + + if (data->size_type != WIDGET_SIZE_TYPE_UNKNOWN && !s_info.conf.field.use_fixed_size) { + minfo.ratio_w = (double)data->fixed_width / (double)w; + minfo.ratio_h = (double)data->fixed_height / (double)h; + } else { + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + } + minfo.device = 0; + + reset_scroller(data); + + if (data->is.field.cancel_click != CANCEL_PROCESSED) { + if (data->down.geo.x != x || data->down.geo.y != y || + data->is.field.scroll_x || data->is.field.scroll_y || + data->is.field.cancel_click == CANCEL_USER || + (!data->is.field.mouse_event && (abs(data->x[0] - data->down.x) > CLICK_REGION || abs(data->y[0] - data->down.y) > CLICK_REGION)) || + (up->event_flags & EVAS_EVENT_FLAG_ON_HOLD) == EVAS_EVENT_FLAG_ON_HOLD) + { + minfo.x = (double)(data->x[0] - x); + minfo.y = (double)(data->y[0] - y); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_ON_HOLD, &minfo); + data->is.field.cancel_click = CANCEL_PROCESSED; + } + } + + if (s_info.conf.field.auto_feed && data->is.field.mouse_event) { + /** + * @note + * UNSET will subtract object.x and object.y by master + * so we just send original touch position based on screen + */ + minfo.x = (double)data->x[0]; + minfo.y = (double)data->y[0]; + DbgPrint("X,Y = %lfx%lf\n", minfo.x, minfo.y); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_UNSET, &minfo); + } else { + minfo.x = (double)(data->x[0] - x); + minfo.y = (double)(data->y[0] - y); + + DbgPrint("%lfx%lf (%lfx%lf)\n", minfo.x, minfo.y, minfo.ratio_w, minfo.ratio_h); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_UP, &minfo); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_LEAVE, &minfo); + } + + if (!data->is.field.flick_down) { + ret = WIDGET_ERROR_INVALID_PARAMETER; + if (data->is.field.gbar_created) { + ret = widget_viewer_destroy_glance_bar(data->handle, __widget_destroy_gbar_cb, widget_ref(data)); + if (ret < 0) { + data = widget_unref(data); + } + } else if (data->is.field.cancel_click == CANCEL_DISABLED) { + ret = widget_viewer_send_click_event(data->handle, minfo.x, minfo.y); + } + } + + if (data) { + DbgPrint("Up: %lfx%lf [x:%d/%d/%d] [y:%d/%d/%d], ret: 0x%X, cancel: 0x%x\n", + minfo.x, minfo.y, + data->is.field.scroll_x, s_info.conf.field.is_scroll_x, data->is.field.cancel_scroll_x, + data->is.field.scroll_y, s_info.conf.field.is_scroll_y, data->is.field.cancel_scroll_y, + ret, data->is.field.cancel_click); + data->is.field.cancel_click = CANCEL_DISABLED; + } + } +} + +static void __widget_multi_move_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Multi_Move *move = event_info; + struct widget_data *data = cbdata; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (!IS_PRESSED(data, move->device)) { + return; + } + + data->x[move->device] = move->cur.canvas.x; + data->y[move->device] = move->cur.canvas.y; + + if (data->handle && !data->is.field.faulted) { + if (!s_info.conf.field.auto_feed && data->is.field.mouse_event) { + struct widget_mouse_event_info minfo; + Evas_Coord x, y, w, h; + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + minfo.x = (double)(data->x[move->device] - x); + minfo.y = (double)(data->y[move->device] - y); + + if (data->size_type != WIDGET_SIZE_TYPE_UNKNOWN && !s_info.conf.field.use_fixed_size) { + minfo.ratio_w = (double)data->fixed_width / (double)w; + minfo.ratio_h = (double)data->fixed_height / (double)h; + } else { + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + } + minfo.device = move->device; + + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_MOVE, &minfo); + } + } else { + if (s_info.conf.field.auto_render_selector) { + s_info.conf.field.render_animator = 1; + } + } +} + +static void __widget_move_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Move *move = event_info; + struct widget_data *data = cbdata; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (!IS_PRESSED(data, 0)) { + return; + } + + if (s_info.conf.field.support_gbar && data->is.field.flick_down && data->y[0] - move->cur.canvas.y > 0) { + struct widget_evas_event_info info; + + DbgPrint("Flick down is canceled\n"); + data->is.field.flick_down = 0; + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_GBAR_CREATED; + info.error = WIDGET_ERROR_CANCELED; + + smart_callback_call(data, WIDGET_SMART_SIGNAL_FLICKDOWN_CANCELLED, &info); + } + + update_scroll_flag(data, move->cur.canvas.x, move->cur.canvas.y); + + data->x[0] = move->cur.canvas.x; + data->y[0] = move->cur.canvas.y; + + if (data->handle && !data->is.field.faulted) { + Evas_Coord x, y, w, h; + struct widget_mouse_event_info minfo; + int need_move_event = 0; + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + if (data->size_type != WIDGET_SIZE_TYPE_UNKNOWN && !s_info.conf.field.use_fixed_size) { + minfo.ratio_w = (double)data->fixed_width / (double)w; + minfo.ratio_h = (double)data->fixed_height / (double)h; + } else { + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + } + minfo.device = 0; + + if (data->is.field.cancel_click == CANCEL_USER) { + + minfo.x = (double)(data->x[0] - x); + minfo.y = (double)(data->y[0] - y); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_ON_HOLD, &minfo); + + /* + * Reset the clicked event + */ + data->is.field.cancel_click = CANCEL_PROCESSED; + + if (s_info.conf.field.auto_render_selector) { + DbgPrint("Change to render animator\n"); + s_info.conf.field.render_animator = 1; + } + + /** + * @note + * After ON_HOLD, we should send one MOVE event. + */ + need_move_event = 1; + } + + if (!s_info.conf.field.auto_feed && (need_move_event || data->is.field.mouse_event)) { + minfo.x = (double)(data->x[0] - x); + minfo.y = (double)(data->y[0] - y); + + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_MOVE, &minfo); + } + + if (s_info.conf.field.support_gbar && data->is.field.flick_down && abs(data->y[0] - data->down.y) > CLICK_REGION) { + struct widget_evas_event_info info; + data->is.field.flick_down = 0; + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_GBAR_CREATED; + info.error = WIDGET_ERROR_CANCELED; + smart_callback_call(data, WIDGET_SMART_SIGNAL_FLICKDOWN_CANCELLED, &info); + DbgPrint("Flick down is canceled\n"); + } + + } else { + if (s_info.conf.field.auto_render_selector) { + s_info.conf.field.render_animator = 1; + } + } +} + +static char *get_package_icon(struct widget_data *data) +{ + char *icon; + char *uiapp; + + if (data->size_type == WIDGET_SIZE_TYPE_UNKNOWN) { + icon = widget_service_get_icon(data->widget_id, NULL); + } else { + icon = get_preview_image(data, data->size_type); + } + + if (icon && access(icon, R_OK) == 0) { + return icon; + } + + if (icon) { + ErrPrint("Failed to access an icon file: [%s]\n", icon); + free(icon); + icon = NULL; + } + + uiapp = widget_service_get_main_app_id(data->widget_id); + if (uiapp) { + int ret; + pkgmgrinfo_appinfo_h appinfo_h; + + ret = pkgmgrinfo_appinfo_get_appinfo(uiapp, &appinfo_h); + free(uiapp); + + if (ret < 0) { + /** + * 'Icon' will be remained as NULL + */ + } else { + char *uiapp_icon = NULL; + + ret = pkgmgrinfo_appinfo_get_icon(appinfo_h, &uiapp_icon); + if (ret == PMINFO_R_OK && uiapp_icon && access(uiapp_icon, R_OK) == 0) { + DbgPrint("UI-App icon: [%s]\n", uiapp_icon); + icon = strdup(uiapp_icon); + if (!icon) { + ErrPrint("Heap: %d\n", strerror(errno)); + /** + * @note + * 'Icon' will be specified to "unknown" icon file (Default) + */ + } + } else { + ErrPrint("[%s] - %d\n", uiapp_icon, errno); + } + + pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h); + } + } + + if (!icon) { + icon = strdup(WIDGET_VIEWER_EVAS_UNKNOWN); + if (!icon) { + ErrPrint("strdup: %d\n", errno); + } + } + + return icon; +} + +static void activate_ret_cb(struct widget *handle, int ret, void *cbdata) +{ + struct widget_data *data = cbdata; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + __widget_overlay_disable(data, 1, 1); + + DbgPrint("Activated (%s): %d\n", data->widget_id, ret); + if (!data->is.field.deleted && (ret == WIDGET_ERROR_NONE || ret == WIDGET_ERROR_INVALID_PARAMETER)) { + widget_size_type_e type; + Evas_Coord w, h; + struct acquire_data acquire_data = { + .data = data, + }; + + evas_object_geometry_get(data->widget_layout, NULL, NULL, &w, &h); + + type = find_size_type(data, w, h); + if (type == WIDGET_SIZE_TYPE_UNKNOWN) { + ErrPrint("Failed to find a proper size type: %dx%d\n", w, h); + type = WIDGET_SIZE_TYPE_1x1; + } + + data->is.field.faulted = 0; + data->is.field.created = 0; + data->is.field.send_delete = 1; + update_widget_geometry(&acquire_data); + data->handle = widget_viewer_add_widget(data->widget_id, data->content, + data->cluster, data->category, + data->period, type, + __widget_created_cb, widget_ref(data)); + if (!data->handle) { + ErrPrint("Failed to send add request\n"); + widget_unref(data); + return; + } + + DbgPrint("Added Handle: (%p) %p\n", data->handle, data); + widget_viewer_set_data(data->handle, data->widget); + __widget_overlay_loading(data); + } + + data->is.field.deleted = 0; + widget_unref(data); +} + +static void __widget_animation_done_cb(void *cbdata, Evas_Object *obj, const char *signal_name, const char *source) +{ + struct widget_data *data = cbdata; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (widget_viewer_has_glance_bar(data->handle)) { + } else { + DbgPrint("Animation finished\n"); + } +} + +static void __widget_turn_done_cb(void *cbdata, Evas_Object *obj, const char *signal_name, const char *source) +{ + struct widget_data *data = cbdata; + Evas_Object *overlay; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + overlay = elm_object_part_content_unset(data->widget_layout, "overlay,content"); + if (overlay) { + evas_object_del(overlay); + data->is.field.widget_overlay_loaded = 0; + } +} + +static void __widget_overlay_clicked_cb(void *cbdata, Evas_Object *obj, const char *signal_name, const char *source) +{ + struct widget_data *data = cbdata; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + DbgPrint("Overlay is clicked: (%s) (%s)\n", signal_name, source); + if (!data->is.field.faulted) { + /*! + * \todo + * Reload + */ + DbgPrint("Package [%s] is not faulted one\n", data->widget_id); + } else { + DbgPrint("Activate: [%s]\n", data->widget_id); + if (widget_viewer_activate_faulted_widget(data->widget_id, activate_ret_cb, widget_ref(data)) < 0) { + ErrPrint("Failed to activate %s\n", data->widget_id); + widget_unref(data); + } + } +} + +static void __widget_data_setup(struct widget_data *data) +{ + data->e = evas_object_evas_get(data->widget); + if (!data->e) { + ErrPrint("Failed to get Evas object\n"); + data->state = WIDGET_DATA_DELETED; + free(data); + return; + } + + data->stage = evas_object_rectangle_add(data->e); + if (!data->stage) { + ErrPrint("Failed to add stage object\n"); + data->state = WIDGET_DATA_DELETED; + free(data); + return; + } + + evas_object_color_set(data->stage, 255, 255, 255, 255); + + data->widget_layout = elm_layout_add(data->parent); + if (!data->widget_layout) { + ErrPrint("Failed to add edje object\n"); + evas_object_del(data->stage); + data->state = WIDGET_DATA_DELETED; + free(data); + return; + } + + if (elm_layout_file_set(data->widget_layout, WIDGET_VIEWER_EVAS_RESOURCE_EDJ, WIDGET_VIEWER_EVAS_RESOURCE_LB) == EINA_FALSE) { + ErrPrint("Failed to load edje object: %s(%s)\n", WIDGET_VIEWER_EVAS_RESOURCE_EDJ, WIDGET_VIEWER_EVAS_RESOURCE_LB); + evas_object_del(data->widget_layout); + evas_object_del(data->stage); + data->state = WIDGET_DATA_DELETED; + free(data); + return; + } + + if (s_info.conf.field.is_scroll_x || s_info.conf.field.is_scroll_y) { + Evas_Object *scroller; + scroller = elm_scroller_add(data->parent); + if (scroller) { + Evas_Object *box; + + elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_FALSE); + elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + elm_scroller_single_direction_set(scroller, ELM_SCROLLER_SINGLE_DIRECTION_HARD); + /* elm_object_scroll_lock_x_set(scroller, EINA_TRUE); */ + + box = evas_object_rectangle_add(data->e); + if (box) { + int height = 0; + int width = 0; + + if (s_info.conf.field.is_scroll_x) { + height = s_info.screen_height << 1; + } + + if (s_info.conf.field.is_scroll_y) { + width = s_info.screen_width << 1; + } + + evas_object_color_set(box, 0, 0, 0, 0); + evas_object_resize(box, width, height); + evas_object_size_hint_min_set(box, width, height); + evas_object_show(box); + } + + elm_object_content_set(scroller, box); + elm_object_part_content_set(data->widget_layout, "scroller", scroller); + } else { + ErrPrint("Failed to create a scroller\n"); + } + } + + evas_object_show(data->widget_layout); + + elm_object_signal_callback_add(data->widget_layout, "mouse,clicked,1", "overlay,content", __widget_overlay_clicked_cb, data); + elm_object_signal_callback_add(data->widget_layout, "done", "turn", __widget_turn_done_cb, data); + elm_object_signal_callback_add(data->widget_layout, "finished", "animation", __widget_animation_done_cb, data); + + evas_object_event_callback_add(data->widget_layout, EVAS_CALLBACK_MOUSE_DOWN, __widget_down_cb, data); + evas_object_event_callback_add(data->widget_layout, EVAS_CALLBACK_MOUSE_MOVE, __widget_move_cb, data); + evas_object_event_callback_add(data->widget_layout, EVAS_CALLBACK_MOUSE_UP, __widget_up_cb, data); + + evas_object_event_callback_add(data->widget_layout, EVAS_CALLBACK_MULTI_DOWN, __widget_multi_down_cb, data); + evas_object_event_callback_add(data->widget_layout, EVAS_CALLBACK_MULTI_MOVE, __widget_multi_move_cb, data); + evas_object_event_callback_add(data->widget_layout, EVAS_CALLBACK_MULTI_UP, __widget_multi_up_cb, data); + + evas_object_smart_member_add(data->stage, data->widget); + evas_object_smart_member_add(data->widget_layout, data->widget); + evas_object_clip_set(data->widget_layout, data->stage); + +} + +static Eina_Bool renderer_cb(void *_data) +{ + struct widget_data *data; + + EINA_LIST_FREE(s_info.widget_dirty_objects, data) { + __widget_event_widget_updated(data); + } + + EINA_LIST_FREE(s_info.gbar_dirty_objects, data) { + __widget_event_gbar_updated(data); + } + + s_info.renderer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static void remove_widget_dirty_object_list(struct widget_data *data) +{ + s_info.widget_dirty_objects = eina_list_remove(s_info.widget_dirty_objects, data); +} + +static void append_widget_dirty_object_list(struct widget_data *data, int idx) +{ + data->is.field.widget_dirty = 1; + + if (idx != WIDGET_KEEP_BUFFER) { + data->widget_latest_idx = idx; + } + + if (widget_viewer_get_visibility(data->handle) != WIDGET_SHOW) { + DbgPrint("Box is not visible\n"); + return; + } + + if (s_info.conf.field.render_animator) { + if (eina_list_data_find(s_info.widget_dirty_objects, data)) { + return; + } + + if (!s_info.renderer) { + s_info.renderer = ecore_animator_add(renderer_cb, NULL); + if (!s_info.renderer) { + ErrPrint("Failed to create a renderer\n"); + } + } + + s_info.widget_dirty_objects = eina_list_append(s_info.widget_dirty_objects, data); + } else { + if (s_info.renderer) { + ecore_animator_del(s_info.renderer); + s_info.renderer = NULL; + } + + /* Need a choice + * Do we have to discard these all changes? or just flush them? + struct widget_data *item; + EINA_LIST_FREE(s_info.widget_dirty_objects, item) { + __widget_event_widget_updated(item); + } + */ + eina_list_free(s_info.widget_dirty_objects); + s_info.widget_dirty_objects = NULL; + __widget_event_widget_updated(data); + } +} + +static void remove_gbar_dirty_object_list(struct widget_data *data) +{ + s_info.gbar_dirty_objects = eina_list_remove(s_info.gbar_dirty_objects, data); +} + +static void append_gbar_dirty_object_list(struct widget_data *data, int idx) +{ + data->is.field.gbar_dirty = 1; + + if (idx != WIDGET_KEEP_BUFFER) { + data->gbar_latest_idx = idx; + } + + if (widget_viewer_get_visibility(data->handle) != WIDGET_SHOW) { + return; + } + + if (s_info.conf.field.render_animator) { + if (eina_list_data_find(s_info.gbar_dirty_objects, data)) { + return; + } + + if (!s_info.renderer) { + s_info.renderer = ecore_animator_add(renderer_cb, NULL); + if (!s_info.renderer) { + ErrPrint("Failed to create a renderer\n"); + } + } + + s_info.gbar_dirty_objects = eina_list_append(s_info.gbar_dirty_objects, data); + } else { + if (s_info.renderer) { + ecore_animator_del(s_info.renderer); + s_info.renderer = NULL; + } + + /* Need a choice + * Do we have to discard these all changes? or just flush them? + struct widget_data *item; + EINA_LIST_FREE(s_info.gbar_dirty_objects, item) { + __widget_event_gbar_updated(item); + } + */ + eina_list_free(s_info.gbar_dirty_objects); + s_info.gbar_dirty_objects = NULL; + __widget_event_gbar_updated(data); + } +} + +static void __widget_add(Evas_Object *widget) +{ + struct widget_data *data; + + data = calloc(1, sizeof(*data)); + if (!data) { + ErrPrint("Heap: %d\n", errno); + return; + } + + data->state = WIDGET_DATA_CREATED; + data->widget = widget; + data->is.field.permanent_delete = 0; + data->widget_latest_idx = WIDGET_PRIMARY_BUFFER; + data->gbar_latest_idx = WIDGET_PRIMARY_BUFFER; + evas_object_smart_data_set(data->widget, data); + widget_ref(data); + + s_info.list = eina_list_append(s_info.list, widget); + return; +} + +static Evas_Object *create_image_object(struct widget_data *data) +{ + Evas_Object *img; + + img = evas_object_image_filled_add(data->e); + if (!img) { + ErrPrint("Failed to create an image object\n"); + } else { + evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888); + evas_object_image_alpha_set(img, EINA_TRUE); + } + + return img; +} + +static void replace_widget_pixmap_with_image(struct widget_data *data) +{ + Evas_Object *img; + Evas_Object *content; + + content = elm_object_part_content_unset(data->widget_layout, "widget,content"); + if (!content) { + ErrPrint("Failed to get content object\n"); + return; + } + + img = create_image_object(data); + if (img) { + Evas_Coord w; + Evas_Coord h; + void *image_data; + + evas_object_image_size_get(content, &w, &h); + evas_object_image_size_set(img, w, h); + + image_data = evas_object_image_data_get(content, 0); + if (image_data) { + evas_object_image_data_copy_set(img, image_data); + } + + evas_object_image_fill_set(img, 0, 0, w, h); + evas_object_image_pixels_dirty_set(img, EINA_TRUE); + evas_object_image_data_update_add(img, 0, 0, w, h); + + elm_object_part_content_set(data->widget_layout, "widget,content", img); + } else { + ErrPrint("Failed to create an image object\n"); + } + + evas_object_del(content); +} + +static void replace_gbar_pixmap_with_image(struct widget_data *data) +{ + Evas_Object *img; + Evas_Object *gbar_content; + + gbar_content = elm_object_part_content_unset(data->widget_layout, "gbar,content"); + if (!gbar_content) { + ErrPrint("Failed to get content object\n"); + return; + } + + img = create_image_object(data); + if (img) { + Evas_Coord w; + Evas_Coord h; + void *content; + + evas_object_image_size_get(gbar_content, &w, &h); + evas_object_image_size_set(img, w, h); + + content = evas_object_image_data_get(gbar_content, 0); + if (content) { + evas_object_image_data_copy_set(img, content); + } + + evas_object_image_fill_set(img, 0, 0, w, h); + evas_object_image_pixels_dirty_set(img, EINA_TRUE); + evas_object_image_data_update_add(img, 0, 0, w, h); + + elm_object_part_content_set(data->widget_layout, "gbar,content", img); + } else { + ErrPrint("Failed to create an image object\n"); + } + + evas_object_del(gbar_content); +} + +static void __widget_destroy_widget_cb(widget_h handle, int ret, void *_data) +{ + struct widget_data *data = _data; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (data->widget_pixmap) { + replace_widget_pixmap_with_image(data); + } + + if (data->gbar_pixmap) { + replace_gbar_pixmap_with_image(data); + } + + data->is.field.send_delete = 0; + DbgPrint("Invoke raw delete %s\n", data->widget_id); + (void)invoke_raw_event_callback(WIDGET_VIEWER_EVAS_RAW_DELETE, data->widget_id, NULL, ret); + remove_widget_dirty_object_list(data); + remove_gbar_dirty_object_list(data); /* for the safety */ + widget_unref(data); +} + +static void __widget_del(Evas_Object *widget) +{ + struct widget_data *data = NULL; + + data = evas_object_smart_data_get(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (data->is.field.deleted == 1) { + DbgPrint("Already deleted: %s\n", data->widget_id); + return; + } + + data->is.field.deleted = 1; + + if (data->delayed_resume_timer) { + ecore_timer_del(data->delayed_resume_timer); + data->delayed_resume_timer = NULL; + } + + s_info.list = eina_list_remove(s_info.list, widget); + + if (data->handle) { + widget_viewer_set_data(data->handle, NULL); + + if (data->is.field.send_delete) { + widget_delete_type_e delete_type; + + if (data->is.field.permanent_delete) { + delete_type = WIDGET_DELETE_PERMANENTLY; + } else { + delete_type = WIDGET_DELETE_TEMPORARY; + } + DbgPrint("Send delete request (0x%X)\n", delete_type); + + if (data->is.field.created) { + if (widget_viewer_delete_widget(data->handle, delete_type, __widget_destroy_widget_cb, widget_ref(data)) < 0) { + widget_unref(data); + data = NULL; + } + } else { + DbgPrint("Not created yet. this will be canceld by created callback, ignore delete callback\n"); + if (widget_viewer_delete_widget(data->handle, delete_type, NULL, NULL) < 0) { + DbgPrint("Unref %p\n", data); + } + } + } else { + DbgPrint("Skip delete request\n"); + } + } else { + DbgPrint("Handle is not created: %s\n", data->widget_id); + if (data->is.field.faulted && data->widget_id) { + /* If a package is faulted. we have to activate it before delete object from here */ + if (widget_viewer_activate_faulted_widget(data->widget_id, NULL, NULL) < 0) { + ErrPrint("Activate: %s\n", data->widget_id); + } + } + } + + /** + * From now, the widget object is not valid + */ + if (data) { + data->widget = NULL; + widget_unref(data); + } +} + +static Eina_Bool delayed_resume_timer_cb(void *_data) +{ + struct widget_data *data = _data; + + (void)widget_viewer_set_visibility(data->handle, WIDGET_SHOW); + + if (data->is.field.widget_dirty) { + /** + * If the object has dirty flag, pumping it up again + * To updates its content + */ + append_widget_dirty_object_list(data, WIDGET_KEEP_BUFFER); + } + + data->delayed_resume_timer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static void update_visibility(struct widget_data *data) +{ + int is_visible = 0; + int delay; + + if (!data->handle || !data->is.field.created) { + return; + } + + if (data->is.field.freeze_visibility) { + DbgPrint("Freezed visibility: %X (%s)\n", data->freezed_visibility, widget_viewer_get_pkgname(data->handle)); + + if (data->freezed_visibility == WIDGET_VISIBILITY_STATUS_SHOW_FIXED) { + if (data->delayed_resume_timer) { + (void)ecore_timer_del(data->delayed_resume_timer); + data->delayed_resume_timer = NULL; + } + data->is.field.initial_resumed = 1; + (void)widget_viewer_set_visibility(data->handle, WIDGET_SHOW); + } else if (data->freezed_visibility == WIDGET_VISIBILITY_STATUS_HIDE_FIXED) { + if (data->delayed_resume_timer) { + (void)ecore_timer_del(data->delayed_resume_timer); + data->delayed_resume_timer = NULL; + } + (void)widget_viewer_set_visibility(data->handle, WIDGET_HIDE_WITH_PAUSE); + } + return; + } + + is_visible = evas_object_visible_get(data->stage); + + if (is_visible) { + Evas_Coord x, y, w, h; + + evas_object_geometry_get(data->widget_layout, &x, &y, &w, &h); + + if (!s_info.conf.field.user_view_port) { + Ecore_Evas *ee; + + ee = ecore_evas_ecore_evas_get(data->e); + if (ee) { + ecore_evas_geometry_get(ee, &data->view_port.x, &data->view_port.y, &data->view_port.w, &data->view_port.h); + } else { + data->view_port.x = 0; + data->view_port.y = 0; + util_screen_size_get(&data->view_port.w, &data->view_port.h); + ErrPrint("Failed to get view port info (Fallback: %dx%d - %dx%d\n", + data->view_port.x, data->view_port.y, data->view_port.w, data->view_port.h); + } + } + + if (x + w <= data->view_port.x || x >= data->view_port.x + data->view_port.w || y + h <= data->view_port.y || y >= data->view_port.y + data->view_port.h) { + is_visible = 0; + } else { + is_visible = 1; + } + } + + if (data->is.field.delayed_resume == 0) { /* Follow the global configuration */ + delay = s_info.conf.field.delayed_resume; + } else { /* Ignore the global configuration */ + /* 1 : Disable Delayed Pause Resume */ + /* 2 : Enable Delayed Pause Resume */ + delay = (data->is.field.delayed_resume == 2); + } + + if (delay) { + if (is_visible) { + if (data->delayed_resume_timer) { + DbgPrint("Reset timer\n"); + ecore_timer_reset(data->delayed_resume_timer); + } else if (WIDGET_CONF_VISIBILITY_CHANGE_DELAY > 0.0f) { + if (data->is.field.initial_resumed == 0) { + /** + * @note + * If a widget is not resumed before, + * it should be resumed immediately for displaying its contents ASAP. + */ + DbgPrint("First immeidiate resume\n"); + data->is.field.initial_resumed = 1; + delayed_resume_timer_cb(data); + } else { + DbgPrint("Delayed resume (%lf)\n", WIDGET_CONF_VISIBILITY_CHANGE_DELAY); + data->delayed_resume_timer = ecore_timer_add(WIDGET_CONF_VISIBILITY_CHANGE_DELAY, delayed_resume_timer_cb, data); + if (!data->delayed_resume_timer) { + ErrPrint("Failed to add a timer\n"); + delayed_resume_timer_cb(data); + } + } + } else { + delayed_resume_timer_cb(data); + } + } else { + if (data->delayed_resume_timer) { + ecore_timer_del(data->delayed_resume_timer); + data->delayed_resume_timer = NULL; + } + + widget_viewer_set_visibility(data->handle, WIDGET_HIDE_WITH_PAUSE); + } + } else { + /** + * @note + * In this case, if there is any registered timer, + * this function should clear it. + * Timer means that the delayed_resume mode is changed. + */ + if (data->delayed_resume_timer) { + ecore_timer_del(data->delayed_resume_timer); + data->delayed_resume_timer = NULL; + DbgPrint("Clear timer of delayed resuming\n"); + } + + if (is_visible) { + delayed_resume_timer_cb(data); + } else { + widget_viewer_set_visibility(data->handle, WIDGET_HIDE_WITH_PAUSE); + } + } +} + +static int do_force_mouse_up(struct widget_data *data) +{ + struct widget_mouse_event_info minfo; + Evas_Coord x, y, w, h; + struct widget_evas_event_info info; + int i; + + if (s_info.conf.field.auto_render_selector && s_info.conf.field.render_animator == 0) { + DbgPrint("Change to render animator\n"); + s_info.conf.field.render_animator = 1; + } + + if (!data->pressed) { + /** + * @note + * No buttons are pressed or there is no touch. + */ + return WIDGET_ERROR_INVALID_PARAMETER; + } + + /** + * @todo + * What happens if this is called for GBar? + */ + evas_object_geometry_get(data->widget, &x, &y, &w, &h); + + /** + * @note + * If the GBar is pressed, we don't need to calculate the ratio. + */ + if (!data->down.is_gbar && (data->size_type != WIDGET_SIZE_TYPE_UNKNOWN && !s_info.conf.field.use_fixed_size)) { + minfo.ratio_w = (double)data->fixed_width / (double)w; + minfo.ratio_h = (double)data->fixed_height / (double)h; + DbgPrint("Width: %d/%d - Height: %d/%d\n", data->fixed_width, w, data->fixed_height, h); + } else { + minfo.ratio_w = 1.0f; + minfo.ratio_h = 1.0f; + } + DbgPrint("Ratio: %lfx%lf\n", minfo.ratio_w, minfo.ratio_h); + + DbgPrint("%x\n", data->is.field.cancel_click); + if (data->is.field.cancel_click != CANCEL_PROCESSED) { + DbgPrint("ON_HOLD send\n"); + minfo.device = 0; + minfo.x = (double)(data->x[0] - x); + minfo.y = (double)(data->y[0] - y); + + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_ON_HOLD, &minfo); + data->is.field.cancel_click = CANCEL_PROCESSED; + } + + reset_scroller(data); + + if (s_info.conf.field.auto_feed && data->is.field.mouse_event) { + for (i = 0; i < MAX_DEVICE; i++) { + if (IS_PRESSED(data, i)) { + /** + * @note + * UNSET will subtract object.x and object.y by master + * so we just send original touch position based on screen + */ + minfo.x = (double)data->x[i]; + minfo.y = (double)data->y[i]; + DbgPrint("X,Y = %lfx%lf\n", minfo.x, minfo.y); + minfo.device = i; + + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_UNSET, &minfo); + } + } + } else { + DbgPrint("%lfx%lf (%lfx%lf)\n", minfo.x, minfo.y, minfo.ratio_w, minfo.ratio_h); + for (i = 0; i < MAX_DEVICE; i++) { + if (IS_PRESSED(data, i)) { + minfo.x = (double)(data->x[i] - x); + minfo.y = (double)(data->y[i] - y); + minfo.device = i; + + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_UP, &minfo); + widget_viewer_feed_mouse_event(data->handle, WIDGET_MOUSE_LEAVE, &minfo); + } + } + } + + data->pressed = 0; + data->is.field.cancel_click = CANCEL_DISABLED; + + if (s_info.conf.field.support_gbar && data->is.field.flick_down) { + data->is.field.flick_down = 0; + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_GBAR_CREATED; + info.error = WIDGET_ERROR_CANCELED; + smart_callback_call(data, WIDGET_SMART_SIGNAL_FLICKDOWN_CANCELLED, &info); + DbgPrint("Flick down is canceled\n"); + } + + return WIDGET_ERROR_NONE; +} + +static void __widget_move(Evas_Object *widget, Evas_Coord x, Evas_Coord y) +{ + struct widget_data *data; + Evas_Coord w, h; + + data = evas_object_smart_data_get(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (data->gbar_layout) { + Evas_Coord gbar_x, gbar_y, gbar_h; + Evas_Coord prev_x, prev_y; + Evas_Coord widget_w, widget_h; + double rx; + double ry; + + evas_object_geometry_get(data->widget_layout, &prev_x, &prev_y, &widget_w, &widget_h); + evas_object_geometry_get(data->gbar_layout, &gbar_x, &gbar_y, NULL, &gbar_h); + + gbar_x += (x - prev_x); + gbar_y += (y - prev_y); + + evas_object_move(data->gbar_layout, gbar_x, gbar_y); + + rx = ((double)x + (double)widget_w / 2.0f) / s_info.screen_width; + switch (find_size_type(data, widget_w, widget_h)) { + case WIDGET_SIZE_TYPE_1x1: + if (rx < 0.25f) { + rx = 0.125f; + } else if (rx < 0.5f) { + rx = 0.375f; + } else if (rx < 0.75f) { + rx = 0.625f; + } else if (rx < 1.0f) { + rx = 0.875f; + } + break; + case WIDGET_SIZE_TYPE_2x1: + case WIDGET_SIZE_TYPE_2x2: + if (rx < 0.5f) { + rx = 0.25f; + } else if (rx < 0.75f) { + rx = 0.5f; + } else { + rx = 0.75f; + } + break; + default: + rx = 0.5f; + break; + } + + if (prev_y + widget_h + gbar_h > s_info.screen_height) { + ry = 1.0f; + } else { + ry = 0.0f; + } + + if (data->is.field.gbar_created) { + widget_viewer_move_glance_bar(data->handle, rx, ry); + } + } + + evas_object_move(data->stage, x, y); + evas_object_move(data->widget_layout, x, y); + evas_object_geometry_get(data->widget_layout, NULL, NULL, &w, &h); + + if (!s_info.conf.field.manual_pause_resume) { + update_visibility(data); + } + + if (s_info.conf.field.sensitive_move) { + do_force_mouse_up(data); + } +} + +static int widget_create_plug_object(struct widget_data *data) +{ + struct acquire_data acquire_data = { + .w = 0, + .h = 0, + .content = NULL, + .data = data, + }; + + DbgPrint("Plug type created\n"); + + acquire_data.content = elm_object_part_content_unset(data->widget_layout, "widget,content"); + if (acquire_data.content) { + DbgPrint("widget Content is already prepared: %s\n", widget_viewer_get_filename(data->handle)); + evas_object_del(acquire_data.content); + } + + acquire_data.content = elm_plug_add(s_info.win); + if (!acquire_data.content) { + ErrPrint("Failed to add a plug object\n"); + return WIDGET_ERROR_FAULT; + } + + DbgPrint("Try to connect to %s\n", widget_viewer_get_filename(data->handle)); + if (!elm_plug_connect(acquire_data.content, widget_viewer_get_filename(data->handle), 0, EINA_TRUE)) { + ErrPrint("Cannot connect plug[%s]", widget_viewer_get_filename(data->handle)); + evas_object_del(acquire_data.content); + return WIDGET_ERROR_FAULT; + } + + elm_object_part_content_set(data->widget_layout, "widget,content", acquire_data.content); + + acquire_data.w = data->widget_width; + acquire_data.h = data->widget_height; + update_widget_geometry(&acquire_data); + return WIDGET_ERROR_NONE; +} + +static int widget_create_image_object(struct widget_data *data) +{ + Evas_Object *front_image; + struct acquire_data acquire_data = { + .w = 0, + .h = 0, + .content = NULL, + .data = data, + }; + + DbgPrint("Image type created\n"); + + acquire_data.content = elm_object_part_content_get(data->widget_layout, "widget,content"); + if (!acquire_data.content) { + acquire_data.content = elm_layout_add(data->parent); + if (!acquire_data.content) { + ErrPrint("Failed to create an edje object\n"); + return WIDGET_ERROR_FAULT; + } + + if (elm_layout_file_set(acquire_data.content, WIDGET_VIEWER_EVAS_RESOURCE_EDJ, WIDGET_VIEWER_EVAS_RESOURCE_IMG) == EINA_FALSE) { + ErrPrint("Failed to load edje object: %s(%s)\n", WIDGET_VIEWER_EVAS_RESOURCE_EDJ, WIDGET_VIEWER_EVAS_RESOURCE_IMG); + evas_object_del(acquire_data.content); + return WIDGET_ERROR_IO_ERROR; + } + + front_image = elm_image_add(acquire_data.content); + if (!front_image) { + ErrPrint("Failed to add front_image object\n"); + evas_object_del(acquire_data.content); + return WIDGET_ERROR_FAULT; + } + + DbgPrint("Default size %dx%d\n", data->widget_width, data->widget_height); + + elm_object_part_content_set(acquire_data.content, "front,content", front_image); + elm_object_part_content_set(data->widget_layout, "widget,content", acquire_data.content); + } else { + front_image = elm_object_part_content_get(acquire_data.content, "front,content"); + if (!front_image) { + ErrPrint("Unable to get front,content object\n"); + front_image = elm_image_add(acquire_data.content); + if (!front_image) { + ErrPrint("Failed to add front_image object\n"); + return WIDGET_ERROR_FAULT; + } + + elm_object_part_content_set(acquire_data.content, "front,content", front_image); + } + } + + /* + evas_object_geometry_get(data->widget, NULL, NULL, &acquire_data.w, &acquire_data.h); + DbgPrint("Default size %dx%d\n", acquire_data.w, acquire_data.h); + DbgPrint("Image size: %dx%d\n", acquire_data.w, acquire_data.h); + */ + acquire_data.w = data->widget_width; + acquire_data.h = data->widget_height; + update_widget_geometry(&acquire_data); + return WIDGET_ERROR_NONE; +} + +static int widget_create_buffer_object(struct widget_data *data) +{ + Evas_Object *content; + + content = elm_object_part_content_get(data->widget_layout, "widget,content"); + if (!content) { + content = evas_object_image_filled_add(data->e); + if (!content) { + ErrPrint("Failed to create an image object\n"); + return WIDGET_ERROR_FAULT; + } + + evas_object_image_colorspace_set(content, EVAS_COLORSPACE_ARGB8888); + evas_object_image_alpha_set(content, EINA_TRUE); + elm_object_part_content_set(data->widget_layout, "widget,content", content); + } + + return WIDGET_ERROR_NONE; +} + +static int widget_text_update_begin(widget_h handle) +{ + struct widget_data *data; + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + DbgPrint("Begin text update: [%s]\n", data->widget_id); + + return WIDGET_ERROR_NONE; +} + +static int widget_text_update_end(widget_h handle) +{ + struct widget_data *data; + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + DbgPrint("End text update: [%s]\n", data->widget_id); + + return WIDGET_ERROR_NONE; +} + +static int widget_text_update_text(widget_h handle, const char *id, const char *part, const char *data) +{ + struct widget_data *widget_data; + Evas_Object *layout; + + widget_data = get_smart_data_from_handle(handle); + if (!widget_data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(widget_data, 0, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_update_text(widget_data->parent, layout, part, data); +} + +static int widget_text_update_image(widget_h handle, const char *id, const char *part, const char *data, const char *option) +{ + struct widget_data *widget_data; + Evas_Object *layout; + + widget_data = get_smart_data_from_handle(handle); + if (!widget_data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(widget_data, 0, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_update_image(layout, part, data, option); +} + +static int widget_text_update_script(widget_h handle, const char *id, const char *new_id, const char *part, const char *file, const char *group) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 0, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_update_script(data, 0, layout, new_id, part, file, group); +} + +static int widget_text_update_signal(widget_h handle, const char *id, const char *signal_name, const char *signal) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 0, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + elm_object_signal_emit(layout, signal, signal_name); + return WIDGET_ERROR_NONE; +} + +static int widget_text_update_drag(widget_h handle, const char *id, const char *part, double dx, double dy) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 0, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + edje_object_part_drag_value_set(elm_layout_edje_get(layout), part, dx, dy); + return WIDGET_ERROR_NONE; +} + +static int widget_text_update_info_size(widget_h handle, const char *id, int w, int h) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 0, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + DbgPrint("Resize to %dx%d\n", w, h); + evas_object_resize(layout, w, h); + + return WIDGET_ERROR_NONE; +} + +static int widget_text_update_info_category(widget_h handle, const char *id, const char *category) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 0, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + DbgPrint("Update category: %s\n", category); + + return WIDGET_ERROR_NONE; +} + +static int widget_text_update_access(widget_h handle, const char *id, const char *part, const char *text, const char *option) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 0, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_update_access(data->parent, layout, part, text, option); +} + +static int widget_text_operate_access(widget_h handle, const char *id, const char *part, const char *operation, const char *option) +{ + struct widget_data *data; + Evas_Object *layout; + + data = get_smart_data_from_handle(handle); + if (!data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(data, 0, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_operate_access(layout, part, operation, option); +} + +static int widget_text_update_color(widget_h handle, const char *id, const char *part, const char *data) +{ + struct widget_data *widget_data; + Evas_Object *layout; + + widget_data = get_smart_data_from_handle(handle); + if (!widget_data) { + return WIDGET_ERROR_FAULT; + } + + layout = find_script_object(widget_data, 0, id); + if (!layout) { + ErrPrint("Target[%s] is not exists\n", id); + return WIDGET_ERROR_NOT_EXIST; + } + + return do_text_update_color(layout, part, data); +} +static int widget_create_text_object(struct widget_data *data) +{ + Evas_Object *content; + + content = elm_object_part_content_get(data->widget_layout, "widget,content"); + if (!content) { + int ret; + char *script_file; + char *script_group; + struct widget_script_operators operator = { + .update_begin = widget_text_update_begin, + .update_end = widget_text_update_end, + + .update_text = widget_text_update_text, + .update_image = widget_text_update_image, + .update_script = widget_text_update_script, + .update_signal = widget_text_update_signal, + .update_drag = widget_text_update_drag, + .update_info_size = widget_text_update_info_size, + .update_info_category = widget_text_update_info_category, + .update_access = widget_text_update_access, + .operate_access = widget_text_operate_access, + .update_color = widget_text_update_color, + }; + + content = elm_layout_add(data->widget_layout); + if (!content) { + ErrPrint("Failed to create a layout object\n"); + return WIDGET_ERROR_FAULT; + } + + script_file = widget_service_get_widget_script_path(data->widget_id); + script_group = widget_service_get_widget_script_group(data->widget_id); + if (!script_file || !script_group) { + ErrPrint("Invalid script info ([%s] - [%s])\n", script_file, script_group); + free(script_file); + free(script_group); + evas_object_del(content); + return WIDGET_ERROR_FAULT; + } + + if (access(script_file, R_OK) != 0) { + ErrPrint("Unable to access [%s] - %d\n", script_file, errno); + free(script_file); + free(script_group); + evas_object_del(content); + return WIDGET_ERROR_FAULT; + } + + ret = elm_layout_file_set(content, script_file, script_group); + DbgPrint("Load edje file ([%s] - [%s])\n", script_file, script_group); + free(script_file); + free(script_group); + if (ret == EINA_FALSE) { + ErrPrint("Failed to load EDJE\n"); + evas_object_del(content); + return WIDGET_ERROR_FAULT; + } + + ret = widget_viewer_set_text_handler(data->handle, 0, &operator); + if (ret != WIDGET_ERROR_NONE) { + ErrPrint("Failed to set text handler for [%s]\n", data->widget_id); + evas_object_del(content); + return ret; + } + + ret = append_script_object(data, 0, NULL, NULL, content); + if (ret != WIDGET_ERROR_NONE) { + ErrPrint("Failed to append this to script object list\n"); + evas_object_del(content); + return ret; + } + + elm_object_part_content_set(data->widget_layout, "widget,content", content); + } + + return WIDGET_ERROR_NONE; +} + +static int widget_create_pixmap_object(struct widget_data *data) +{ + Evas_Object *content; + + content = elm_object_part_content_get(data->widget_layout, "widget,content"); + if (!content) { + content = evas_object_image_filled_add(data->e); + if (!content) { + ErrPrint("Failed to create an image object\n"); + return WIDGET_ERROR_FAULT; + } + + evas_object_image_colorspace_set(content, EVAS_COLORSPACE_ARGB8888); + evas_object_image_alpha_set(content, EINA_TRUE); + evas_object_event_callback_add(content, EVAS_CALLBACK_DEL, __widget_pixmap_del_cb, data); + + elm_object_part_content_set(data->widget_layout, "widget,content", content); + } + + return WIDGET_ERROR_NONE; +} + +static void __widget_resize_pixmap_object(struct widget_data *data) +{ + DbgPrint("widget resize request is succssfully sent\n"); +} + +static void update_widget_pixmap(Evas_Object *content, int w, int h) +{ + evas_object_image_pixels_dirty_set(content, EINA_TRUE); + evas_object_image_data_update_add(content, 0, 0, w, h); + evas_object_show(content); +} + +static void acquire_widget_extra_resource_cb(struct widget *handle, int pixmap, void *cbdata) +{ + DbgPrint("Acquired: %u\n", (unsigned int)pixmap); +} + +static void acquire_gbar_extra_resource_cb(struct widget *handle, int pixmap, void *cbdata) +{ + DbgPrint("Acquired: %u\n", (unsigned int)pixmap); +} + +static void replace_pixmap(struct widget *handle, int gbar, Evas_Object *content, unsigned int pixmap) +{ + unsigned int old_pixmap; + + old_pixmap = util_replace_native_surface(handle, gbar, content, pixmap); + if (!s_info.conf.field.skip_acquire && old_pixmap != 0u) { + widget_viewer_release_resource_id(handle, gbar, old_pixmap); + } +} + +static void acquire_widget_pixmap_cb(struct widget *handle, int pixmap, void *cbdata) +{ + struct acquire_data *acquire_data = cbdata; + struct widget_data *data = acquire_data->data; + + data->is.field.widget_pixmap_acquire_requested = 0; + __widget_overlay_disable(data, 0, 0); + + if (pixmap == 0) { + DbgPrint("Pixmap gotten (0)\n"); + if (!s_info.conf.field.skip_acquire) { + free(acquire_data); + } + widget_unref(data); + return; + } + + evas_object_image_size_set(acquire_data->content, acquire_data->w, acquire_data->h); + evas_object_image_fill_set(acquire_data->content, 0, 0, acquire_data->w, acquire_data->h); + DbgPrint("fillset: %dx%d\n", acquire_data->w, acquire_data->h); + + replace_pixmap(handle, 0, acquire_data->content, (unsigned int)pixmap); + + data->widget_pixmap = pixmap; + + append_widget_dirty_object_list(data, WIDGET_KEEP_BUFFER); + update_widget_geometry(acquire_data); + + widget_unref(data); + if (!s_info.conf.field.skip_acquire) { + free(acquire_data); + } +} + +static void __widget_update_pixmap_object(struct widget_data *data, Evas_Object *widget_content, int w, int h) +{ + int ret; + struct acquire_data *acquire_data; + + if (data->widget_latest_idx == WIDGET_PRIMARY_BUFFER) { + unsigned int resource_id; + + widget_viewer_get_resource_id(data->handle, 0, &resource_id); + if (data->widget_pixmap == resource_id) { + if (data->widget_extra) { + /* Just replace the pixmap in this case, do not release old pixmap */ + replace_pixmap(NULL, 0, widget_content, data->widget_pixmap); + } + + update_widget_pixmap(widget_content, w, h); + return; + } + + if (s_info.conf.field.skip_acquire && resource_id != 0) { + struct acquire_data local_acquire_data = { + .data = widget_ref(data), + .content = widget_content, + .w = w, + .h = h, + }; + + acquire_widget_pixmap_cb(data->handle, resource_id, &local_acquire_data); + return; + } + + if (data->is.field.widget_pixmap_acquire_requested) { + DbgPrint("Pixmap is not acquired\n"); + return; + } + + acquire_data = malloc(sizeof(*acquire_data)); + if (!acquire_data) { + ErrPrint("malloc: %d\n", errno); + return; + } + + acquire_data->data = widget_ref(data); + acquire_data->content = widget_content; + acquire_data->w = w; + acquire_data->h = h; + + ret = widget_viewer_acquire_resource_id(data->handle, 0, acquire_widget_pixmap_cb, acquire_data); + if (ret != WIDGET_ERROR_NONE) { + widget_unref(data); + free(acquire_data); + } else { + data->is.field.widget_pixmap_acquire_requested = 1; + } + } else { + if (!data->widget_extra) { + ErrPrint("Extra buffer is not prepared yet\n"); + return; + } + + replace_pixmap(NULL, 0, widget_content, data->widget_extra[data->widget_latest_idx]); + update_widget_pixmap(widget_content, w, h); + } +} + +static int widget_system_created(struct widget *handle, struct widget_data *data) +{ + int ret; + struct widget_evas_event_info info; + widget_type_e widget_type; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p, %s\n", data, widget_viewer_get_pkgname(handle)); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + widget_viewer_get_size_type(handle, &data->size_type); + + if (data->size_type == WIDGET_SIZE_TYPE_UNKNOWN || widget_service_get_size(data->size_type, &data->widget_width, &data->widget_height) < 0) { + ErrPrint("Failed to get size info: %s\n", widget_viewer_get_pkgname(handle)); + + } else { + DbgPrint("System created WIDGET size is (%d)%dx%d\n", data->size_type, data->widget_width, data->widget_height); + } + + widget_viewer_get_type(handle, 0, &widget_type); + + switch (widget_type) { + case WIDGET_CONTENT_TYPE_IMAGE: + ret = widget_create_image_object(data); + break; + case WIDGET_CONTENT_TYPE_RESOURCE_ID: + if (!s_info.conf.field.force_to_buffer) { + ret = widget_create_pixmap_object(data); + break; + } + case WIDGET_CONTENT_TYPE_BUFFER: + ret = widget_create_buffer_object(data); + break; + case WIDGET_CONTENT_TYPE_TEXT: + ret = widget_create_text_object(data); + break; + case WIDGET_CONTENT_TYPE_UIFW: + ret = widget_create_plug_object(data); + break; + case WIDGET_CONTENT_TYPE_INVALID: + default: + ret = WIDGET_ERROR_INVALID_PARAMETER; + break; + } + + if (ret == WIDGET_ERROR_NONE) { + info.error = WIDGET_ERROR_NONE; + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_CREATED; + + data->is.field.created = 1; + + update_visibility(data); + smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_CREATED, &info); + + /** + * In case of using the direct update path, + * sometimes the provider can send the updated event faster than created event. + * In that case, the viewer cannot recognize the updated content of a widget. + * So for the safety, I added this to forcely update the widget at the first time + * Right after creating its instance. + */ + append_widget_dirty_object_list(data, WIDGET_PRIMARY_BUFFER); + } + + return ret; +} + +static void __widget_created_cb(struct widget *handle, int ret, void *cbdata) +{ + struct widget_data *data = cbdata; + struct widget_evas_event_info info; + widget_type_e widget_type; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p (%d), %s\n", data, ret, widget_viewer_get_pkgname(handle)); + return; + } + + if (ret != WIDGET_ERROR_NONE) { + DbgPrint("Failed to create: %X\n", ret); + data->handle = NULL; + + if (!data->is.field.deleted) { + struct widget_evas_event_info fault_event; + + fault_event.error = ret; + fault_event.widget_app_id = data->widget_id; + fault_event.event = WIDGET_EVENT_CREATED; + + if (!data->is.field.faulted) { + data->is.field.faulted = 1; + __widget_overlay_faulted(data); + } + + DbgPrint("Display tap to load (%p) [%s]\n", data, data->widget_id); + smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED, &fault_event); + + ret = WIDGET_ERROR_FAULT; + } else { + ret = WIDGET_ERROR_CANCELED; + } + + data->is.field.send_delete = 0; + DbgPrint("Invoke raw delete %s\n", data->widget_id); + (void)invoke_raw_event_callback(WIDGET_VIEWER_EVAS_RAW_DELETE, data->widget_id, data->widget, ret); + widget_unref(data); + return; + } + + widget_viewer_get_type(handle, 0, &widget_type); + + switch (widget_type) { + case WIDGET_CONTENT_TYPE_IMAGE: + ret = widget_create_image_object(data); + break; + case WIDGET_CONTENT_TYPE_RESOURCE_ID: + if (!s_info.conf.field.force_to_buffer) { + ret = widget_create_pixmap_object(data); + break; + } + case WIDGET_CONTENT_TYPE_BUFFER: + ret = widget_create_buffer_object(data); + break; + case WIDGET_CONTENT_TYPE_TEXT: + ret = widget_create_text_object(data); + break; + case WIDGET_CONTENT_TYPE_UIFW: + ret = widget_create_plug_object(data); + break; + case WIDGET_CONTENT_TYPE_INVALID: + default: + ret = WIDGET_ERROR_INVALID_PARAMETER; + break; + } + + if (ret == WIDGET_ERROR_NONE) { + info.error = WIDGET_ERROR_NONE; + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_CREATED; + + data->is.field.created = 1; + + update_visibility(data); + smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_CREATED, &info); + DbgPrint("Invoke raw create %s\n", data->widget_id); + (void)invoke_raw_event_callback(WIDGET_VIEWER_EVAS_RAW_CREATE, data->widget_id, data->widget, ret); + + /** + * In case of using the direct update path, + * sometimes the provider can send the updated event faster than created event. + * In that case, the viewer cannot recognize the updated content of a widget. + * So for the safety, I added this to forcely update the widget at the first time + * Right after creating its instance. + */ + append_widget_dirty_object_list(data, WIDGET_KEEP_BUFFER); + + if (data->is.field.extra_info_updated) { + data->is.field.extra_info_updated = 0; + + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_EXTRA_INFO_UPDATED; + info.error = WIDGET_ERROR_NONE; + smart_callback_call(data, WIDGET_SMART_SIGNAL_EXTRA_INFO_UPDATED, &info); + } + } else { + info.error = ret; + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_CREATED; + smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED, &info); + data->is.field.send_delete = 0; + DbgPrint("Invoke raw delete %s\n", data->widget_id); + (void)invoke_raw_event_callback(WIDGET_VIEWER_EVAS_RAW_DELETE, data->widget_id, data->widget, ret); + } + + widget_unref(data); +} + +static void __widget_resize_image_object(struct widget_data *data) +{ + DbgPrint("widget resize request is succssfully sent\n"); +} + +static void __widget_resize_buffer_object(struct widget_data *data) +{ + DbgPrint("widget resize request is succssfully sent\n"); +} + +static void __widget_resize_text_object(struct widget_data *data) +{ + DbgPrint("widget resize request is succssfully sent\n"); +} + +static void __widget_resize_cb(struct widget *handle, int ret, void *cbdata) +{ + struct widget_data *data = cbdata; + struct widget_evas_event_info info; + widget_type_e widget_type; + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + if (ret != WIDGET_ERROR_NONE) { + info.error = ret; + info.event = WIDGET_EVENT_WIDGET_SIZE_CHANGED; + info.widget_app_id = data->widget_id; + smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_RESIZE_ABORTED, &info); + widget_unref(data); + return; + } + + widget_viewer_get_type(handle, 0, &widget_type); + switch (widget_type) { + case WIDGET_CONTENT_TYPE_IMAGE: + __widget_resize_image_object(data); + break; + case WIDGET_CONTENT_TYPE_RESOURCE_ID: + if (!s_info.conf.field.force_to_buffer) { + __widget_resize_pixmap_object(data); + break; + } + case WIDGET_CONTENT_TYPE_BUFFER: + __widget_resize_buffer_object(data); + break; + case WIDGET_CONTENT_TYPE_TEXT: + __widget_resize_text_object(data); + break; + case WIDGET_CONTENT_TYPE_UIFW: + break; + case WIDGET_CONTENT_TYPE_INVALID: + break; + default: + break; + } + + Evas_Object *scroller; + scroller = elm_object_part_content_get(data->widget_layout, "scroller"); + if (scroller) { + Evas_Object *box; + + box = elm_object_content_get(scroller); + if (box) { + widget_size_type_e type; + + if (widget_viewer_get_size_type(handle, &type) == WIDGET_ERROR_NONE) { + int height; + int width; + + if (widget_service_get_size(type, &width, &height) == WIDGET_ERROR_NONE) { + if (s_info.conf.field.is_scroll_x) { + height <<= 1; + } + + if (s_info.conf.field.is_scroll_y) { + width <<= 1; + } + + DbgPrint("Update scroller size to : %dx%d\n", width, height); + elm_object_content_unset(scroller); + evas_object_resize(box, width, height); + evas_object_size_hint_min_set(box, width, height); + elm_object_content_set(scroller, box); + } + } else { + ErrPrint("Failed to get widget size: %x\n", type); + } + } + } + + info.error = ret; + info.event = WIDGET_EVENT_WIDGET_SIZE_CHANGED; + info.widget_app_id = data->widget_id; + smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_RESIZED, &info); + widget_unref(data); +} + +static void gbar_overlay_disable(struct widget_data *data) +{ + if (!data->gbar_layout) { + return; + } + + if (!data->is.field.gbar_overlay_loaded) { + return; + } + + elm_object_signal_emit(data->gbar_layout, "disable", "overlay"); + data->is.field.gbar_overlay_loaded = 0; +} + +static void gbar_overlay_loading(struct widget_data *data) +{ + Evas_Object *rect; + + if (data->is.field.gbar_overlay_loaded) { + ErrPrint("Already loaded"); + return; + } + + rect = elm_object_part_content_unset(data->gbar_layout, "overlay,content"); + if (rect) { + evas_object_del(rect); + } + + rect = evas_object_rectangle_add(data->e); + evas_object_color_set(rect, 0, 0, 0, 0); + evas_object_show(rect); + /*! + * \todo + * Overlay for loading a GBAR + */ + + elm_object_part_content_set(data->gbar_layout, "overlay,content", rect); + elm_object_signal_emit(data->gbar_layout, "enable", "overlay"); + + data->is.field.gbar_overlay_loaded = 1; +} + +static Evas_Object *widget_load_overlay_edje(struct widget_data *data) +{ + Evas_Object *overlay; + + overlay = elm_layout_add(data->parent); + if (!overlay) { + ErrPrint("Failed to create a overlay\n"); + return NULL; + } + + if (elm_layout_file_set(overlay, WIDGET_VIEWER_EVAS_RESOURCE_EDJ, WIDGET_VIEWER_EVAS_RESOURCE_OVERLAY_LOADING) == EINA_FALSE) { + ErrPrint("Failed to load overlay file\n"); + evas_object_del(overlay); + return NULL; + } + + elm_object_part_content_set(data->widget_layout, "overlay,content", overlay); + return overlay; +} + +static Eina_Bool delayed_overlay_disable_cb(void *_data) +{ + struct widget_data *data = _data; + + if (data->is.field.disabled_overlay_animation) { + elm_object_signal_emit(data->widget_layout, "disable,without,animation", "overlay"); + } else { + elm_object_signal_emit(data->widget_layout, "disable", "overlay"); + } + + data->is.field.widget_overlay_loaded = 0; + data->overlay_update_counter = DEFAULT_OVERLAY_COUNTER; + data->overlay_timer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static void __widget_overlay_disable(struct widget_data *data, int no_timer, int ignore_update_count) +{ + if (!data->widget_layout) { + return; + } + + if (!data->is.field.widget_overlay_loaded) { + return; + } + + if (ignore_update_count) { + data->overlay_update_counter = 0; + } else { + if (data->is.field.hide_overlay_manually) { + return; + } + } + + /** + * @note + * After the frame update counter reaches to ZERO, + * The overlay will be disabled immediately if the "no_timer" is true(1), + * or it will be disabled after a few milli-seconds later. + * The timer will be fired when it gets the first frame update event. + * And it will start estimating seconds. + * Even after the last frame is updated (by "overlay_update_counter"), + * The timer will be expired after DEFAULT_OVERLAY_WAIT_TIME secs later + * which is started from the first frame update event. + */ + data->overlay_update_counter--; + if (data->overlay_update_counter <= 0) { + if (no_timer) { + if (data->overlay_timer) { + ecore_timer_del(data->overlay_timer); + /** + * @note + * data->overlay_timer will be reset'd to NULL by delayed_overlay_disable_cb(). + */ + } + delayed_overlay_disable_cb(data); + return; + } + } + + if (!no_timer && !data->overlay_timer) { + /** + * @note + * This routine will be executed when the update_counter is greater than 0, + * (means that the frame should be updated more as this count) + */ + data->overlay_timer = ecore_timer_add(DEFAULT_OVERLAY_WAIT_TIME, delayed_overlay_disable_cb, data); + if (!data->overlay_timer) { + ErrPrint("Failed to create a timer\n"); + delayed_overlay_disable_cb(data); + } + } +} + +static void __widget_overlay_loading(struct widget_data *data) +{ + struct acquire_data acquire_data; + Evas_Object *overlay; + + if (data->is.field.disable_loading == 1) { + DbgPrint("Loading overlay is disabled"); + return; + } + + if (data->is.field.widget_overlay_loaded == 1) { + DbgPrint("Overlay is already loaded"); + return; + } + + overlay = elm_object_part_content_get(data->widget_layout, "overlay,content"); + if (!overlay) { + overlay = widget_load_overlay_edje(data); + if (!overlay) { + return; + } + } + + if (!data->is.field.disable_preview) { + char *icon; + + icon = get_package_icon(data); + if (icon) { + Evas_Object *preview; + + preview = elm_object_part_content_get(overlay, "preview"); + if (!preview) { + preview = elm_image_add(overlay); + } + + if (preview) { + elm_image_file_set(preview, icon, NULL); + elm_object_part_content_set(overlay, "preview", preview); + } + + free(icon); + } + + DbgPrint("Set overlay loading (%p) %s\n", data, data->widget_id); + } else { + DbgPrint("Overlay is disabled (%s)\n", data->widget_id); + } + + elm_object_domain_translatable_part_text_set(overlay, "text", PKGNAME, "IDS_ST_BODY_LOADING_ING"); + if (data->is.field.disable_text) { + elm_object_signal_emit(overlay, "disable", "text"); + } + + elm_object_signal_emit(data->widget_layout, "reset", "overlay"); + if (data->is.field.disabled_overlay_animation) { + elm_object_signal_emit(data->widget_layout, "enable,without,animation", "overlay"); + } else { + elm_object_signal_emit(data->widget_layout, "enable", "overlay"); + } + + evas_object_geometry_get(data->widget, NULL, NULL, &acquire_data.w, &acquire_data.h); + acquire_data.content = NULL; + acquire_data.data = data; + update_widget_geometry(&acquire_data); + + data->is.field.widget_overlay_loaded = 1; + data->overlay_update_counter = DEFAULT_OVERLAY_COUNTER; +} + +static void __widget_overlay_faulted(struct widget_data *data) +{ + struct acquire_data acquire_data; + Evas_Object *overlay; + widget_type_e widget_type; + + if (data->is.field.widget_overlay_loaded) { + __widget_overlay_disable(data, 1, 1); + } + + overlay = elm_object_part_content_get(data->widget_layout, "overlay,content"); + if (!overlay) { + overlay = widget_load_overlay_edje(data); + if (!overlay) { + return; + } + } + + widget_viewer_get_type(data->handle, 0, &widget_type); + if (widget_type != WIDGET_CONTENT_TYPE_IMAGE) { + Evas_Object *preview; + + preview = elm_object_part_content_get(overlay, "preview"); + if (!preview) { + char *icon; + + icon = get_preview_image(data, data->size_type); + if (icon) { + preview = elm_image_add(data->widget_layout); + if (preview) { + elm_image_file_set(preview, icon, NULL); + elm_object_part_content_set(overlay, "preview", preview); + } + + free(icon); + } + } + } + + DbgPrint("Set overlay fault (%p) %s\n", data, data->widget_id); + elm_object_domain_translatable_part_text_set(overlay, "text", PKGNAME, "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY"); + elm_object_signal_emit(overlay, "enable", "text"); + elm_object_signal_emit(data->widget_layout, "reset", "overlay"); + elm_object_signal_emit(data->widget_layout, "enable", "overlay"); + + evas_object_geometry_get(data->widget, NULL, NULL, &acquire_data.w, &acquire_data.h); + acquire_data.content = NULL; + acquire_data.data = data; + update_widget_geometry(&acquire_data); + data->is.field.widget_overlay_loaded = 1; +} + +static void __widget_resize(Evas_Object *widget, Evas_Coord w, Evas_Coord h) +{ + struct widget_data *data; + widget_size_type_e type; + bool need_of_touch_effect = false; + bool need_of_mouse_event = false; + + data = evas_object_smart_data_get(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + type = find_size_type(data, w, h); + if (type == WIDGET_SIZE_TYPE_UNKNOWN) { + ErrPrint("Invalid size: %dx%d\n", w, h); + } else if (s_info.conf.field.use_fixed_size) { + if (widget_service_get_size(type, &w, &h) < 0) { + ErrPrint("Failed to get box size\n"); + } + data->fixed_width = w; + data->fixed_height = h; + } else { + if (widget_service_get_size(type, &data->fixed_width, &data->fixed_height) < 0) { + DbgPrint("Use the given size\n"); + data->fixed_width = w; + data->fixed_width = h; + } else { + ErrPrint("Failed to get box size\n"); + } + } + + /** + * @note + * If the use_fixed_size is false, the size_type can be differ with width & height + * Then we should not try to resize resource_id(surface) as width & height. + * Just keep them their size and try to resize layout only. + */ + if (!widget_viewer_is_created_by_user(data->handle)) { + /** + * Viewer should not be able to resize the box + */ + ErrPrint("System created Widget is not able to be resized (%s)\n", widget_viewer_get_pkgname(data->handle)); + + /* But update its size by handle's size */ + widget_viewer_get_size_type(data->handle, &data->size_type); + + if (data->size_type == WIDGET_SIZE_TYPE_UNKNOWN || widget_service_get_size(data->size_type, &data->widget_width, &data->widget_height)) { + ErrPrint("Unable to get default size from handle\n"); + /* + * In this case, just depends on user's request. + * Because, there is no other information which we can use. + */ + data->size_type = type; + data->widget_width = w; + data->widget_height = h; + } + } else { + data->widget_width = w; + data->widget_height = h; + data->size_type = type; + } + + DbgPrint("Request size change: %dx%d [0x%X]\n", w, h, data->size_type); + + if (data->is.field.faulted) { + evas_object_resize(data->widget_layout, data->widget_width, data->widget_height); + ErrPrint("Faulted widget, skip resizing (%s)\n", data->widget_id); + return; + } + + if (!data->handle) { + struct acquire_data acquire_data = { + .data = data, + }; + + DbgPrint("Create new handle: %dx%d, (%s, %s), %s/%s\n", data->widget_width, data->widget_height, + data->widget_id, data->content, + data->cluster, data->category); + + if (widget_viewer_activate_faulted_widget(data->widget_id, NULL, NULL) < 0) { + ErrPrint("Activate: %s\n", data->widget_id); + } + + data->is.field.created = 0; + data->is.field.send_delete = 1; + update_widget_geometry(&acquire_data); + + data->handle = widget_viewer_add_widget(data->widget_id, data->content, + data->cluster, data->category, + data->period, type, + __widget_created_cb, widget_ref(data)); + if (!data->handle) { + ErrPrint("Failed to send add request\n"); + DbgPrint("Unref %p %s\n", data, data->widget_id); + widget_unref(data); + return; + } + + DbgPrint("Added handle: %p (%p)\n", data->handle, data); + widget_viewer_set_data(data->handle, widget); + __widget_overlay_loading(data); + widget_service_get_need_of_touch_effect(data->widget_id, type, (bool *)&need_of_touch_effect); + data->is.field.touch_effect = need_of_touch_effect; + widget_service_get_need_of_mouse_event(data->widget_id, type, (bool *)&need_of_mouse_event); + data->is.field.mouse_event = need_of_mouse_event; + } else { + + int ret; + + if (type > 0 && type != WIDGET_SIZE_TYPE_UNKNOWN) { + ret = widget_viewer_resize_widget(data->handle, type, __widget_resize_cb, widget_ref(data)); + } else { + ret = WIDGET_ERROR_INVALID_PARAMETER; + /* This will be decreased soon ... */ + widget_ref(data); + } + + evas_object_resize(data->widget_layout, data->widget_width, data->widget_height); + if (ret == WIDGET_ERROR_ALREADY_EXIST) { + DbgPrint("Same size\n"); + widget_unref(data); + } else if (ret == WIDGET_ERROR_NONE) { + DbgPrint("Resize request is successfully sent\n"); + widget_service_get_need_of_touch_effect(data->widget_id, type, (bool *)&need_of_touch_effect); + data->is.field.touch_effect = need_of_touch_effect; + widget_service_get_need_of_mouse_event(data->widget_id, type, (bool *)&need_of_mouse_event); + data->is.field.mouse_event = need_of_mouse_event; + } else { + widget_unref(data); + } + } +} + +static void __widget_show(Evas_Object *widget) +{ + struct widget_data *data; + + data = evas_object_smart_data_get(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + evas_object_show(data->stage); + evas_object_show(data->widget_layout); + + if (!s_info.conf.field.manual_pause_resume) { + update_visibility(data); + } +} + +static void __widget_hide(Evas_Object *widget) +{ + struct widget_data *data; + + data = evas_object_smart_data_get(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + evas_object_hide(data->stage); + evas_object_hide(data->widget_layout); + + if (!s_info.conf.field.manual_pause_resume) { + update_visibility(data); + } +} + +static void __widget_color_set(Evas_Object *widget, int r, int g, int b, int a) +{ + struct widget_data *data; + + data = evas_object_smart_data_get(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + evas_object_color_set(data->stage, r, g, b, a); +} + +static void __widget_clip_set(Evas_Object *widget, Evas_Object *clip) +{ + struct widget_data *data; + + data = evas_object_smart_data_get(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + evas_object_clip_set(data->stage, clip); +} + +static void __widget_clip_unset(Evas_Object *widget) +{ + struct widget_data *data; + + data = evas_object_smart_data_get(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + if (data->state != WIDGET_DATA_CREATED) { + ErrPrint("Invalid widget data: %p\n", data); + return; + } + + evas_object_clip_unset(data->stage); +} + +/** + * This must be called before update_gbar_geometry + */ +static void update_stage_geometry(struct acquire_data *acquire_data) +{ + Evas_Coord widget_x, widget_y, widget_w, widget_h; + Evas_Coord stage_w, stage_h; + + evas_object_geometry_get(acquire_data->data->widget_layout, &widget_x, &widget_y, &widget_w, &widget_h); + + const int delta_y_top = (acquire_data->h - widget_y); + const int delta_y_bottom = (acquire_data->h - (s_info.screen_height - widget_y - widget_h)); + + stage_w = widget_w > acquire_data->w ? widget_w : acquire_data->w; + stage_h = widget_h + acquire_data->h;/* - delta_y_top; */ + + if (delta_y_top >= delta_y_bottom) { + evas_object_move(acquire_data->data->stage, 0, widget_y); + } else { + evas_object_move(acquire_data->data->stage, 0, widget_y - acquire_data->h); + } + + evas_object_resize(acquire_data->data->stage, stage_w, stage_h); +} + +static void update_gbar_geometry(struct acquire_data *acquire_data) +{ + Evas_Coord widget_x, widget_y, widget_w, widget_h; + + evas_object_geometry_get(acquire_data->data->widget_layout, &widget_x, &widget_y, &widget_w, &widget_h); + + /* How much of the GBAR is outside the screen */ + const int delta_y_top = (acquire_data->h - widget_y) < 0 ? 0 : acquire_data->h - widget_y; + const int delta_y_bottom = (acquire_data->h - (s_info.screen_height - widget_y - widget_h)) < 0 ? 0 : (acquire_data->h - (s_info.screen_height - widget_y - widget_h)); + + /* If more of the GBAR is outside the top side draw at the bottom, otherwise draw at the top */ + if (delta_y_top >= delta_y_bottom) { + evas_object_move(acquire_data->data->gbar_layout, 0, widget_y + widget_h - delta_y_bottom); + effect_resize(acquire_data->data->gbar_layout, acquire_data->w, acquire_data->h, EFFECT_HEIGHT); + } else { + evas_object_move(acquire_data->data->gbar_layout, 0, widget_y + delta_y_top); + effect_resize(acquire_data->data->gbar_layout, acquire_data->w, acquire_data->h, EFFECT_HEIGHT|EFFECT_MOVE); + } +} + +static void update_widget_geometry(struct acquire_data *acquire_data) +{ + Evas_Coord widget_x, widget_y, widget_w, widget_h; + Evas_Coord stage_w, stage_h; + struct widget_data *data = acquire_data->data; + + evas_object_resize(data->widget_layout, data->widget_width, data->widget_height); + evas_object_geometry_get(data->widget_layout, &widget_x, &widget_y, &widget_w, &widget_h); + + if (data->gbar_layout) { + Evas_Coord gbar_x, gbar_y, gbar_w, gbar_h; + + evas_object_geometry_get(data->gbar_layout, &gbar_x, &gbar_y, &gbar_w, &gbar_h); + if (widget_y + widget_h + gbar_h > s_info.screen_height) { + evas_object_move(data->gbar_layout, 0, widget_y - gbar_h); + evas_object_move(data->stage, 0, widget_y - gbar_h); + } else { + evas_object_move(data->gbar_layout, 0, widget_y + widget_h); + evas_object_move(data->stage, 0, widget_y); + } + + stage_w = gbar_w > widget_w ? gbar_w : widget_w; + stage_h = widget_h + gbar_h; + } else { + stage_w = widget_w; + if (s_info.conf.field.support_gbar) { + stage_h = widget_h + RESEVED_AREA_FOR_GBAR_EFFECT; /* Reserve 100 px for effect */ + } else { + stage_h = widget_h; + } + + evas_object_move(data->stage, widget_x, widget_y); + } + + evas_object_resize(data->stage, stage_w, stage_h); +} + +static void __widget_update_image_object(struct widget_data *data, Evas_Object *widget_content, int w, int h) +{ + Evas_Object *front_image; + + front_image = elm_object_part_content_get(widget_content, "front,content"); + if (front_image) { + elm_image_file_set(front_image, widget_viewer_get_filename(data->handle), NULL); + } else { + ErrPrint("Image object not found\n"); + } +} + +static void __widget_update_buffer_object(struct widget_data *data, Evas_Object *widget_content, int w, int h) +{ + struct acquire_data acquire_data = { + .w = w, + .h = h, + .content = widget_content, + .data = data, + }; + + if (data->widget_fb) { + widget_viewer_release_buffer(data->widget_fb); + data->widget_fb = NULL; + } + + data->widget_fb = widget_viewer_acquire_buffer(data->handle, 0); + if (!data->widget_fb) { + ErrPrint("Failed to get fb\n"); + return; + } + + evas_object_image_size_set(widget_content, w, h); + + if (widget_viewer_acquire_buffer_lock(data->handle, 0) < 0) { + ErrPrint("Failed to acquire lock\n"); + } + evas_object_image_data_copy_set(widget_content, data->widget_fb); + if (widget_viewer_release_buffer_lock(data->handle, 0) < 0) { + ErrPrint("Failed to release lock\n"); + } + + evas_object_image_fill_set(widget_content, 0, 0, w, h); + evas_object_image_pixels_dirty_set(widget_content, EINA_TRUE); + evas_object_image_data_update_add(widget_content, 0, 0, w, h); + update_widget_geometry(&acquire_data); +} + +static void __widget_update_text_object(struct widget_data *data, Evas_Object *widget_content, int w, int h) +{ + struct acquire_data acquire_data = { + .w = w, + .h = h, + .content = widget_content, + .data = data, + }; + + update_widget_geometry(&acquire_data); +} + +static void __widget_event_extra_info_updated(struct widget_data *data) +{ + struct widget_evas_event_info info; + const char *content_info; + char *tmp; + + if (data->is.field.deleted) { + DbgPrint("Box is %s, ignore update\n", data->is.field.deleted ? "deleted" : "faulted"); + return; + } + + content_info = widget_viewer_get_content_string(data->handle); + if (content_info && data->content) { + if (!strcmp(content_info, data->content)) { + /* Nothing chnaged */ + } else { + tmp = strdup(content_info); + if (!tmp) { + ErrPrint("Heap: %d\n", errno); + return; + } + + free(data->content); + data->content = tmp; + } + } else if (content_info) { + tmp = strdup(content_info); + if (!tmp) { + ErrPrint("Heap: %d\n", errno); + return; + } + data->content = tmp; + } else if (data->content) { + free(data->content); + data->content = NULL; + } else { + /* Nothing changed */ + } + + if (data->is.field.created == 0) { + DbgPrint("Extra info is updated[%s]\n", data->widget_id); + data->is.field.extra_info_updated = 1; + } else { + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_EXTRA_INFO_UPDATED; + info.error = WIDGET_ERROR_NONE; + smart_callback_call(data, WIDGET_SMART_SIGNAL_EXTRA_INFO_UPDATED, &info); + } +} + +/*! + * Event handlers + */ +static void __widget_event_widget_updated(struct widget_data *data) +{ + Evas_Object *content; + widget_size_type_e type; + widget_type_e widget_type; + int w, h; + struct widget_evas_event_info info; + + data->is.field.widget_dirty = 0; + + if (data->is.field.deleted) { + DbgPrint("Box is %s, ignore update\n", data->is.field.deleted ? "deleted" : "faulted"); + return; + } + + content = elm_object_part_content_get(data->widget_layout, "widget,content"); + if (!content) { + ErrPrint("Failed to get content object\n"); + return; + } + + widget_viewer_get_size_type(data->handle, &type); + if (type < 0 || type == WIDGET_SIZE_TYPE_UNKNOWN) { + ErrPrint("Size is not valid %X\n", type); + return; + } + + /** + * @note + * We should not use this widget_width and widget_height + * It is set'd by user but the resource_id buffer should be resized by size_type. + * Even if the script or text or image can be resized to given size,. + * We should handles them as resource_id to make the consistent behaviour. + */ + widget_service_get_size(type, &w, &h); + if (w != data->widget_width || h != data->widget_height) { + DbgPrint("Pixel and Type are differ. use type [%dx%d] - [%dx%d]\n", w, h, data->widget_width, data->widget_height); + } + + widget_viewer_get_type(data->handle, 0, &widget_type); + + switch (widget_type) { + case WIDGET_CONTENT_TYPE_IMAGE: + __widget_update_image_object(data, content, w, h); + __widget_overlay_disable(data, 0, 0); + break; + case WIDGET_CONTENT_TYPE_RESOURCE_ID: + if (!s_info.conf.field.force_to_buffer) { + __widget_update_pixmap_object(data, content, w, h); + break; + } + case WIDGET_CONTENT_TYPE_BUFFER: + __widget_update_buffer_object(data, content, w, h); + __widget_overlay_disable(data, 0, 0); + break; + case WIDGET_CONTENT_TYPE_TEXT: + __widget_update_text_object(data, content, w, h); + __widget_overlay_disable(data, 0, 0); + break; + case WIDGET_CONTENT_TYPE_UIFW: + break; + case WIDGET_CONTENT_TYPE_INVALID: + default: + break; + } + + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_WIDGET_UPDATED; + info.error = WIDGET_ERROR_NONE; + smart_callback_call(data, WIDGET_SMART_SIGNAL_UPDATED, &info); +} + +static void gbar_update_buffer_object(struct widget_data *data, Evas_Object *gbar_content, int w, int h) +{ + struct acquire_data acquire_data = { + .data = data, + .content = gbar_content, + .w = w, + .h = h, + }; + + if (data->gbar_fb) { + widget_viewer_release_buffer(data->gbar_fb); + data->gbar_fb = NULL; + } else { + /* This is first time */ + gbar_overlay_disable(data); + } + + data->gbar_fb = widget_viewer_acquire_buffer(data->handle, 1); + if (!data->gbar_fb) { + ErrPrint("Failed to get fb\n"); + return; + } + + evas_object_image_size_set(gbar_content, w, h); + + if (widget_viewer_acquire_buffer_lock(data->handle, 1) < 0) { + ErrPrint("Failed to acquire lock\n"); + } + evas_object_image_data_copy_set(gbar_content, data->gbar_fb); + if (widget_viewer_release_buffer_lock(data->handle, 1) < 0) { + ErrPrint("Failed to release lock\n"); + } + + evas_object_image_fill_set(gbar_content, 0, 0, w, h); + evas_object_image_pixels_dirty_set(gbar_content, EINA_TRUE); + evas_object_image_data_update_add(gbar_content, 0, 0, w, h); + + update_stage_geometry(&acquire_data); + update_gbar_geometry(&acquire_data); +} + +static void gbar_update_text_object(struct widget_data *data, Evas_Object *gbar_content, int w, int h) +{ + struct acquire_data acquire_data = { + .data = data, + .content = gbar_content, + .w = w, + .h = h, + }; + + ErrPrint("Text type is updated\n"); + gbar_overlay_disable(data); + + update_stage_geometry(&acquire_data); + update_gbar_geometry(&acquire_data); +} + +static void update_gbar_pixmap(Evas_Object *content, int w, int h) +{ + evas_object_image_pixels_dirty_set(content, EINA_TRUE); + evas_object_image_data_update_add(content, 0, 0, w, h); + evas_object_show(content); +} + +static void acquire_gbar_pixmap_cb(struct widget *handle, int pixmap, void *cbdata) +{ + struct acquire_data *acquire_data = cbdata; + struct widget_data *data = acquire_data->data; + + data->is.field.gbar_pixmap_acquire_requested = 0; + + if (pixmap == 0) { + ErrPrint("Failed to acquire pixmap\n"); + DbgPrint("Unref %p %s\n", data, data->widget_id); + widget_unref(data); + if (!s_info.conf.field.skip_acquire) { + free(acquire_data); + } + return; + } + + evas_object_image_size_set(acquire_data->content, acquire_data->w, acquire_data->h); + evas_object_image_fill_set(acquire_data->content, 0, 0, acquire_data->w, acquire_data->h); + + /** + * 1 means, First time. + */ + if (util_set_native_surface(handle, 1, acquire_data->content, (unsigned int)pixmap, s_info.conf.field.skip_acquire) == 1) { + gbar_overlay_disable(data); + } + + data->gbar_pixmap = (unsigned int)pixmap; + + append_gbar_dirty_object_list(data, WIDGET_KEEP_BUFFER); + update_stage_geometry(acquire_data); + update_gbar_geometry(acquire_data); + + if (!s_info.conf.field.skip_acquire) { + free(acquire_data); + } + DbgPrint("Unref %p %s\n", data, data->widget_id); + widget_unref(data); +} + +static void gbar_update_pixmap_object(struct widget_data *data, Evas_Object *gbar_content, int w, int h) +{ + struct acquire_data *acquire_data; + int ret; + unsigned int resource_id; + + if (data->gbar_latest_idx == WIDGET_PRIMARY_BUFFER) { + widget_viewer_get_resource_id(data->handle, 1, &resource_id); + if (data->gbar_pixmap == resource_id) { + int ow; + int oh; + + effect_size_get(gbar_content, &ow, &oh); + + if (data->gbar_extra) { + replace_pixmap(NULL, 1, gbar_content, data->gbar_pixmap); + } + update_gbar_pixmap(gbar_content, w, h); + + if (ow != w || oh != h) { + struct acquire_data adata = { + .data = data, + .content = gbar_content, + .w = w, + .h = h, + }; + + update_stage_geometry(&adata); + } + return; + } + + if (s_info.conf.field.skip_acquire && resource_id != 0) { + struct acquire_data local_acquire_data = { + .data = widget_ref(data), + .content = gbar_content, + .w = w, + .h = h, + }; + + acquire_gbar_pixmap_cb(data->handle, resource_id, &local_acquire_data); + return; + } + + if (data->is.field.gbar_pixmap_acquire_requested) { + return; + } + + acquire_data = malloc(sizeof(*acquire_data)); + if (!acquire_data) { + ErrPrint("Heap: %d\n", errno); + return; + } + + acquire_data->content = gbar_content; + acquire_data->w = w; + acquire_data->h = h; + acquire_data->data = widget_ref(data); + + ret = widget_viewer_acquire_resource_id(data->handle, 1, acquire_gbar_pixmap_cb, acquire_data); + if (ret != WIDGET_ERROR_NONE) { + ErrPrint("Failed to acquire gbar resource id\n"); + free(acquire_data); + DbgPrint("Unref %p %s\n", data, data->widget_id); + widget_unref(data); + } else { + data->is.field.gbar_pixmap_acquire_requested = 1; + } + } else { + int ow; + int oh; + + if (!data->gbar_extra) { + DbgPrint("Extra GBar is not prepared yet\n"); + return; + } + + effect_size_get(gbar_content, &ow, &oh); + + replace_pixmap(NULL, 1, gbar_content, data->gbar_extra[data->gbar_latest_idx]); + update_gbar_pixmap(gbar_content, w, h); + + if (ow != w || oh != h) { + struct acquire_data adata = { + .data = data, + .content = gbar_content, + .w = w, + .h = h, + }; + + update_stage_geometry(&adata); + } + } +} + +static void __widget_event_gbar_updated(struct widget_data *data) +{ + Evas_Object *gbar_content; + int w, h; + widget_type_e widget_type; + + data->is.field.gbar_dirty = 0; + + if (data->is.field.deleted) { + DbgPrint("Box is deleted, ignore update\n"); + return; + } + + gbar_content = elm_object_part_content_get(data->gbar_layout, "gbar,content"); + if (!gbar_content) { + ErrPrint("Failed to get content object\n"); + return; + } + + if (widget_viewer_get_glance_bar_size(data->handle, &w, &h) != WIDGET_ERROR_NONE) { + ErrPrint("Failed to get gbar_size\n"); + w = 0; + h = 0; + } + + widget_viewer_get_type(data->handle, 1, &widget_type); + + switch (widget_type) { + case WIDGET_CONTENT_TYPE_RESOURCE_ID: + if (!s_info.conf.field.force_to_buffer) { + gbar_update_pixmap_object(data, gbar_content, w, h); + break; + } + case WIDGET_CONTENT_TYPE_BUFFER: + gbar_update_buffer_object(data, gbar_content, w, h); + break; + case WIDGET_CONTENT_TYPE_TEXT: + gbar_update_text_object(data, gbar_content, w, h); + break; + case WIDGET_CONTENT_TYPE_UIFW: + break; + case WIDGET_CONTENT_TYPE_INVALID: + default: + ErrPrint("Invalid pd type\n"); + break; + } +} + +static void __widget_event_deleted(struct widget_data *data) +{ + struct widget_evas_event_info info; + + if (data->widget_fb) { + widget_viewer_release_buffer(data->widget_fb); + data->widget_fb = NULL; + } + + if (data->gbar_fb) { + widget_viewer_release_buffer(data->gbar_fb); + data->gbar_fb = NULL; + } + + if (data->widget_pixmap) { + replace_widget_pixmap_with_image(data); + } + + if (data->gbar_pixmap) { + replace_gbar_pixmap_with_image(data); + } + + DbgPrint("widget is deleted: %p (emit signal)\n", data); + data->is.field.send_delete = 0; + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_DELETED; + info.error = data->is.field.faulted ? WIDGET_ERROR_FAULT : WIDGET_ERROR_NONE; + + /** + * Even if the widget object tries to be deleted from WIDGET_DELETED event callback, + * widget data should not be released while processing RAW_DELETE event handling + */ + widget_ref(data); + + smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_DELETED, &info); + DbgPrint("Invoke raw delete %s\n", data->widget_id); + (void)invoke_raw_event_callback(WIDGET_VIEWER_EVAS_RAW_DELETE, data->widget_id, data->widget, info.error); + + remove_widget_dirty_object_list(data); + remove_gbar_dirty_object_list(data); /* For the safety */ + + data->handle = NULL; + + /** + * All event handler is handled correctly, + * Then decrease the refcnt of it. + */ + widget_unref(data); +} + +static void __widget_event_request_close_gbar(struct widget_data *data) +{ + int ret; + + ret = widget_viewer_destroy_glance_bar(data->handle, __widget_destroy_gbar_cb, widget_ref(data)); + if (ret < 0) { + ErrPrint("Failed to close a GBAR: %x\n", ret); + DbgPrint("Unref %p %s\n", data, data->widget_id); + widget_unref(data); + } +} + +static void __widget_event_group_changed(struct widget_data *data) +{ + DbgPrint("Group is changed\n"); +} + +static void __widget_event_pinup_changed(struct widget_data *data) +{ + DbgPrint("Pinup is changed\n"); +} + +static void __widget_event_period_changed(struct widget_data *data) +{ + struct widget_evas_event_info info; + + widget_viewer_get_period(data->handle, &(data->period)); + DbgPrint("Update period is changed to (%lf)\n", data->period); + + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_PERIOD_CHANGED; + info.error = WIDGET_ERROR_NONE; + smart_callback_call(data, WIDGET_SMART_SIGNAL_PERIOD_CHANGED, &info); +} + +static void __widget_event_widget_size_changed(struct widget_data *data) +{ + DbgPrint("widget LB size is changed\n"); +} + +static void __widget_event_gbar_size_changed(struct widget_data *data) +{ + DbgPrint("widget GBAR size is changed\n"); +} + +static void __widget_event_gbar_created(struct widget_data *data) +{ + DbgPrint("widget GBAR is created\n"); +} + +static void __widget_event_gbar_destroyed(struct widget_data *data) +{ + DbgPrint("widget GBAR is destroyed\n"); + remove_gbar_dirty_object_list(data); +} + +static void __widget_event_hold_scroll(struct widget_data *data) +{ + struct widget_evas_event_info info; + DbgPrint("widget hold scroll\n"); + + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_HOLD_SCROLL; + info.error = WIDGET_ERROR_NONE; + smart_callback_call(data, WIDGET_SMART_SIGNAL_CONTROL_SCROLLER, &info); +} + +static void __widget_event_release_scroll(struct widget_data *data) +{ + struct widget_evas_event_info info; + DbgPrint("widget release scroll\n"); + + info.widget_app_id = data->widget_id; + info.event = WIDGET_EVENT_RELEASE_SCROLL; + info.error = WIDGET_ERROR_NONE; + smart_callback_call(data, WIDGET_SMART_SIGNAL_CONTROL_SCROLLER, &info); +} + +static void __widget_event_widget_update_begin(struct widget_data *data) +{ + DbgPrint("WIDGET Update Begin\n"); +} + +static void __widget_event_widget_update_end(struct widget_data *data) +{ + DbgPrint("WIDGET Update End\n"); +} + +static void __widget_event_gbar_update_begin(struct widget_data *data) +{ + DbgPrint("GBAR Update Begin\n"); +} + +static void __widget_event_gbar_update_end(struct widget_data *data) +{ + DbgPrint("GBAR Update End\n"); +} + +static void __widget_event_update_mode_changed(struct widget_data *data) +{ + DbgPrint("Update mode changed\n"); +} + +static void __widget_event_ignored(struct widget_data *data) +{ + DbgPrint("Request is ignored\n"); +} + +static Evas_Object *create_widget_object(struct widget *handle) +{ + struct widget_data *data; + const char *cluster; + const char *sub_cluster; + Evas_Object *widget; + double period; + + if (widget_viewer_get_group(handle, &cluster, &sub_cluster) != WIDGET_ERROR_NONE) { + ErrPrint("Unable to get the group info\n"); + } + + /** + * \TODO: Create a widget evas object + */ + + widget_viewer_get_period(handle, &period); + + widget = widget_viewer_evas_add_widget(s_info.win, + widget_viewer_get_pkgname(handle), widget_viewer_get_content_string(handle), + period); + + data = evas_object_smart_data_get(widget); + if (data) { + widget_size_type_e type; + int w = 0; + int h = 0; + + data->handle = handle; + + widget_viewer_get_size_type(handle, &type); + widget_service_get_size(type, &w, &h); + DbgPrint("Size: %dx%d\n", w, h); + evas_object_resize(widget, w, h); + } + + return widget; +} + +static inline int handle_subscribed_group(struct widget *handle) +{ + const char *cluster = NULL; + const char *sub_cluster = NULL; + Eina_List *l; + struct subscribe_group *group; + + if (widget_viewer_get_group(handle, &cluster, &sub_cluster) != WIDGET_ERROR_NONE) { + return WIDGET_ERROR_FAULT; + } + + if (!cluster || !sub_cluster) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + EINA_LIST_FOREACH(s_info.subscribed_group_list, l, group) { + if (!strcasecmp(group->cluster, cluster) && !strcasecmp(group->sub_cluster, sub_cluster)) { + int nr; + Evas_Object *widget; + struct widget_data *temp_widget_data = NULL; + + DbgPrint("Subscribed Group: (%s)(%s)\n", cluster, sub_cluster); + + /* Subscribed object, Create this */ + widget = create_widget_object(handle); + if (!widget) { + ErrPrint("Failed to create a widget object\n"); + (void)widget_viewer_delete_widget(handle, WIDGET_DELETE_PERMANENTLY, NULL, NULL); + return WIDGET_ERROR_FAULT; + } + + widget_viewer_set_data(handle, widget); + + /* Emit RAW_CREATE event */ + nr = invoke_raw_event_callback(WIDGET_VIEWER_EVAS_RAW_CREATE, widget_viewer_get_pkgname(handle), widget, WIDGET_ERROR_NONE); + + if ((temp_widget_data = get_smart_data(widget)) == NULL) { + ErrPrint("Failed to get widget data\n"); + (void)widget_viewer_delete_widget(handle, WIDGET_DELETE_PERMANENTLY, NULL, NULL); + return WIDGET_ERROR_FAULT; + } + + if (nr <= 0 || widget_system_created(handle, temp_widget_data) != WIDGET_ERROR_NONE) { + /* + * Deleting evas object will invoke delete callback. + * Then it will invoke the RAW_DELETE event and execute the proper procedures for deleting object + */ + widget_viewer_evas_set_permanent_delete(widget, EINA_TRUE); + evas_object_del(widget); + } + + return WIDGET_ERROR_NONE; + } + } + + return WIDGET_ERROR_NOT_EXIST; +} + +static inline int handle_subscribed_category(struct widget *handle) +{ + char *category; + Eina_List *l; + struct subscribe_category *info; + + category = widget_service_get_category(widget_viewer_get_pkgname(handle)); + if (!category) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + EINA_LIST_FOREACH(s_info.subscribed_category_list, l, info) { + if (!strcmp(category, info->category)) { + int nr; + Evas_Object *widget; + struct widget_data *temp_widget_data; + + DbgPrint("Subscribed Category: (%s)(%s)\n", category, info->category); + + widget = create_widget_object(handle); + if (!widget) { + ErrPrint("Failed to create a widget object\n"); + (void)widget_viewer_delete_widget(handle, WIDGET_DELETE_PERMANENTLY, NULL, NULL); + free(category); + return WIDGET_ERROR_FAULT; + } + + widget_viewer_set_data(handle, widget); + + /* Subscribed object, Create this */ + nr = invoke_raw_event_callback(WIDGET_VIEWER_EVAS_RAW_CREATE, widget_viewer_get_pkgname(handle), widget, WIDGET_ERROR_NONE); + + temp_widget_data = get_smart_data(widget); + if (!temp_widget_data) { + ErrPrint("Failed to get widget data\n"); + (void)widget_viewer_delete_widget(handle, WIDGET_DELETE_PERMANENTLY, NULL, NULL); + evas_object_del(widget); + free(category); + return WIDGET_ERROR_FAULT; + } + + if (nr <= 0 || widget_system_created(handle, temp_widget_data) != WIDGET_ERROR_NONE) { + /* Delete widget, if no one cares it */ + DbgPrint("No one cares\n"); + widget_viewer_evas_set_permanent_delete(widget, EINA_TRUE); + evas_object_del(widget); + } + + free(category); + return WIDGET_ERROR_NONE; + } + } + + free(category); + return WIDGET_ERROR_NOT_EXIST; +} + +static int widget_event_handler(struct widget *handle, enum widget_event_type event, void *cbdata) +{ + Evas_Object *widget; + struct widget_data *data; + int idx; + unsigned int resource_id; + int status; + + widget = widget_viewer_get_data(handle); + if (widget) { + data = get_smart_data(widget); + } else { + data = NULL; + DbgPrint("widget Object is not exists, create it?\n"); + } + + if (!widget || !data || data->is.field.deleted) { + widget_viewer_set_data(handle, NULL); + + if (event == WIDGET_EVENT_CREATED) { + if (handle_subscribed_group(handle) == WIDGET_ERROR_NONE) { + return 0; + } + + if (handle_subscribed_category(handle) == WIDGET_ERROR_NONE) { + return 0; + } + + DbgPrint("System created widget is not supported\n"); + (void)widget_viewer_delete_widget(handle, WIDGET_DELETE_PERMANENTLY, NULL, NULL); + } else { + ErrPrint("Failed to get smart data\n"); + } + + return 0; + } + + switch ((int)event) { + case WIDGET_EVENT_WIDGET_EXTRA_BUFFER_CREATED: + widget_viewer_get_affected_extra_buffer(handle, 0, &idx, &resource_id); + DbgPrint("Extra buffer created for WIDGET: %d (%u)\n", idx, resource_id); + + status = widget_viewer_acquire_extra_resource_id(handle, 0, idx, acquire_widget_extra_resource_cb, data); + if (status < 0) { + ErrPrint("Failed to acquire resource: %u (0x%X)\n", resource_id, status); + break; + } + + if (!data->widget_extra) { + data->widget_extra = calloc(widget_viewer_get_option(WIDGET_OPTION_EXTRA_BUFFER_CNT), sizeof(*data->widget_extra)); + if (!data->widget_extra) { + ErrPrint("calloc: %d\n", errno); + break; + } + } + + data->widget_extra[idx] = resource_id; + data->widget_extra_cnt++; + break; + case WIDGET_EVENT_WIDGET_EXTRA_BUFFER_DESTROYED: + widget_viewer_get_affected_extra_buffer(handle, 0, &idx, &resource_id); + DbgPrint("Extra buffer destroyed for WIDGET: %d (%u)\n", idx, resource_id); + if (data->widget_extra[idx] != resource_id) { + DbgPrint("Resource Id mismatched\n"); + if (data->widget_extra[idx] == 0u) { + DbgPrint("Not acquired resourced\n"); + break; + } + } + + data->widget_extra[idx] = 0u; + data->widget_extra_cnt--; + if (!data->widget_extra_cnt) { + DbgPrint("Release widget array\n"); + free(data->widget_extra); + data->widget_extra = NULL; + } + + if (!s_info.conf.field.skip_acquire) { + if (widget_viewer_release_resource_id(handle, 0, resource_id) < 0) { + ErrPrint("Failed to release resource: %u\n", resource_id); + } + } + break; + case WIDGET_EVENT_GBAR_EXTRA_BUFFER_CREATED: + widget_viewer_get_affected_extra_buffer(handle, 1, &idx, &resource_id); + DbgPrint("Extra buffer destroyed for GBAR: %d (%u)\n", idx, resource_id); + if (!data->gbar_extra) { + data->gbar_extra = calloc(widget_viewer_get_option(WIDGET_OPTION_EXTRA_BUFFER_CNT), sizeof(*data->gbar_extra)); + if (!data->gbar_extra) { + ErrPrint("calloc: %d\n", errno); + break; + } + } + + data->gbar_extra[idx] = resource_id; + data->gbar_extra_cnt++; + + if (widget_viewer_acquire_extra_resource_id(handle, 1, idx, acquire_gbar_extra_resource_cb, data) < 0) { + ErrPrint("Failed to acquire resource: %u\n", resource_id); + } + break; + case WIDGET_EVENT_GBAR_EXTRA_BUFFER_DESTROYED: + widget_viewer_get_affected_extra_buffer(handle, 1, &idx, &resource_id); + DbgPrint("Extra buffer destroyed for GBAR: %d (%u)\n", idx, resource_id); + if (data->gbar_extra[idx] != resource_id) { + DbgPrint("Resource Id mismatched\n"); + } + data->gbar_extra[idx] = 0u; + data->gbar_extra_cnt--; + if (!data->gbar_extra_cnt) { + DbgPrint("Release gbar array\n"); + free(data->gbar_extra); + data->gbar_extra = NULL; + } + + if (!s_info.conf.field.skip_acquire) { + if (widget_viewer_release_resource_id(handle, 1, resource_id) < 0) { + ErrPrint("Failed to release resource: %u\n", resource_id); + } + } + break; + case WIDGET_EVENT_WIDGET_EXTRA_UPDATED: + widget_viewer_get_affected_extra_buffer(handle, 0, &idx, &resource_id); + if (!data->widget_extra) { + ErrPrint("Extra buffer is not prepared yet\n"); + } else { + if (data->widget_extra[idx] != resource_id) { + ErrPrint("Resource ID mismatched\n"); + } + append_widget_dirty_object_list(data, idx); + } + break; + case WIDGET_EVENT_GBAR_EXTRA_UPDATED: + widget_viewer_get_affected_extra_buffer(handle, 1, &idx, &resource_id); + if (!data->gbar_extra) { + ErrPrint("Extra buffer is not prepared yet\n"); + } else { + if (data->gbar_extra[idx] != resource_id) { + ErrPrint("Resource ID mismatched\n"); + } + append_gbar_dirty_object_list(data, idx); + } + break; + case WIDGET_EVENT_WIDGET_UPDATED: + append_widget_dirty_object_list(data, WIDGET_PRIMARY_BUFFER); + break; + case WIDGET_EVENT_GBAR_UPDATED: + append_gbar_dirty_object_list(data, WIDGET_PRIMARY_BUFFER); + break; + case WIDGET_EVENT_EXTRA_INFO_UPDATED: + __widget_event_extra_info_updated(data); + break; + + case WIDGET_EVENT_DELETED: + __widget_event_deleted(data); + break; + + case WIDGET_EVENT_GROUP_CHANGED: + __widget_event_group_changed(data); + break; + case WIDGET_EVENT_PINUP_CHANGED: + __widget_event_pinup_changed(data); + break; + case WIDGET_EVENT_PERIOD_CHANGED: + __widget_event_period_changed(data); + break; + + case WIDGET_EVENT_WIDGET_SIZE_CHANGED: + __widget_event_widget_size_changed(data); + break; + case WIDGET_EVENT_GBAR_SIZE_CHANGED: + __widget_event_gbar_size_changed(data); + break; + + case WIDGET_EVENT_GBAR_CREATED: + __widget_event_gbar_created(data); + break; + case WIDGET_EVENT_GBAR_DESTROYED: + __widget_event_gbar_destroyed(data); + break; + + case WIDGET_EVENT_HOLD_SCROLL: + __widget_event_hold_scroll(data); + break; + case WIDGET_EVENT_RELEASE_SCROLL: + __widget_event_release_scroll(data); + break; + + case WIDGET_EVENT_WIDGET_UPDATE_BEGIN: + __widget_event_widget_update_begin(data); + break; + case WIDGET_EVENT_WIDGET_UPDATE_END: + __widget_event_widget_update_end(data); + break; + + case WIDGET_EVENT_GBAR_UPDATE_BEGIN: + __widget_event_gbar_update_begin(data); + break; + case WIDGET_EVENT_GBAR_UPDATE_END: + __widget_event_gbar_update_end(data); + break; + + case WIDGET_EVENT_UPDATE_MODE_CHANGED: + __widget_event_update_mode_changed(data); + break; + + case WIDGET_EVENT_REQUEST_CLOSE_GBAR: + __widget_event_request_close_gbar(data); + break; + + case WIDGET_EVENT_IGNORED: + __widget_event_ignored(data); + break; + default: + break; + } + + return 0; +} + +static int widget_fault_handler(enum widget_fault_type fault, const char *pkgname, const char *filename, const char *funcname, void *cbdata) +{ + Eina_List *l = NULL; + Evas_Object *widget; + struct widget_data *data; + struct widget_evas_event_info info; + + switch (fault) { + case WIDGET_FAULT_DEACTIVATED: + EINA_LIST_FOREACH(s_info.list, l, widget) { + data = get_smart_data(widget); + if (!data) { + continue; + } + + if (!strcmp(data->widget_id, pkgname)) { + DbgPrint("Faulted: %s (%p)\n", pkgname, data); + data->is.field.faulted = 1; + __widget_overlay_faulted(data); + info.error = WIDGET_ERROR_FAULT; + info.widget_app_id = data->widget_id; + info.event = WIDGET_FAULT_DEACTIVATED; + smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_FAULTED, &info); + } + } + break; + case WIDGET_FAULT_PROVIDER_DISCONNECTED: + EINA_LIST_FOREACH(s_info.list, l, widget) { + data = get_smart_data(widget); + if (!data) { + continue; + } + + if (!strcmp(data->widget_id, pkgname)) { + DbgPrint("Disconnected: %s (%p)\n", pkgname, data); + data->is.field.faulted = 1; + __widget_overlay_faulted(data); + info.error = WIDGET_ERROR_FAULT; + info.widget_app_id = data->widget_id; + info.event = WIDGET_FAULT_PROVIDER_DISCONNECTED; + smart_callback_call(data, WIDGET_SMART_SIGNAL_PROVIDER_DISCONNECTED, &info); + } + } + break; + default: + break; + } + return 0; +} + +EAPI int widget_viewer_evas_init(Evas_Object *win) +{ + int ret; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!win) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (s_info.initialized) { + ErrPrint("Already initialized\n"); + return WIDGET_ERROR_ALREADY_EXIST; + } + + if (!bindtextdomain(PKGNAME, WIDGET_EVAS_RESOURCE_PO)) { + ErrPrint("bindtextdomain: %d\n", errno); + } else { + DbgPrint("%s - %s\n", PKGNAME, WIDGET_EVAS_RESOURCE_PO); + } + + util_screen_size_get(&s_info.screen_width, &s_info.screen_height); + + s_info.conf.field.render_animator = 0; /* By default, use render animator for updating */ + + ret = widget_viewer_init(util_display_get(), 1, 0.001f, 1); + if (ret < 0) { + return ret; + } + + ret = widget_viewer_add_event_handler(widget_event_handler, NULL); + if (ret != WIDGET_ERROR_NONE) { + ErrPrint("Failed to set handler\n"); + widget_viewer_fini(); + } else { + DbgPrint("Event handler registered\n"); + ret = widget_viewer_add_fault_handler(widget_fault_handler, NULL); + if (ret != WIDGET_ERROR_NONE) { + ErrPrint("Failed to set fault handler\n"); + widget_viewer_remove_event_handler(widget_event_handler); + widget_viewer_fini(); + } else { + DbgPrint("Fault handler is registered\n"); + s_info.initialized = 1; + widget_conf_init(); + widget_conf_load(); + } + } + + /* s_info.conf.field.force_to_buffer = force_to_buffer; */ + s_info.conf.field.force_to_buffer = 0; + s_info.win = win; + + return ret; +} + +EAPI int widget_viewer_evas_fini(void) +{ + int ret; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (s_info.initialized) { + widget_viewer_remove_event_handler(widget_event_handler); + widget_viewer_remove_fault_handler(widget_fault_handler); + widget_viewer_fini(); + widget_conf_reset(); + s_info.initialized = 0; + + ret = WIDGET_ERROR_NONE; + } else { + ret = WIDGET_ERROR_FAULT; + } + + return ret; +} + +EAPI int widget_viewer_evas_notify_resumed_status_of_viewer(void) +{ + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + return widget_viewer_notify_resumed_status_of_viewer(); +} + +EAPI int widget_viewer_evas_notify_paused_status_of_viewer(void) +{ + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + return widget_viewer_notify_paused_status_of_viewer(); +} + +EAPI int widget_viewer_evas_notify_orientation_of_viewer(int orientation) +{ + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + return widget_viewer_notify_orientation_of_viewer(orientation); +} + +EAPI Evas_Object *widget_viewer_evas_add_widget(Evas_Object *parent, const char *widget_id, const char *content_info, double period) +{ + struct widget_data *data; + Evas_Object *widget; + char *_widget_id; + char *_content_info; + char *_cluster; + char *_category; + char *cluster = DEFAULT_CLUSTER; + char *category = DEFAULT_CATEGORY; + + if (!is_widget_feature_enabled()) { + return NULL; + } + + if (!s_info.initialized) { + ErrPrint("Viewer is not initialized\n"); + return NULL; + } + + if (!parent || !widget_id) { + return NULL; + } + + _cluster = strdup(cluster); + if (!_cluster) { + ErrPrint("Heap: %d\n", errno); + return NULL; + } + + _category = strdup(category); + if (!_category) { + ErrPrint("Heap: %d\n", errno); + free(_cluster); + return NULL; + } + + _widget_id = strdup(widget_id); + if (!_widget_id) { + ErrPrint("Heap: %d\n", errno); + free(_category); + free(_cluster); + return NULL; + } + + if (content_info) { + _content_info = strdup(content_info); + if (!_content_info) { + ErrPrint("Heap: %d\n", errno); + free(_widget_id); + free(_category); + free(_cluster); + return NULL; + } + } else { + _content_info = NULL; + } + + if (!s_info.smart) { + s_info.sc.add = __widget_add; + s_info.sc.del = __widget_del; + s_info.sc.move = __widget_move; + s_info.sc.resize = __widget_resize; + s_info.sc.show = __widget_show; + s_info.sc.hide = __widget_hide; + s_info.sc.color_set = __widget_color_set; + s_info.sc.clip_set = __widget_clip_set; + s_info.sc.clip_unset = __widget_clip_unset; + + s_info.smart = evas_smart_class_new(&s_info.sc); + } + + widget = evas_object_smart_add(evas_object_evas_get(parent), s_info.smart); + + data = evas_object_smart_data_get(widget); + if (data) { + data->parent = parent; + data->widget_id = _widget_id; + data->content = _content_info; + data->cluster = _cluster; + data->category = _category; + data->is.field.mouse_event = 0; + data->period = period; + + __widget_data_setup(data); + } else { + ErrPrint("Failed to get smart data\n"); + free(_widget_id); + free(_content_info); + free(_cluster); + free(_category); + } + + return widget; +} + +EAPI int widget_viewer_evas_set_view_port(Evas_Object *widget, int x, int y, int w, int h) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + data->view_port.x = x; + data->view_port.y = y; + data->view_port.w = w; + data->view_port.h = h; + s_info.conf.field.user_view_port = 1; + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_evas_get_view_port(Evas_Object *widget, int *x, int *y, int *w, int *h) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (x) { + *x = data->view_port.x; + } + + if (y) { + *y = data->view_port.y; + } + + if (w) { + *w = data->view_port.w; + } + + if (h) { + *h = data->view_port.h; + } + + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_evas_set_option(widget_evas_conf_e type, int value) +{ + int ret = WIDGET_ERROR_NONE; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + switch ((int)type) { + case WIDGET_VIEWER_EVAS_SENSITIVE_MOVE: + s_info.conf.field.sensitive_move = value; + break; + case WIDGET_VIEWER_EVAS_EVENT_AUTO_FEED: + s_info.conf.field.auto_feed = value; + break; + case WIDGET_VIEWER_EVAS_EASY_MODE: + s_info.conf.field.easy_mode = value; + break; + case WIDGET_VIEWER_EVAS_USE_FIXED_SIZE: + s_info.conf.field.use_fixed_size = value; + break; + case WIDGET_VIEWER_EVAS_MANUAL_PAUSE_RESUME: + s_info.conf.field.manual_pause_resume = value; + break; + case WIDGET_VIEWER_EVAS_SHARED_CONTENT: + (void)widget_viewer_set_option(WIDGET_OPTION_SHARED_CONTENT, value); + break; + case WIDGET_VIEWER_EVAS_SUPPORT_GBAR: + s_info.conf.field.support_gbar = value; + break; + case WIDGET_VIEWER_EVAS_SCROLL_X: + s_info.conf.field.is_scroll_x = value; + break; + case WIDGET_VIEWER_EVAS_SCROLL_Y: + s_info.conf.field.is_scroll_y = value; + break; + case WIDGET_VIEWER_EVAS_DELAYED_RESUME: + s_info.conf.field.delayed_resume = value; + break; + case WIDGET_VIEWER_EVAS_AUTO_RENDER_SELECTION: + s_info.conf.field.auto_render_selector = value; + break; + case WIDGET_VIEWER_EVAS_DIRECT_UPDATE: + (void)widget_viewer_set_option(WIDGET_OPTION_DIRECT_UPDATE, !!value); + break; + case WIDGET_VIEWER_EVAS_USE_RENDER_ANIMATOR: + if (s_info.conf.field.auto_render_selector) { + DbgPrint("Auto selector enabled, this render_animator option will be changed automatically\n"); + } + + s_info.conf.field.render_animator = !!value; + DbgPrint("Turn %s render animator\n", s_info.conf.field.render_animator ? "on" : "off"); + break; + case WIDGET_VIEWER_EVAS_SKIP_ACQUIRE: + s_info.conf.field.skip_acquire = !!value; + DbgPrint("Turn %s skip-acquire option\n", s_info.conf.field.skip_acquire ? "on" : "off"); + break; + default: + ret = WIDGET_ERROR_INVALID_PARAMETER; + break; + } + + return ret; +} + +EAPI int widget_viewer_evas_pause_widget(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data || !data->is.field.created || !data->handle) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (data->delayed_resume_timer) { + (void)ecore_timer_del(data->delayed_resume_timer); + data->delayed_resume_timer = NULL; + } + + return widget_viewer_set_visibility(data->handle, WIDGET_HIDE_WITH_PAUSE); +} + +EAPI int widget_viewer_evas_resume_widget(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data || !data->is.field.created || !data->handle) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (data->delayed_resume_timer) { + (void)ecore_timer_del(data->delayed_resume_timer); + data->delayed_resume_timer = NULL; + } + + data->is.field.initial_resumed = 1; + return widget_viewer_set_visibility(data->handle, WIDGET_SHOW); +} + +EAPI int widget_viewer_evas_destroy_glance_bar(Evas_Object *widget) +{ + struct widget_data *data; + int ret; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data || data->state != WIDGET_DATA_CREATED || !data->is.field.created || !data->handle || !data->is.field.gbar_created) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + ret = widget_viewer_destroy_glance_bar(data->handle, __widget_destroy_gbar_cb, widget_ref(data)); + if (ret < 0) { + widget_unref(data); + } + + return ret; +} + +EAPI const char *widget_viewer_evas_get_content_info(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return NULL; + } + + if (!s_info.initialized) { + return NULL; + } + + data = get_smart_data(widget); + if (!data || !data->is.field.created || !data->handle) { + return NULL; + } + + return widget_viewer_get_content_string(data->handle); +} + +EAPI const char *widget_viewer_evas_get_title_string(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return NULL; + } + + if (!s_info.initialized) { + return NULL; + } + + data = get_smart_data(widget); + if (!data || !data->is.field.created || !data->handle) { + return NULL; + } + + return widget_viewer_get_title_string(data->handle); +} + +EAPI const char *widget_viewer_evas_get_widget_id(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return NULL; + } + + if (!s_info.initialized) { + return NULL; + } + + data = get_smart_data(widget); + if (!data || data->state != WIDGET_DATA_CREATED) { + return NULL; + } + + return data->widget_id; +} + +EAPI double widget_viewer_evas_get_period(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return 0.0f; + } + + if (!s_info.initialized) { + return 0.0f; + } + + data = get_smart_data(widget); + if (!data || !data->is.field.created || !data->handle) { + return 0.0f; + } + + return data->period; +} + +EAPI void widget_viewer_evas_cancel_click_event(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return; + } + + if (!s_info.initialized) { + return; + } + + data = get_smart_data(widget); + if (!data || !data->is.field.created || !data->handle) { + return; + } + + if (!data->pressed) { + DbgPrint("Cancel ignored\n"); + return; + } + + if (data->is.field.cancel_click == CANCEL_DISABLED) { + data->is.field.cancel_click = CANCEL_USER; + } +} + +#if defined(ELM_ACCESS_ENABLED) +static void access_ret_cb(struct widget *handle, int ret, void *data) +{ + struct access_ret_cb_data *cb_data = data; + + switch (ret) { + case WIDGET_ACCESS_STATUS_ERROR: + ret = WIDGET_ACCESS_RESULT_ERROR; + break; + case WIDGET_ACCESS_STATUS_DONE: + ret = WIDGET_ACCESS_RESULT_DONE; + break; + case WIDGET_ACCESS_STATUS_FIRST: + ret = WIDGET_ACCESS_RESULT_FIRST; + break; + case WIDGET_ACCESS_STATUS_LAST: + ret = WIDGET_ACCESS_RESULT_LAST; + break; + case WIDGET_ACCESS_STATUS_READ: + ret = WIDGET_ACCESS_RESULT_READ; + break; + default: + ret = WIDGET_ACCESS_RESULT_UNKNOWN; + break; + } + + if (cb_data->ret_cb) { + cb_data->ret_cb(cb_data->obj, ret, cb_data->data); + } + + free(cb_data); +} +#endif + +EAPI int widget_viewer_evas_feed_mouse_up_event(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data || !data->is.field.created || !data->handle) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return do_force_mouse_up(data); +} + +EAPI int widget_viewer_evas_feed_access_event(Evas_Object *widget, int type, void *_info, void (*ret_cb)(Evas_Object *obj, int ret, void *data), void *cbdata) +{ + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + +#if defined(ELM_ACCESS_ENABLED) + struct widget_data *data; + Elm_Access_Action_Info *info = _info; + int w; + int h; + struct access_ret_cb_data *cb_data; + int ret; + struct widget_access_event_info ainfo; + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data || !data->is.field.created || !data->handle) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + evas_object_geometry_get(data->widget_layout, NULL, NULL, &w, &h); + ainfo.x = (double)info->x / (double)w; + ainfo.y = (double)info->y / (double)h; + ainfo.info = 0; + + switch (type) { + case ELM_ACCESS_ACTION_HIGHLIGHT: /* highlight an object */ + DbgPrint("Highlight %dx%d ignored\n", info->x, info->y); + break; + case ELM_ACCESS_ACTION_READ: + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + ainfo.type = WIDGET_ACCESS_TYPE_HIGHLIGHT; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_HIGHLIGHT, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_UNHIGHLIGHT: /* unhighlight an object */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + ainfo.type = WIDGET_ACCESS_TYPE_UNHIGHLIGHT; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_HIGHLIGHT, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_HIGHLIGHT_NEXT: /* set highlight to next object */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + ainfo.type = WIDGET_ACCESS_TYPE_HIGHLIGHT_NEXT; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_HIGHLIGHT, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_HIGHLIGHT_PREV: /* set highlight to previous object */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + ainfo.type = WIDGET_ACCESS_TYPE_HIGHLIGHT_NEXT; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_HIGHLIGHT, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_ACTIVATE: /* activate a highlight object */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + ainfo.type = WIDGET_ACCESS_TYPE_NONE; /* meaningless */ + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_ACTIVATE, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_SCROLL: /* scroll if one of highlight object parents * is scrollable */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + switch (info->mouse_type) { + case 0: + ainfo.type = WIDGET_ACCESS_TYPE_DOWN; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_SCROLL, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case 1: + ainfo.type = WIDGET_ACCESS_TYPE_MOVE; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_SCROLL, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case 2: + ainfo.type = WIDGET_ACCESS_TYPE_UP; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_SCROLL, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + default: + ret = WIDGET_ERROR_INVALID_PARAMETER; + free(cb_data); + break; + } + break; + case ELM_ACCESS_ACTION_MOUSE: /* give mouse event to highlight object */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + ainfo.type = WIDGET_ACCESS_TYPE_NONE; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_MOUSE, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_UP: /* change value up of highlight object */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + ainfo.type = WIDGET_ACCESS_TYPE_UP; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_ACTION, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_DOWN: /* change value down of highlight object */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + ainfo.type = WIDGET_ACCESS_TYPE_DOWN; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_ACTION, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_VALUE_CHANGE: /* TODO: deprecate this */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + ainfo.type = WIDGET_ACCESS_TYPE_NONE; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_VALUE_CHANGE, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_BACK: /* go back to a previous view ex: pop naviframe item */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + ainfo.type = WIDGET_ACCESS_TYPE_NONE; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_BACK, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_OVER: /* mouse over an object */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + ainfo.type = WIDGET_ACCESS_TYPE_NONE; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_OVER, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_ENABLE: /* enable highlight and read ability */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + ainfo.type = WIDGET_ACCESS_TYPE_ENABLE; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_ENABLE, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + case ELM_ACCESS_ACTION_DISABLE: /* disable highlight and read ability */ + cb_data = calloc(1, sizeof(*cb_data)); + if (!cb_data) { + ErrPrint("Heap: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cb_data->ret_cb = ret_cb; + cb_data->data = cbdata; + cb_data->obj = widget; + + ainfo.type = WIDGET_ACCESS_TYPE_DISABLE; + ret = widget_viewer_feed_access_event(data->handle, WIDGET_ACCESS_ENABLE, &ainfo, access_ret_cb, cb_data); + if (ret != WIDGET_ERROR_NONE) { + free(cb_data); + } + break; + default: + ret = WIDGET_ERROR_INVALID_PARAMETER; + break; + } + + return ret; +#else + return WIDGET_ERROR_NOT_SUPPORTED; +#endif +} + +/** + * @note + * While displaying "loading" overlay, there is a preview image. + * But if this function is called, the preview image will not be displayed. + * Only the help text will be there. if it is not disabled of course. + */ +EAPI void widget_viewer_evas_disable_preview(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return; + } + + if (!s_info.initialized) { + return; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + data->is.field.disable_preview = 1; +} + +/** + * @note + * While displaying "loading" overlay, there is a help text. + * But if this function is called, the text help message will not be displayed. + * Only the preview image will be there. if it is not disabled of course. + */ +EAPI void widget_viewer_evas_disable_overlay_text(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return; + } + + if (!s_info.initialized) { + return; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + data->is.field.disable_text = 1; +} + +/** + * @note + * This function should be called before resize the widget object after create it. + * If this function is called, the widget object will not display "preview" image. + * Instead of it, the widget content object will be displayed immediately. + */ +EAPI void widget_viewer_evas_disable_loading(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return; + } + + if (!s_info.initialized) { + return; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + data->is.field.disable_loading = 1; +} + +EAPI void widget_viewer_evas_activate_faulted_widget(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return; + } + + if (!s_info.initialized) { + return; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + if (data->is.field.faulted) { + elm_object_signal_emit(data->widget_layout, "mouse,clicked,1", "overlay,content"); + } else { + DbgPrint("widget is not faulted\n"); + } +} + +EAPI bool widget_viewer_evas_is_faulted(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return false; + } + + if (!s_info.initialized) { + return 0; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return 0; + } + + return (bool)data->is.field.faulted; +} + +EAPI int widget_viewer_evas_set_raw_event_callback(widget_evas_raw_event_type_e type, raw_event_cb cb, void *data) +{ + struct raw_event_cbdata *cbdata; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + cbdata = calloc(1, sizeof(*cbdata)); + if (!cbdata) { + ErrPrint("calloc: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + cbdata->cb = cb; + cbdata->data = data; + + switch (type) { + case WIDGET_VIEWER_EVAS_RAW_DELETE: + s_info.raw_event.delete_list = eina_list_append(s_info.raw_event.delete_list, cbdata); + break; + case WIDGET_VIEWER_EVAS_RAW_CREATE: + s_info.raw_event.create_list = eina_list_append(s_info.raw_event.create_list, cbdata); + break; + default: + free(cbdata); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_evas_unset_raw_event_callback(widget_evas_raw_event_type_e type, raw_event_cb cb, void *data) +{ + Eina_List *l; + Eina_List *n; + struct raw_event_cbdata *cbdata; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + switch (type) { + case WIDGET_VIEWER_EVAS_RAW_DELETE: + EINA_LIST_FOREACH_SAFE(s_info.raw_event.delete_list, l, n, cbdata) { + if (cbdata->cb == cb && cbdata->data == data) { + s_info.raw_event.delete_list = eina_list_remove(s_info.raw_event.delete_list, cbdata); + break; + } + } + break; + case WIDGET_VIEWER_EVAS_RAW_CREATE: + EINA_LIST_FOREACH_SAFE(s_info.raw_event.create_list, l, n, cbdata) { + if (cbdata->cb == cb && cbdata->data == data) { + s_info.raw_event.create_list = eina_list_remove(s_info.raw_event.create_list, cbdata); + break; + } + } + break; + default: + break; + } + + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_evas_freeze_visibility(Evas_Object *widget, widget_visibility_status_e status) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + data->is.field.freeze_visibility = 1; + data->freezed_visibility = status; + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_evas_thaw_visibility(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + data->is.field.freeze_visibility = 0; + + return WIDGET_ERROR_NONE; +} + +EAPI bool widget_viewer_evas_is_visibility_frozen(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return false; + } + + if (!s_info.initialized) { + ErrPrint("Not initialized\n"); + return false; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return false; + } + + return (bool)data->is.field.freeze_visibility; +} + +EAPI int widget_viewer_evas_dump_to_file(Evas_Object *widget, const char *filename) +{ + struct widget_data *data; + FILE *fp; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + fp = fopen(filename, "w+"); + if (fp) { + Evas_Object *image; + image = elm_object_part_content_get(data->widget_layout, "widget,content"); + if (image) { + void *data; + Evas_Coord w, h; + evas_object_geometry_get(image, NULL, NULL, &w, &h); + + data = evas_object_image_data_get(image, 0); + if (data) { + fwrite(data, w * h, sizeof(int), fp); + } + } + fclose(fp); + } + + return WIDGET_ERROR_NONE; +} + +EAPI bool widget_viewer_evas_is_widget(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return false; + } + + if (!s_info.initialized) { + return false; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return false; + } + + return true; +} + +EAPI void widget_viewer_evas_set_permanent_delete(Evas_Object *widget, int flag) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return; + } + + if (!s_info.initialized) { + return; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return; + } + + data->is.field.permanent_delete = !!flag; +} + +EAPI int widget_viewer_evas_subscribe_group(const char *cluster, const char *sub_cluster) +{ + struct subscribe_group *group; + Eina_List *l; + int ret; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + if (!cluster || !sub_cluster) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + EINA_LIST_FOREACH(s_info.subscribed_group_list, l, group) { + if (!strcasecmp(group->cluster, cluster) && !strcasecmp(group->sub_cluster, sub_cluster)) { + return WIDGET_ERROR_ALREADY_EXIST; + } + } + + group = calloc(1, sizeof(*group)); + if (!group) { + ErrPrint("calloc: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + group->cluster = strdup(cluster); + if (!group->cluster) { + ErrPrint("strdup: %d\n", errno); + free(group); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + group->sub_cluster = strdup(sub_cluster); + if (!group->sub_cluster) { + ErrPrint("strdup: %d\n", errno); + free(group->cluster); + free(group); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + ret = widget_viewer_subscribe_group(cluster, sub_cluster); + if (ret != WIDGET_ERROR_NONE) { + free(group->sub_cluster); + free(group->cluster); + free(group); + return ret; + } + + s_info.subscribed_group_list = eina_list_append(s_info.subscribed_group_list, group); + + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_evas_unsubscribe_group(const char *cluster, const char *sub_cluster) +{ + struct subscribe_group *group; + Eina_List *l; + Eina_List *n; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + if (!cluster || !sub_cluster) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + EINA_LIST_FOREACH_SAFE(s_info.subscribed_group_list, l, n, group) { + if (!strcasecmp(group->cluster, cluster) && !strcasecmp(group->sub_cluster, sub_cluster)) { + s_info.subscribed_group_list = eina_list_remove(s_info.subscribed_group_list, group); + free(group->cluster); + free(group->sub_cluster); + free(group); + return widget_viewer_unsubscribe_group(cluster, sub_cluster); + } + } + + return WIDGET_ERROR_NOT_EXIST; +} + +EAPI int widget_viewer_evas_subscribe_category(const char *category) +{ + struct subscribe_category *item; + Eina_List *l; + int ret; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + if (!category) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + EINA_LIST_FOREACH(s_info.subscribed_category_list, l, item) { + if (!strcmp(category, item->category)) { + return WIDGET_ERROR_ALREADY_EXIST; + } + } + + item = calloc(1, sizeof(*item)); + if (!item) { + ErrPrint("calloc: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + item->category = strdup(category); + if (!item->category) { + ErrPrint("strdup: %d\n", errno); + free(item); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + ret = widget_viewer_subscribe_category(category); + if (ret != WIDGET_ERROR_NONE) { + free(item->category); + free(item); + return ret; + } + + s_info.subscribed_category_list = eina_list_append(s_info.subscribed_category_list, item); + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_evas_unsubscribe_category(const char *category) +{ + Eina_List *l; + Eina_List *n; + struct subscribe_category *item; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + if (!category) { + return WIDGET_ERROR_INVALID_PARAMETER; + } + + EINA_LIST_FOREACH_SAFE(s_info.subscribed_category_list, l, n, item) { + if (!strcmp(item->category, category)) { + s_info.subscribed_category_list = eina_list_remove(s_info.subscribed_category_list, item); + free(item->category); + free(item); + return widget_viewer_unsubscribe_category(category); + } + } + + return WIDGET_ERROR_NOT_EXIST; +} + +static void text_signal_cb(widget_h handle, int ret, void *data) +{ + /* TODO : add codes to invoke smart event callback function */ +} + +EAPI int widget_viewer_evas_emit_text_signal(Evas_Object *widget, widget_text_signal_s event_info, void *data) +{ + struct widget_data *widget_data_from_evas; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + widget_data_from_evas = get_smart_data(widget); + + if (!widget_data_from_evas) { + ErrPrint("Invalid object\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return widget_viewer_emit_text_signal(widget_data_from_evas->handle, event_info, text_signal_cb, data); +} + +EAPI int widget_viewer_evas_get_instance_id(Evas_Object *widget, char **instance_id) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return widget_viewer_get_instance_id(data->handle, instance_id); +} + +EAPI int widget_viewer_evas_set_widget_option(Evas_Object *widget, widget_option_widget_e option, int value) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + switch (option) { + case WIDGET_OPTION_WIDGET_DELAYED_RESUME: + data->is.field.delayed_resume = (value & 0x03); + break; + case WIDGET_OPTION_WIDGET_DISABLE_OVERLAY_ANIMATION: + data->is.field.disabled_overlay_animation = !!value; + break; + case WIDGET_OPTION_WIDGET_MANUAL_OVERLAY_HIDE: + data->is.field.hide_overlay_manually = !!value; + break; + default: + return WIDGET_ERROR_INVALID_PARAMETER; + } + + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_evas_set_preview_image(Evas_Object *widget, widget_size_type_e type, const char *preview) +{ + struct widget_data *data; + Eina_List *l; + Eina_List *n; + struct preview_info *info; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + EINA_LIST_FOREACH_SAFE(data->preview_list, l, n, info) { + if (info->type == type) { + char *tmp; + + if (preview) { + tmp = strdup(preview); + if (!tmp) { + ErrPrint("strdup: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + free(info->preview); + info->preview = tmp; + return WIDGET_ERROR_NONE; + } + + data->preview_list = eina_list_remove(data->preview_list, info); + free(info->preview); + free(info); + return WIDGET_ERROR_NONE; + } + } + + info = malloc(sizeof(struct preview_info)); + if (!info) { + ErrPrint("malloc: %d\n", errno); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + info->type = type; + info->preview = strdup(preview); + if (!info->preview) { + ErrPrint("strdup: %d\n", errno); + free(info); + return WIDGET_ERROR_OUT_OF_MEMORY; + } + + data->preview_list = eina_list_append(data->preview_list, info); + return WIDGET_ERROR_NONE; +} + +EAPI int widget_viewer_evas_hide_overlay(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (!data->is.field.widget_overlay_loaded) { + /** + * Already disabled + */ + return WIDGET_ERROR_NONE; + } + + if (!data->is.field.hide_overlay_manually) { + DbgPrint("Overlay is not controlled manually\n"); + } + + if (data->overlay_timer) { + ecore_timer_del(data->overlay_timer); + /** + * @note + * data->overlay_timer will be reset'd to NULL by delayed_overlay_disable_cb(). + */ + } + delayed_overlay_disable_cb(data); + + return WIDGET_ERROR_NONE; +} + +/* End of a file */ diff --git a/widget_viewer_evas/widget_viewer_evas.pc.in b/widget_viewer_evas/widget_viewer_evas.pc.in new file mode 100644 index 0000000..87ee6a6 --- /dev/null +++ b/widget_viewer_evas/widget_viewer_evas.pc.in @@ -0,0 +1,12 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: widget_viewer_evas +Description: Support development of the widget Viewer EVAS Frontend library +Version: @VERSION@ +Requires: widget_service widget_viewer +Libs: -L${libdir} -lwidget_viewer_evas +Cflags: -I${includedir} +cppflags: -I${includedir} diff --git a/widget_viewer_sdk/CMakeLists.txt b/widget_viewer_sdk/CMakeLists.txt new file mode 100644 index 0000000..14e7b2a --- /dev/null +++ b/widget_viewer_sdk/CMakeLists.txt @@ -0,0 +1,69 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(widget_viewer_sdk C) + +SET(PACKAGE ${PROJECT_NAME}) +SET(VENDOR "tizen") +SET(PKGNAME "org.${VENDOR}.${PACKAGE}") +SET(PREFIX "/usr/apps/${PKGNAME}") +SET(BINDIR "${PREFIX}/bin") +SET(RESDIR "${PREFIX}/res") +SET(SHARED_RESDIR "${PREFIX}/shared/res") +SET(USRDATADIR "/usr/apps/org.${VENDOR}.${PACKAGE}/data") +SET(DATADIR "/opt/usr/apps/org.${VENDOR}.${PACKAGE}/data") +SET(LOCALEDIR "${RESDIR}/locale") +SET(ICONDIR "/usr/share/icons/default/small") +SET(IMAGEDIR "${RESDIR}/images/${PACKAGE}") +SET(SOUNDDIR "${RESDIR}/sound/${PACKAGE}") +SET(EDJDIR "${RESDIR}/edje") +SET(LIBEXECDIR "${PREFIX}/shared/libexec") + +ADD_DEFINITIONS("-DRESDIR=\"${RESDIR}\"") +ADD_DEFINITIONS("-DSHARED_RESDIR=\"${SHARED_RESDIR}\"") +ADD_DEFINITIONS("-DNDEBUG") +ADD_DEFINITIONS("-DLOG_TAG=\"WIDGET_SDK\"") + +FIND_PROGRAM(UNAME NAMES uname) +EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH") + +IF("${ARCH}" STREQUAL "arm") + ADD_DEFINITIONS("-DTARGET") + MESSAGE("add -DTARGET") +ENDIF("${ARCH}" STREQUAL "arm") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE") + +INCLUDE(FindPkgConfig) +pkg_check_modules(sdk_pkgs REQUIRED + capi-appfw-application + appcore-efl + ecore + evas + edje + vconf + bundle + dlog + widget_service + efl-extension +) + +ADD_DEFINITIONS("-DWIDGET_EVAS_RESOURCE_EDJ=\"${EDJDIR}/widget_viewer_sdk.edj\"") +ADD_DEFINITIONS("-DWIDGET_EVAS_RESOURCE_PD=\"gbar\"") +ADD_DEFINITIONS("-DWIDGET_EVAS_RESOURCE_LB=\"widget\"") +ADD_DEFINITIONS("-DWIDGET_EVAS_RESOURCE_IMG=\"widget,image\"") +ADD_DEFINITIONS(${sdk_pkgs_CFLAGS}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../widget_viewer_evas/include) + +ADD_EXECUTABLE(${PROJECT_NAME} src/main.c) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${sdk_pkgs_LDFLAGS} "-lm -pie -fPIC" widget_viewer_evas) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PKGNAME}.xml DESTINATION /usr/share/packages) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PKGNAME}.efl DESTINATION /etc/smack/accesses.d RENAME ${PKGNAME}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME ${PKGNAME}) +INSTALL(DIRECTORY DESTINATION ${DATADIR}) + +ADD_SUBDIRECTORY(data) + +# End of a file diff --git a/widget_viewer_sdk/LICENSE b/widget_viewer_sdk/LICENSE new file mode 100644 index 0000000..571fe79 --- /dev/null +++ b/widget_viewer_sdk/LICENSE @@ -0,0 +1,206 @@ +Flora License + +Version 1.1, April, 2013 + +http://floralicense.org/license/ + +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. + +"Tizen Certified Platform" shall mean a software platform that complies +with the standards set forth in the Tizen Compliance Specification +and passes the Tizen Compliance Tests as defined from time to time +by the Tizen Technical Steering Group and certified by the Tizen +Association or its designated agent. + +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 +solely as incorporated into a Tizen Certified Platform, 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 solely +as incorporated into a Tizen Certified Platform 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 pursuant to the copyright license +above, in any medium, with or without modifications, and in Source or +Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works + a copy of this License; and + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + 3. 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 + 4. 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 + and your own copyright statement or terms and conditions do not conflict + the conditions stated in the License including section 3. + +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 Flora License to your work + +To apply the Flora 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 Flora License, Version 1.1 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://floralicense.org/license/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT 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/widget_viewer_sdk/data/CMakeLists.txt b/widget_viewer_sdk/data/CMakeLists.txt new file mode 100644 index 0000000..7170a8b --- /dev/null +++ b/widget_viewer_sdk/data/CMakeLists.txt @@ -0,0 +1,11 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# install edj +ADD_CUSTOM_TARGET(widget_viewer_sdk.edj + COMMAND edje_cc -id ${CMAKE_CURRENT_SOURCE_DIR}/images ${EDJE_CFLAGS} + ${CMAKE_CURRENT_SOURCE_DIR}/widget_viewer_sdk.edc widget_viewer_sdk.edj + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/widget_viewer_sdk.edc +) +ADD_DEPENDENCIES(${PROJECT_NAME} widget_viewer_sdk.edj) +INSTALL(FILES widget_viewer_sdk.edj DESTINATION ${EDJDIR}) +INSTALL(FILES images/unknown.png DESTINATION ${SHARED_RESDIR}/images) diff --git a/widget_viewer_sdk/data/images/unknown.png b/widget_viewer_sdk/data/images/unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..535db6063ad8e69e355c808507480f46ab0ea5bc GIT binary patch literal 19568 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

e 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 + + + Sungjae Park + Widget Viewer for SDK + + + http://tizen.org/privilege/application.launch + http://tizen.org/privilege/system + + + + + + + org.tizen.widget_viewer_sdk + + diff --git a/widget_viewer_sdk/src/main.c b/widget_viewer_sdk/src/main.c new file mode 100644 index 0000000..c1d6861 --- /dev/null +++ b/widget_viewer_sdk/src/main.c @@ -0,0 +1,738 @@ +/* + * Copyright 2014 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include +#include +#include +#include +#include +#include +#include +#include + +int errno; + +#include "main.h" +#include "debug.h" + +#define WATCH_CATEGORY "http://tizen.org/category/wearable_clock" +#define DEFAULT_WATCH "org.tizen.digitalclock" +#define LAZY_WATCH_TIME 3.0f +#define CR 13 +#define LF 10 + +static struct info { + int w; + int h; + Evas_Object *win; + Evas_Object *bg; + Evas_Object *box; + Evas_Object *layout; + Ecore_Timer *long_press; + + struct ctx_item { + char *content_info; + char *title; + double period; + Evas_Object *widget; + int *size_types; + int count_of_size_type; + } ctx; + + Ecore_Timer *lazy_widget_loader; + double lazy_watch_time; + char *default_watch; + char *watch_category; +} s_info = { + .w = 0, + .h = 0, + .win = NULL, + .layout = NULL, + .long_press = NULL, + + .ctx = { + .content_info = NULL, + .title = NULL, + .period = WIDGET_VIEWER_EVAS_DEFAULT_PERIOD, + .widget = NULL, + .size_types = NULL, + .count_of_size_type = 20, + }, + + .lazy_widget_loader = NULL, + .lazy_watch_time = LAZY_WATCH_TIME, + .default_watch = DEFAULT_WATCH, + .watch_category = WATCH_CATEGORY, +}; + +#define LONG_PRESS 1.0f +#define CONF_FNAME "/etc/widget_viewer_sdk.conf" + +static void watch_category_handler(char *buffer) +{ + char *old_category; + + old_category = s_info.watch_category; + + s_info.watch_category = strdup(buffer); + if (!s_info.watch_category) { + ErrPrint("strdup: %d\n", errno); + s_info.watch_category = old_category; + } else if ((long)old_category != (long)WATCH_CATEGORY) { /** Forcely compare the address */ + free(old_category); + } + + DbgPrint("Watch category: [%s]\n", s_info.watch_category); +} + +static void default_watch_handler(char *buffer) +{ + char *old_watch; + + old_watch = s_info.default_watch; + + s_info.default_watch = strdup(buffer); + if (!s_info.default_watch) { + ErrPrint("strdup: %d\n", errno); + s_info.default_watch = old_watch; + } else if ((long)old_watch != (long)DEFAULT_WATCH) { /** Forcely compare the address */ + free(old_watch); + } + + DbgPrint("Default watch: [%s]\n", s_info.default_watch); +} + +static void lazy_load_time_handler(char *buffer) +{ + double val; + if (sscanf(buffer, "%lf", &val) != 1) { + ErrPrint("Unable to parse data: [%s]\n", buffer); + return; + } + + if (val < 0.0f) { + ErrPrint("Invalid value: %lf\n", val); + val = LAZY_WATCH_TIME; + } + + s_info.lazy_watch_time = val; + DbgPrint("Lazy watch time: %lf\n", s_info.lazy_watch_time); +} + +static void load_configuration(void) +{ + static const widget_conf_parser_table_t token_handler[] = { + { + .name = "watch_category", + .handler = watch_category_handler, + }, + { + .name = "default_watch", + .handler = default_watch_handler, + }, + { + .name = "lazy_load_time", + .handler = lazy_load_time_handler, + }, + { + .name = NULL, + .handler = NULL, + }, + }; + + (void)widget_conf_parser(CONF_FNAME, token_handler); +} + +static void back_key_cb(void *data, Evas_Object *obj, void *event_info) +{ + ui_app_exit(); +} + +static void hide_widget_info_cb(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + DbgPrint("Hide info panel\n"); + elm_object_signal_emit(s_info.layout, "hide", "info"); +} + +static Eina_Bool show_widget_info_cb(void *data) +{ + DbgPrint("Show info panel\n"); + elm_object_signal_emit(s_info.layout, "show", "info"); + + s_info.long_press = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static void layout_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + if (s_info.long_press) { + ecore_timer_del(s_info.long_press); + s_info.long_press = NULL; + } + + s_info.long_press = ecore_timer_add(LONG_PRESS, show_widget_info_cb, NULL); + if (!s_info.long_press) { + ErrPrint("Failed to add a timer\n"); + } +} + +static void layout_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + if (s_info.long_press) { + ecore_timer_del(s_info.long_press); + s_info.long_press = NULL; + } +} + +static bool app_create(void *data) +{ + load_configuration(); + + s_info.win = elm_win_add(NULL, "Widget Viewer (SDK)", ELM_WIN_BASIC); + if (!s_info.win) { + LOGD("Failed to create a window\n"); + return false; + } + + evas_object_show(s_info.win); + + elm_win_screen_size_get(s_info.win, NULL, NULL, &s_info.w, &s_info.h); + LOGD("Window: %dx%d\n", s_info.w, s_info.h); + + s_info.bg = elm_bg_add(s_info.win); + if (!s_info.bg) { + ErrPrint("Failed to add a BG\n"); + evas_object_del(s_info.win); + s_info.win = NULL; + return false; + } + + elm_win_resize_object_add(s_info.win, s_info.bg); + elm_bg_color_set(s_info.bg, 0, 0, 0); + evas_object_show(s_info.bg); + + s_info.box = elm_box_add(s_info.win); + if (!s_info.box) { + evas_object_del(s_info.bg); + evas_object_del(s_info.win); + s_info.bg = NULL; + s_info.win = NULL; + return false; + } + evas_object_size_hint_expand_set(s_info.box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_fill_set(s_info.box, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_box_align_set(s_info.box, 0.5, 0.5); + + s_info.layout = elm_layout_add(s_info.win); + if (!s_info.layout) { + evas_object_del(s_info.box); + evas_object_del(s_info.bg); + evas_object_del(s_info.win); + s_info.box = NULL; + s_info.win = NULL; + s_info.bg = NULL; + return false; + } + + if (elm_layout_file_set(s_info.layout, LAYOUT_EDJ, "layout") != EINA_TRUE) { + LOGE("Failed to load an edje\n"); + evas_object_del(s_info.bg); + evas_object_del(s_info.layout); + evas_object_del(s_info.win); + s_info.bg = NULL; + s_info.layout = NULL; + s_info.win = NULL; + return false; + } + evas_object_size_hint_expand_set(s_info.layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_fill_set(s_info.layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_win_resize_object_add(s_info.win, s_info.layout); + evas_object_show(s_info.layout); + + elm_object_signal_callback_add(s_info.layout, "mouse,clicked,1", "widget,info,bg", hide_widget_info_cb, NULL); + evas_object_event_callback_add(s_info.layout, EVAS_CALLBACK_MOUSE_DOWN, layout_down_cb, NULL); + evas_object_event_callback_add(s_info.layout, EVAS_CALLBACK_MOUSE_UP, layout_up_cb, NULL); + + elm_object_part_content_set(s_info.layout, "widget", s_info.box); + + /* WIDGET init */ + widget_viewer_evas_set_option(WIDGET_VIEWER_EVAS_DIRECT_UPDATE, 1); + widget_viewer_evas_set_option(WIDGET_VIEWER_EVAS_EVENT_AUTO_FEED, 1); + + widget_viewer_evas_init(s_info.win); + + eext_object_event_callback_add(s_info.win, EEXT_CALLBACK_BACK, back_key_cb, NULL); + + return true; +} + +static int unload_widget(void) +{ + const char *tmp; + + if (!s_info.ctx.widget) { + return WIDGET_ERROR_NOT_EXIST; + } + + tmp = widget_viewer_evas_get_widget_id(s_info.ctx.widget); + DbgPrint("Unload previous widget: %s\n", tmp); + + widget_viewer_evas_set_permanent_delete(s_info.ctx.widget, EINA_TRUE); + elm_box_unpack(s_info.box, s_info.ctx.widget); + evas_object_del(s_info.ctx.widget); + free(s_info.ctx.title); + free(s_info.ctx.content_info); + free(s_info.ctx.size_types); + + s_info.ctx.widget = NULL; + s_info.ctx.title = NULL; + s_info.ctx.content_info = NULL; + s_info.ctx.size_types = NULL; + s_info.ctx.period = WIDGET_VIEWER_EVAS_DEFAULT_PERIOD; + s_info.ctx.count_of_size_type = 20; + + elm_object_part_text_set(s_info.layout, "widget,id", ""); + elm_object_part_text_set(s_info.layout, "widget,content,info", ""); + elm_object_part_text_set(s_info.layout, "widget,title", ""); + elm_object_part_text_set(s_info.layout, "widget,period", ""); + + return WIDGET_ERROR_NONE; +} + +static void app_terminate(void *data) +{ + eext_object_event_callback_del(s_info.win, EEXT_CALLBACK_BACK, back_key_cb); + + unload_widget(); + + /* WIDGET fini */ + widget_viewer_evas_fini(); + + if (s_info.win) { + evas_object_del(s_info.win); + s_info.win = NULL; + } +} + +static void app_pause(void *data) +{ + /* WIDGET pause */ + widget_viewer_evas_notify_paused_status_of_viewer(); +} + +static void app_resume(void *data) +{ + /* WIDGET resume */ + widget_viewer_evas_notify_resumed_status_of_viewer(); +} + +static void updated_cb(void *data, Evas_Object *obj, void *event_info) +{ + /* Updated */ + DbgPrint("Widget updated\n"); +} + +static void list_item_clicked_cb(void *data, Evas_Object *obj, void *event_info) +{ + int w; + int h; + + if (widget_service_get_size(s_info.ctx.size_types[(long)data], &w, &h) != WIDGET_ERROR_NONE) { + return; + } + + evas_object_resize(s_info.ctx.widget, w, h); + evas_object_size_hint_min_set(s_info.ctx.widget, w, h); + evas_object_size_hint_max_set(s_info.ctx.widget, w, h); +} + +static void extra_updated_cb(void *data, Evas_Object *obj, void *event_info) +{ + const char *string; + char *tmp; + + string = widget_viewer_evas_get_title_string(obj); + if (string) { + tmp = strdup(string); + if (!tmp) { + return; + } + + free(s_info.ctx.title); + s_info.ctx.title = tmp; + + elm_object_part_text_set(s_info.layout, "widget,title", s_info.ctx.title); + } + + string = widget_viewer_evas_get_content_info(obj); + if (string) { + tmp = strdup(string); + if (!tmp) { + return; + } + + free(s_info.ctx.content_info); + s_info.ctx.content_info = tmp; + + elm_object_part_text_set(s_info.layout, "widget,content,info", s_info.ctx.content_info); + DbgPrint("Content updated: [%s]\n", s_info.ctx.content_info); + } +} + +static void period_changed_cb(void *data, Evas_Object *obj, void *event_info) +{ + char buffer[96]; + + s_info.ctx.period = widget_viewer_evas_get_period(obj); + snprintf(buffer, sizeof(buffer), "%lf", s_info.ctx.period); + elm_object_part_text_set(s_info.layout, "widget,period", buffer); + DbgPrint("Period updated: %s\n", buffer); +} + +static void update_message(const char *fmt, ...) +{ + if (!fmt) { + elm_object_signal_emit(s_info.layout, "hide", "message"); + } else { + va_list ap; + char buffer[1024]; + + va_start(ap, fmt); + vsnprintf(buffer, sizeof(buffer) - 1, fmt, ap); + va_end(ap); + + elm_object_part_text_set(s_info.layout, "message", buffer); + elm_object_signal_emit(s_info.layout, "show", "message"); + ErrPrint("%s", buffer); + } +} + +static void widget_create_aborted_cb(void *data, Evas_Object *obj, void *event_info) +{ + update_message("Create aborted"); +} + +static void widget_created_cb(void *data, Evas_Object *obj, void *event_info) +{ + period_changed_cb(data, obj, NULL); + extra_updated_cb(data, obj, NULL); +} + +static int load_widget(const char *widget_id) +{ + int w = 0; + int h = 0; + int i; + + for (i = 0; i < s_info.ctx.count_of_size_type; i++) { + if (widget_service_get_size(s_info.ctx.size_types[i], &w, &h) != WIDGET_ERROR_NONE || w == 0 || h == 0) { + continue; + } + + break; + } + + if (i == s_info.ctx.count_of_size_type) { + Evas_Object *rect; + + rect = evas_object_rectangle_add(evas_object_evas_get(s_info.layout)); + evas_object_resize(rect, s_info.w, s_info.h); + evas_object_size_hint_min_set(rect, s_info.w, s_info.h); + evas_object_color_set(rect, 100, 100, 100, 255); + evas_object_show(rect); + elm_box_pack_end(s_info.box, rect); + + update_message("Supported size is not found"); + return WIDGET_ERROR_NOT_SUPPORTED; + } + update_message(NULL); + + DbgPrint("Found valid size[%X]: %dx%d\n", s_info.ctx.size_types[i], w, h); + + s_info.ctx.widget = widget_viewer_evas_add_widget(s_info.win, widget_id, s_info.ctx.content_info, s_info.ctx.period); + if (!s_info.ctx.widget) { + update_message("Failed to create a new widget"); + return WIDGET_ERROR_FAULT; + } + + DbgPrint("Resize the widget(%s) to [%X] %dx%d\n", widget_id, s_info.ctx.size_types[0], w, h); + + evas_object_smart_callback_add(s_info.ctx.widget, WIDGET_SMART_SIGNAL_UPDATED, updated_cb, NULL); + evas_object_smart_callback_add(s_info.ctx.widget, WIDGET_SMART_SIGNAL_EXTRA_INFO_UPDATED, extra_updated_cb, NULL); + evas_object_smart_callback_add(s_info.ctx.widget, WIDGET_SMART_SIGNAL_PERIOD_CHANGED, period_changed_cb, NULL); + evas_object_smart_callback_add(s_info.ctx.widget, WIDGET_SMART_SIGNAL_WIDGET_CREATED, widget_created_cb, NULL); + evas_object_smart_callback_add(s_info.ctx.widget, WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED, widget_create_aborted_cb, NULL); + + elm_object_part_text_set(s_info.layout, "widget,id", widget_id); + elm_box_pack_end(s_info.box, s_info.ctx.widget); + + evas_object_resize(s_info.ctx.widget, w, h); + evas_object_size_hint_min_set(s_info.ctx.widget, w, h); + evas_object_size_hint_max_set(s_info.ctx.widget, w, h); + evas_object_show(s_info.ctx.widget); + + return WIDGET_ERROR_NONE; +} + +static char *list_item_text_get_cb(void *data, Evas_Object *obj, const char *part) +{ + char buffer[256]; + int ret; + int w; + int h; + + ret = widget_service_get_size(s_info.ctx.size_types[(long)data], &w, &h); + if (ret != WIDGET_ERROR_NONE) { + return strdup("Invalid"); + } + + snprintf(buffer, sizeof(buffer), "%dx%d", w, h); + DbgPrint("Size: [%s]\n", buffer); + return strdup(buffer); +} + +static Evas_Object *list_item_content_get_cb(void *data, Evas_Object *obj, const char *part) +{ + Evas_Object *icon = NULL; + char *icon_filename; + const char *widget_id; + + widget_id = widget_viewer_evas_get_widget_id(s_info.ctx.widget); + + icon_filename = widget_service_get_preview_image_path(widget_id, s_info.ctx.size_types[(long)data]); + if (icon_filename) { + icon = elm_icon_add(s_info.win); + if (icon) { + elm_image_file_set(icon, icon_filename, NULL); + elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE); + evas_object_size_hint_max_set(icon, 100, 100); + DbgPrint("Icon: %s\n", icon_filename); + } + free(icon_filename); + } else { + icon = NULL; + } + + return icon; +} + +static int prepare_widget(const char *widget_id, app_control_h control) +{ + int ret; + Evas_Object *size_list; + Elm_Object_Item *item; + long i; + int w; + int h; + bundle *b; + static Elm_Genlist_Item_Class class = { + .item_style = "1text.1icon", + .func = { + .text_get = list_item_text_get_cb, + .content_get = list_item_content_get_cb, + .state_get = NULL, + .del = NULL, + } + }; + + if (app_control_export_as_bundle(control, &b) == APP_CONTROL_ERROR_NONE) { + bundle_raw *r; + int len; + + if (bundle_encode(b, &r, &len) == BUNDLE_ERROR_NONE) { + s_info.ctx.content_info = malloc(len + 8); + if (!s_info.ctx.content_info) { + ErrPrint("malloc: %d\n", errno); + } else { + snprintf(s_info.ctx.content_info, len + 8, "%d:%s", len, (char *)r); + DbgPrint("Encoded content_info: [%s]\n", s_info.ctx.content_info); + } + + free((char *)r); /* Do I have to use the g_free? */ + } else { + ErrPrint("Failed to encode a bundle\n"); + } + + bundle_free(b); + } + + s_info.ctx.count_of_size_type = 20; + ret = widget_service_get_supported_size_types(widget_id, &s_info.ctx.count_of_size_type, &s_info.ctx.size_types); + if (ret != WIDGET_ERROR_NONE) { + ErrPrint("Failed to load an widget\n"); + } + + DbgPrint("[%s] %d\n", widget_id, s_info.ctx.count_of_size_type); + + if (s_info.ctx.count_of_size_type <= 1) { + elm_object_signal_emit(s_info.layout, "hide", "size,list"); + return WIDGET_ERROR_NONE; + } else { + elm_object_signal_emit(s_info.layout, "show", "size,list"); + } + + size_list = elm_object_part_content_get(s_info.layout, "widget,size,list"); + if (size_list) { + elm_genlist_clear(size_list); + } else { + size_list = elm_genlist_add(s_info.win); + if (!size_list) { + ErrPrint("Failed to create a genlist\n"); + return WIDGET_ERROR_FAULT; + } + + elm_object_part_content_set(s_info.layout, "widget,size,list", size_list); + } + + DbgPrint("========\nDump supported size types [%s]\n", widget_id); + for (i = 0; i < s_info.ctx.count_of_size_type; i++) { + if (widget_service_get_size(s_info.ctx.size_types[i], &w, &h) != WIDGET_ERROR_NONE || w == 0 || h == 0) { + DbgPrint("[%X] is not supported (%dx%d)\n", s_info.ctx.size_types[i], w, h); + continue; + } + + DbgPrint("Size[%X]\n", s_info.ctx.size_types[i]); + item = elm_genlist_item_append(size_list, &class, (void *)i, NULL, ELM_GENLIST_ITEM_NONE, list_item_clicked_cb, (void *)i); + if (!item) { + ErrPrint("Failed to add a new size item\n"); + } + } + DbgPrint("========\nEnd of a dump\n"); + + return ret; +} + +static Eina_Bool lazy_widget_loader_cb(void *widget_id) +{ + DbgPrint("Lazy loader expired. load widget [%s]\n", widget_id); + + (void)load_widget(widget_id); + free(widget_id); + s_info.lazy_widget_loader = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static void _app_control(app_control_h service, void *data) +{ + char *widget_id = NULL; + int ret; + + ret = app_control_get_extra_data(service, WIDGET_APPID, &widget_id); + if (ret == APP_CONTROL_ERROR_NONE) { + char *category; + int lazy_loader = 0; + + DbgPrint("Loading a widget: [%s]\n", widget_id); + if (!widget_id) { + return; + } + + category = widget_service_get_category(widget_id); + if (category) { + if (!strcmp(category, WATCH_CATEGORY)) { + /** + * Trying to unload the WATCH from W-HOME + */ + char *watch_id; + int need_to_unload = 0; + + watch_id = vconf_get_str(VCONFKEY_WMS_CLOCKS_SET_IDLE); + if (watch_id) { + need_to_unload = !!strcmp(watch_id, s_info.default_watch); + free(watch_id); + } + + if (need_to_unload) { + DbgPrint("Watch: [%s] - unload first, SET(%s)\n", widget_id, s_info.default_watch); + ret = vconf_set_str(VCONFKEY_WMS_CLOCKS_SET_IDLE, s_info.default_watch); + if (ret != 0) { + ErrPrint("If this is not wearable, there is no such CLOCKS_SET_IDLE key (%d)\n", ret); + } + + /** + * @note + * In this case, we should waiting some time to unload watch first. + */ + lazy_loader = 1; + } + } + free(category); + } + + ret = unload_widget(); + ret = prepare_widget(widget_id, service); + + if (s_info.lazy_widget_loader) { + char *tmp; + tmp = ecore_timer_del(s_info.lazy_widget_loader); + free(tmp); + } + + if (lazy_loader) { + DbgPrint("Load a watch after some time later (%lf)\n", s_info.lazy_watch_time); + s_info.lazy_widget_loader = ecore_timer_add(s_info.lazy_watch_time, lazy_widget_loader_cb, widget_id); + if (!s_info.lazy_widget_loader) { + ErrPrint("Unable to fire the timer\n"); + lazy_widget_loader_cb(widget_id); + } + /** + * @note + * widget_id will be deleted from lazy_widget_loader_cb. or return value of ecore_timer_del(). + */ + } else { + DbgPrint("Immediately loads the watch[%s]\n", widget_id); + lazy_widget_loader_cb(widget_id); + } + } else { + /** + * @note + * Just raise up the window and notify to resumed state + */ + widget_viewer_evas_notify_resumed_status_of_viewer(); + elm_win_activate(s_info.win); + } +} + +int main(int argc, char *argv[]) +{ + ui_app_lifecycle_callback_s event_callback; + + event_callback.create = app_create; + event_callback.terminate = app_terminate; + event_callback.pause = app_pause; + event_callback.resume = app_resume; + event_callback.app_control = _app_control; + + if (setenv("BUFMGR_LOCK_TYPE", "once", 0) < 0) { + LOGE("setenv(BUFMGR_LOCK_TYPE) is failed: %s", strerror(errno)); + } + + if (setenv("BUFMGR_MAP_CACHE", "true", 0) < 0) { + LOGE("setenv(BUFMGR_MAP_CACHE) is failed: %s", strerror(errno)); + } + + return ui_app_main(argc, argv, &event_callback, NULL); +} + +/* End of a file */ -- 2.7.4 From c19b6d90c38cdc0d5b336ede42ccce0e28af56db Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Sat, 24 Oct 2015 15:49:41 +0900 Subject: [PATCH 3/3] tizen 2.4 release --- CMakeLists.txt | 2 + packaging/libwidget_viewer.spec | 43 +- widget_viewer/include/debug.h | 4 +- widget_viewer/include/util.h | 1 - widget_viewer/include/widget_viewer.h | 6 +- widget_viewer/src/client.c | 17 +- widget_viewer/src/util.c | 13 - widget_viewer/src/widget.c | 11 +- widget_viewer/src/widget_internal.c | 2 +- widget_viewer_dali/CMakeLists.txt | 68 +++ widget_viewer_dali/LICENSE | 206 +++++++++ widget_viewer_dali/include/widget_dali.h | 97 ++++ widget_viewer_dali/include/widget_dali_impl.h | 161 +++++++ widget_viewer_dali/include/widget_dali_list.h | 52 +++ widget_viewer_dali/include/widget_viewer_dali.h | 73 +++ .../include/widget_viewer_dali_const.h | 113 +++++ .../include/widget_viewer_dali_generic.h | 102 +++++ widget_viewer_dali/res/image/btn_delete_nor.png | Bin 0 -> 2436 bytes widget_viewer_dali/res/image/btn_delete_press.png | Bin 0 -> 2598 bytes .../src/common/widget_viewer_dali_const.cpp | 147 ++++++ widget_viewer_dali/src/widget_dali.cpp | 209 +++++++++ widget_viewer_dali/src/widget_dali_impl.cpp | 491 +++++++++++++++++++++ widget_viewer_dali/src/widget_dali_list.cpp | 113 +++++ widget_viewer_dali/src/widget_viewer_dali.cpp | 426 ++++++++++++++++++ widget_viewer_dali/widget_viewer_dali.pc.in | 12 + widget_viewer_evas/doc/widget_viewer_evas_doc.h | 4 + widget_viewer_evas/include/widget_viewer_evas.h | 96 +++- .../include/widget_viewer_evas_internal.h | 3 + widget_viewer_evas/src/widget_viewer_evas.c | 319 ++++++++++--- widget_viewer_sdk/include/debug.h | 4 +- widget_viewer_sdk/org.tizen.widget_viewer_sdk.efl | 8 +- widget_viewer_sdk/src/main.c | 4 + 32 files changed, 2700 insertions(+), 107 deletions(-) mode change 100644 => 100755 CMakeLists.txt mode change 100644 => 100755 packaging/libwidget_viewer.spec mode change 100644 => 100755 widget_viewer/include/widget_viewer.h create mode 100755 widget_viewer_dali/CMakeLists.txt create mode 100755 widget_viewer_dali/LICENSE create mode 100755 widget_viewer_dali/include/widget_dali.h create mode 100755 widget_viewer_dali/include/widget_dali_impl.h create mode 100755 widget_viewer_dali/include/widget_dali_list.h create mode 100755 widget_viewer_dali/include/widget_viewer_dali.h create mode 100755 widget_viewer_dali/include/widget_viewer_dali_const.h create mode 100755 widget_viewer_dali/include/widget_viewer_dali_generic.h create mode 100755 widget_viewer_dali/res/image/btn_delete_nor.png create mode 100755 widget_viewer_dali/res/image/btn_delete_press.png create mode 100755 widget_viewer_dali/src/common/widget_viewer_dali_const.cpp create mode 100755 widget_viewer_dali/src/widget_dali.cpp create mode 100755 widget_viewer_dali/src/widget_dali_impl.cpp create mode 100755 widget_viewer_dali/src/widget_dali_list.cpp create mode 100755 widget_viewer_dali/src/widget_viewer_dali.cpp create mode 100755 widget_viewer_dali/widget_viewer_dali.pc.in diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100644 new mode 100755 index b289f6d..71ab3f7 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) ADD_SUBDIRECTORY(widget_viewer) ADD_SUBDIRECTORY(widget_viewer_evas) ADD_SUBDIRECTORY(widget_viewer_sdk) +#ADD_SUBDIRECTORY(widget_viewer_dali) ADD_DEPENDENCIES(widget_viewer_evas widget_viewer) +#ADD_DEPENDENCIES(widget_viewer_dali widget_viewer) ADD_DEPENDENCIES(widget_viewer_sdk widget_viewer_evas) diff --git a/packaging/libwidget_viewer.spec b/packaging/libwidget_viewer.spec old mode 100644 new mode 100755 index d1273d0..8d139cc --- a/packaging/libwidget_viewer.spec +++ b/packaging/libwidget_viewer.spec @@ -2,7 +2,7 @@ Name: libwidget_viewer Summary: Library for developing the application -Version: 1.2.1 +Version: 1.2.2 Release: 1 Group: Applications/Core Applications License: Flora-1.1 @@ -25,6 +25,9 @@ BuildRequires: pkgconfig(capi-appfw-application) BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(efl-extension) +#BuildRequires: pkgconfig(dali) +#BuildRequires: pkgconfig(dali-core) +#BuildRequires: pkgconfig(dali-toolkit) %if %{with wayland} BuildRequires: pkgconfig(wayland-client) @@ -32,6 +35,8 @@ BuildRequires: pkgconfig(libtbm) %else BuildRequires: pkgconfig(x11) BuildRequires: pkgconfig(xext) +BuildRequires: pkgconfig(ecore-x) +BuildRequires: pkgconfig(ecore) %endif %description @@ -90,6 +95,27 @@ rm -rf %{buildroot} %{_libdir}/pkgconfig/widget_viewer.pc ################################################# +## libwidget_viewer_dali +#%package -n %{name}_dali +#Summary: Library for developing the widget viewer dali +#Group: Applications/Core Applications +#License: Flora-1.1 +# +#%description -n %{name}_dali +#Provider APIs to develop the widget viewer Dali application. +# +#%package -n %{name}_dali-devel +#Summary: Widget viewer application development library (dev) (Dali version) +#Group: Development/Libraries +#Requires: %{name}_dali +# +#%description -n %{name}_dali-devel +#Header & package configuration files to support development of the widget viewer applications. (for Dali app) +# +#%post -n %{name}_dali -p /sbin/ldconfig +#%postun -n %{name}_dali -p /sbin/ldconfig +# +################################################# # libwidget_viewer_evas %package -n %{name}_evas Summary: Library for developing the widget viewer evas @@ -125,6 +151,21 @@ While developing the widget applications, this viewer will load it and execute i %post -n org.tizen.widget_viewer_sdk -p /sbin/ldconfig %postun -n org.tizen.widget_viewer_sdk -p /sbin/ldconfig +#%files -n %{name}_dali +#%manifest %{name}.manifest +#%defattr(-,root,root,-) +#%{_libdir}/%{name}_dali.so* +#%{_datadir}/widget_viewer_dali/* +#%{_datarootdir}/license/%{name}_dali +# +#%files -n %{name}_dali-devel +#%manifest %{name}.manifest +#%defattr(-,root,root,-) +#%{_includedir}/widget_viewer_dali/widget_viewer_dali.h +#%{_includedir}/widget_viewer_dali/widget_dali.h +#%{_includedir}/widget_viewer_dali/widget_viewer_dali_generic.h +#%{_libdir}/pkgconfig/widget_viewer_dali.pc + %files -n %{name}_evas %manifest %{name}.manifest %defattr(-,root,root,-) diff --git a/widget_viewer/include/debug.h b/widget_viewer/include/debug.h index a6563ee..483309e 100644 --- a/widget_viewer/include/debug.h +++ b/widget_viewer/include/debug.h @@ -19,9 +19,9 @@ #define ErrPrint(format, arg...) SECURE_LOGE(format, ##arg) #else extern FILE *__file_log_fp; -#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) +#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [%s/%s:%d] " format, widget_util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) -#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) +#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [%s/%s:%d] " format, widget_util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) #endif diff --git a/widget_viewer/include/util.h b/widget_viewer/include/util.h index 498a249..b463568 100644 --- a/widget_viewer/include/util.h +++ b/widget_viewer/include/util.h @@ -16,7 +16,6 @@ extern int util_check_extension(const char *filename, const char *check_ptr); extern double util_timestamp(void); -extern const char *util_basename(const char *name); extern const char *util_uri_to_path(const char *uri); extern int util_unlink(const char *filename); diff --git a/widget_viewer/include/widget_viewer.h b/widget_viewer/include/widget_viewer.h old mode 100644 new mode 100755 index 6c7a81c..be29dcd --- a/widget_viewer/include/widget_viewer.h +++ b/widget_viewer/include/widget_viewer.h @@ -48,6 +48,10 @@ typedef struct widget *widget_h; */ #define WIDGET_DEFAULT_PERIOD -1.0f +#define WIDGET_VIEWER_CLICK_BUTTON_LEFT "clicked" +#define WIDGET_VIEWER_CLICK_BUTTON_RIGHT "clicked,1" +#define WIDGET_VIEWER_CLICK_BUTTON_CENTER "clicked,2" + /** * @internal * @brief Enumeration for Mouse & Key event for buffer type widget or Glance Bar. @@ -654,7 +658,7 @@ extern int widget_viewer_resize_widget(widget_h handle, widget_size_type_e type, * @retval #WIDGET_STATUS_ERROR_FAULT Unrecoverable error occurred * @retval #WIDGET_STATUS_ERROR_NONE Successfully done */ -extern int widget_viewer_send_click_event(widget_h handle, double x, double y); +extern int widget_viewer_send_click_event(widget_h handle, const char *event, double x, double y); /** * @internal diff --git a/widget_viewer/src/client.c b/widget_viewer/src/client.c index 70e7eac..9609dff 100644 --- a/widget_viewer/src/client.c +++ b/widget_viewer/src/client.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "debug.h" @@ -729,7 +730,7 @@ static struct packet *master_extra_updated(pid_t pid, int handle, const struct p if (!conf_manual_sync()) { ret = _widget_sync_widget_fb(common); if (ret != (int)WIDGET_ERROR_NONE) { - ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, util_basename(util_uri_to_path(id)), ret); + ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, widget_util_basename(util_uri_to_path(id)), ret); } } else { ret = WIDGET_ERROR_NONE; @@ -822,7 +823,7 @@ static struct packet *master_widget_updated(pid_t pid, int handle, const struct if (!conf_manual_sync()) { ret = _widget_sync_widget_fb(common); if (ret != (int)WIDGET_ERROR_NONE) { - ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, util_basename(util_uri_to_path(id)), ret); + ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, widget_util_basename(util_uri_to_path(id)), ret); } } else { ret = WIDGET_ERROR_NONE; @@ -915,7 +916,7 @@ static struct packet *master_gbar_created(pid_t pid, int handle, const struct pa ret = _widget_sync_gbar_fb(common); if (ret < 0) { - ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, widget_util_basename(util_uri_to_path(id))); } } } @@ -1015,7 +1016,7 @@ static struct packet *master_gbar_destroyed(pid_t pid, int handle, const struct switch (fb_type(_widget_get_gbar_fb(common))) { case WIDGET_FB_TYPE_FILE: case WIDGET_FB_TYPE_SHM: - widget_service_destroy_lock(common->gbar.lock); + widget_service_destroy_lock(common->gbar.lock, 0); common->gbar.lock = NULL; break; case WIDGET_FB_TYPE_PIXMAP: @@ -1089,7 +1090,7 @@ static struct packet *master_gbar_updated(pid_t pid, int handle, const struct pa if (!conf_manual_sync()) { ret = _widget_sync_gbar_fb(common); if (ret < 0) { - ErrPrint("Failed to do sync FB (%s - %s), %d\n", pkgname, util_basename(util_uri_to_path(id)), ret); + ErrPrint("Failed to do sync FB (%s - %s), %d\n", pkgname, widget_util_basename(util_uri_to_path(id)), ret); } else { dlist_foreach(common->widget_list, l, handler) { _widget_invoke_event_handler(handler, WIDGET_EVENT_GBAR_UPDATED); @@ -1470,7 +1471,7 @@ static struct packet *master_size_changed(pid_t pid, int handle, const struct pa ret = _widget_sync_widget_fb(common); if (ret < 0) { - ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, widget_util_basename(util_uri_to_path(id))); } /* Just update the size info only. */ @@ -1791,7 +1792,7 @@ static struct packet *master_created(pid_t pid, int handle, const struct packet ret = _widget_sync_widget_fb(common); if (ret < 0) { - ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, widget_util_basename(util_uri_to_path(id))); } break; case WIDGET_TYPE_TEXT: @@ -1815,7 +1816,7 @@ static struct packet *master_created(pid_t pid, int handle, const struct packet ret = _widget_sync_gbar_fb(common); if (ret < 0) { - ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, widget_util_basename(util_uri_to_path(id))); } /*! diff --git a/widget_viewer/src/util.c b/widget_viewer/src/util.c index c9cc01d..eac5a75 100644 --- a/widget_viewer/src/util.c +++ b/widget_viewer/src/util.c @@ -91,19 +91,6 @@ double util_timestamp(void) #endif } -const char *util_basename(const char *name) -{ - int length; - length = name ? strlen(name) : 0; - if (!length) { - return "."; - } - - while (--length > 0 && name[length] != '/'); - - return length <= 0 ? name : name + length + (name[length] == '/'); -} - const char *util_uri_to_path(const char *uri) { int len; diff --git a/widget_viewer/src/widget.c b/widget_viewer/src/widget.c index 0adcd84..fa5fba2 100644 --- a/widget_viewer/src/widget.c +++ b/widget_viewer/src/widget.c @@ -1216,7 +1216,7 @@ static void _job_del_cb(widget_h handle, int type, void *data) } } - DbgPrint("Send delete request\n"); + DbgPrint("Send delete request [%s]\n", handle->common->id); _widget_send_delete(handle, type, cb, data); } else { if (cb) { @@ -1841,7 +1841,7 @@ EAPI int widget_viewer_resize_widget(widget_h handle, widget_size_type_e type, w return ret; } -EAPI int widget_viewer_send_click_event(widget_h handle, double x, double y) +EAPI int widget_viewer_send_click_event(widget_h handle, const char *event, double x, double y) { struct packet *packet; double timestamp; @@ -1858,6 +1858,11 @@ EAPI int widget_viewer_send_click_event(widget_h handle, double x, double y) return WIDGET_ERROR_INVALID_PARAMETER; } + if (!event || (strcmp(event, WIDGET_VIEWER_CLICK_BUTTON_LEFT) && strcmp(event, WIDGET_VIEWER_CLICK_BUTTON_RIGHT) && strcmp(event, WIDGET_VIEWER_CLICK_BUTTON_CENTER))) { + ErrPrint("Unknown event: (%s)\n", event); + return WIDGET_ERROR_INVALID_PARAMETER; + } + if (!handle->common->id) { ErrPrint("Handler is not valid\n"); return WIDGET_ERROR_INVALID_PARAMETER; @@ -1875,7 +1880,7 @@ EAPI int widget_viewer_send_click_event(widget_h handle, double x, double y) timestamp = util_timestamp(); DbgPrint("CLICKED: %lf\n", timestamp); - packet = packet_create_noack((const char *)&cmd, "sssddd", handle->common->pkgname, handle->common->id, "clicked", timestamp, x, y); + packet = packet_create_noack((const char *)&cmd, "sssddd", handle->common->pkgname, handle->common->id, event, timestamp, x, y); if (!packet) { ErrPrint("Failed to build param\n"); return WIDGET_ERROR_FAULT; diff --git a/widget_viewer/src/widget_internal.c b/widget_viewer/src/widget_internal.c index a767b12..acd4db6 100644 --- a/widget_viewer/src/widget_internal.c +++ b/widget_viewer/src/widget_internal.c @@ -754,7 +754,7 @@ widget_h _widget_unref(widget_h handler, int destroy_common) * \note * Lock file should be deleted after all callbacks are processed. */ - (void)widget_service_destroy_lock(handler->common->widget.lock); + (void)widget_service_destroy_lock(handler->common->widget.lock, 0); handler->common->widget.lock = NULL; _widget_destroy_common_handle(handler->common); } diff --git a/widget_viewer_dali/CMakeLists.txt b/widget_viewer_dali/CMakeLists.txt new file mode 100755 index 0000000..e8e6988 --- /dev/null +++ b/widget_viewer_dali/CMakeLists.txt @@ -0,0 +1,68 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(widget_viewer_dali CXX) + +SET(PREFIX "${CMAKE_INSTALL_PREFIX}") +SET(EXEC_PREFIX "\${prefix}") +SET(PROJECT_NAME "${PROJECT_NAME}") +SET(LIBDIR ${LIB_INSTALL_DIR}) +SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}") +SET(VERSION_MAJOR 1) +SET(VERSION "${VERSION_MAJOR}.0.0") +SET(EDJDIR "/usr/share/${PROJECT_NAME}/res/edje") +SET(RESDIR "/usr/share/${PROJECT_NAME}/res") +SET(IMGDIR "/usr/share/${PROJECT_NAME}/res/image") + +INCLUDE(FindPkgConfig) +pkg_check_modules(viewer_dali REQUIRED + dlog + widget_service + dali + dali-core + dali-toolkit +) + +IF (X11_SUPPORT) +pkg_check_modules(viewer_dali_extra REQUIRED + ecore-x +) + +SET(BUILD_SOURCE + src/widget_viewer_dali.cpp + src/widget_dali.cpp + src/widget_dali_impl.cpp + src/widget_dali_list.cpp + src/common/widget_viewer_dali_const.cpp +) +ENDIF (X11_SUPPORT) + +FOREACH(flag ${viewer_dali_CFLAGS} ${viewer_dali_extra_CFLAGS}) + SET(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -fvisibility=hidden -Wall -Werror -Winline -g") + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}") +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_CXX_FLAGS_RELEASE "-O2") + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/widget_viewer/include) + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${BUILD_SOURCE}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION}) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${viewer_dali_LDFLAGS} ${viewer_dali_extra_LDFLAGS} "-lpthread" widget_viewer) + +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) +SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PROJECT_NAME}.pc") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${PROJECT_NAME}.h DESTINATION include/${PROJECT_NAME}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/widget_dali.h DESTINATION include/${PROJECT_NAME}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/widget_viewer_dali_generic.h DESTINATION include/${PROJECT_NAME}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME "lib${PROJECT_NAME}") +INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/res/image DESTINATION "${RESDIR}") + +ADD_SUBDIRECTORY(res) diff --git a/widget_viewer_dali/LICENSE b/widget_viewer_dali/LICENSE new file mode 100755 index 0000000..571fe79 --- /dev/null +++ b/widget_viewer_dali/LICENSE @@ -0,0 +1,206 @@ +Flora License + +Version 1.1, April, 2013 + +http://floralicense.org/license/ + +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. + +"Tizen Certified Platform" shall mean a software platform that complies +with the standards set forth in the Tizen Compliance Specification +and passes the Tizen Compliance Tests as defined from time to time +by the Tizen Technical Steering Group and certified by the Tizen +Association or its designated agent. + +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 +solely as incorporated into a Tizen Certified Platform, 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 solely +as incorporated into a Tizen Certified Platform 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 pursuant to the copyright license +above, in any medium, with or without modifications, and in Source or +Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works + a copy of this License; and + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + 3. 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 + 4. 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 + and your own copyright statement or terms and conditions do not conflict + the conditions stated in the License including section 3. + +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 Flora License to your work + +To apply the Flora 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 Flora License, Version 1.1 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://floralicense.org/license/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT 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/widget_viewer_dali/include/widget_dali.h b/widget_viewer_dali/include/widget_dali.h new file mode 100755 index 0000000..9b63e3a --- /dev/null +++ b/widget_viewer_dali/include/widget_dali.h @@ -0,0 +1,97 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 __WIDGET_H__ +#define __WIDGET_H__ + +#include +#include + +#include "widget_viewer_dali_generic.h" + +using namespace Dali; + +namespace WidgetViewerDali +{ + +namespace Internal +{ +class CWidget; +} + +class CWidget : public Dali::Toolkit::Control +{ +public: + typedef Signal DeletedSignal; + typedef Signal TouchedSignal; + typedef Signal TappedSignal; + typedef Signal LongpressedSignal; + typedef Signal ReloadSignal; + +public: + CWidget(); + CWidget(const CWidget& widget); + CWidget(Internal::CWidget&); + CWidget(Dali::Internal::CustomActor*); + + ~CWidget(); + + static WidgetViewerDali::CWidget New(unsigned int id, void* handle, const char *pkgname, widget_size_type_e size, double period); + + CWidget& operator=( const CWidget& widget ); + static CWidget DownCast( BaseHandle handle ); + + void Initialize(); + + void UpdateByPixmap(unsigned int pixmap); + + int GetRowLen(); + int GetColLen(); + + void SetGridPosition(int row, int col); + void GetGridPosition(int *row, int *col); + + unsigned int GetPixmap(); + void SetPixmap(unsigned int pixmap); + unsigned int GetWidgetId(); + void SetWidgetId(unsigned int id); + + void SetEditMode(bool mode); + void SetTouchable(bool able); + void CancelTouchOperation(); + + DeletedSignal& SignalDeleted(); + TouchedSignal& SignalTouched(); + TappedSignal& SignalTapped(); + LongpressedSignal& SignalLongpressed(); + ReloadSignal& SignalReload(); + + std::string GetPkgName(); + double GetPeriod(); + void SetWidgetHandler(void* handle); + void* GetWidgetHandle(); + widget_size_type_e GetSizeType(); + + bool IsFaulted(); + void SetFault(bool fault); + + bool OnTouch(const TouchEvent& event); + void OnFault(); +}; + +} + +#endif diff --git a/widget_viewer_dali/include/widget_dali_impl.h b/widget_viewer_dali/include/widget_dali_impl.h new file mode 100755 index 0000000..034a130 --- /dev/null +++ b/widget_viewer_dali/include/widget_dali_impl.h @@ -0,0 +1,161 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 __WIDGET_IMPL_H__ +#define __WIDGET_IMPL_H__ + +#include + +#include "widget_viewer_dali_generic.h" +#include "widget_dali.h" + +using namespace Dali; + +namespace WidgetViewerDali +{ + +namespace Internal +{ + +class CWidget; +typedef IntrusivePtr WidgetInternalPtr; + +class CWidget : public Dali::Toolkit::Internal::Control +{ +public: + CWidget(unsigned int id, void* handle, const char *pkgname, widget_size_type_e size, double period); + + CWidget(const CWidget&); + CWidget(Internal::CWidget&); + + virtual ~CWidget(); + + static WidgetViewerDali::CWidget New(unsigned int id, void* handler, const char *pkgname, widget_size_type_e size, double period); + + void Initialize(); + + void UpdateByPixmap(unsigned int pixmap); + + int GetRowLen() { return mRowLen; } + int GetColLen() { return mColLen; } + + void SetGridPosition(int row, int col); + void GetGridPosition(int *row, int *col); + + unsigned int GetPixmap() { return mPixmap; } + void SetPixmap(unsigned int pixmap); + + unsigned int GetWidgetId(); + void SetWidgetId(unsigned int id); + + void SetEditMode(bool mode); + void SetTouchable(bool able); + void CancelTouchOperation(); + + std::string GetPkgName() { return mPkgName; } + double GetPeriod() { return mPeriod; } + void SetWidgetHandler(void* handle); + void* GetWidgetHandle() { return mHandler; } + widget_size_type_e GetSizeType() { return mSize; } + bool IsFaulted() { return mIsFaulted; } + void SetFault(bool fault); + void OnFault(); + + WidgetViewerDali::CWidget::DeletedSignal& SignalDeleted() { return mSignalDeleted; } + WidgetViewerDali::CWidget::TouchedSignal& SignalTouched() { return mSignalTouched; }; + WidgetViewerDali::CWidget::TappedSignal& SignalTapped() { return mSignalTapped; }; + WidgetViewerDali::CWidget::LongpressedSignal& SignalLongpressed() { return mSignalLongpressed; }; + WidgetViewerDali::CWidget::ReloadSignal& SignalReload() { return mSignalReload; } + + bool OnTouch(const TouchEvent& event); + +private: + CWidget& operator=(const CWidget& rhs); + + bool _OnDeleteButtonClicked( Dali::Toolkit::Button button ); + bool _OnEventAreaTouchEvent(Dali::Actor actor, const TouchEvent& event); + + Vector3 _GetScreenPosition(); + void _ConnectTouchSignal(bool isConnect); + bool _OnLongTapTimerComplete(); + void _OnWidgetTapped(); + +private: + void* mHandler; + widget_size_type_e mSize; + unsigned int mPixmap; + int mRow; + int mCol; + unsigned int mRowLen; + unsigned int mColLen; + unsigned int mId; + + PixmapImagePtr mPixmapImage; + NativeImage mBaseNativeImageData; + ImageActor mBaseImage; + + Toolkit::TextLabel mLoadingTextLabel; + Toolkit::TextLabel mFaultedTextLabel; + Dali::Toolkit::PushButton mDeleteButton; + + Actor mEventArea; + + WidgetViewerDali::CWidget::DeletedSignal mSignalDeleted; + WidgetViewerDali::CWidget::TouchedSignal mSignalTouched; + WidgetViewerDali::CWidget::TappedSignal mSignalTapped; + WidgetViewerDali::CWidget::LongpressedSignal mSignalLongpressed; + WidgetViewerDali::CWidget::ReloadSignal mSignalReload; + + std::string mPkgName; + double mPeriod; + bool mIsTouched; + bool mIsTouchable; + bool mIsConnectedTouchSignal; + + bool mIsFaulted; + + Timer mLongTapTimer; + Vector2 mDownPos; + + bool mIsEditMode; + ImageActor mFaultDimBg; + +}; + +} + +inline WidgetViewerDali::Internal::CWidget& GetImpl(WidgetViewerDali::CWidget& widget) +{ + DALI_ASSERT_ALWAYS(widget); + + Dali::RefObject& handle = widget.GetImplementation(); + + return static_cast(handle); +} + +inline const WidgetViewerDali::Internal::CWidget& GetImpl(const WidgetViewerDali::CWidget& widget) +{ + DALI_ASSERT_ALWAYS(widget); + + const Dali::RefObject& handle = widget.GetImplementation(); + + return static_cast(handle); +} + +} + +#endif + diff --git a/widget_viewer_dali/include/widget_dali_list.h b/widget_viewer_dali/include/widget_dali_list.h new file mode 100755 index 0000000..ee99a97 --- /dev/null +++ b/widget_viewer_dali/include/widget_dali_list.h @@ -0,0 +1,52 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 __WIDGET_LIST_H__ +#define __WIDGET_LIST_H__ + +#include + +#include "widget_viewer_dali_generic.h" +#include "widget_dali.h" + +using namespace Dali; + +namespace WidgetViewerDali +{ + +class CWidgetList +{ +public: + CWidgetList(); + + ~CWidgetList(); + + int Add(void* handle, CWidget widget); + void Remove(void* handle); + CWidget GetWidget(unsigned int id); + unsigned int GetWidgetId(void *handle); + std::vector GetWidgetList(const char * pkgname); + void Update(void* handle, void* newHandle, CWidget widget); + +private: + std::map m_mWidgetList; +}; + +} + +#endif + + diff --git a/widget_viewer_dali/include/widget_viewer_dali.h b/widget_viewer_dali/include/widget_viewer_dali.h new file mode 100755 index 0000000..9037656 --- /dev/null +++ b/widget_viewer_dali/include/widget_viewer_dali.h @@ -0,0 +1,73 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 __WIDGET_VIEWER_DALI_H__ +#define __WIDGET_VIEWER_DALI_H__ + +#include + +#include "widget_viewer_dali_generic.h" +#include "widget_dali.h" + +using namespace Dali; + +namespace WidgetViewerDali +{ +class CWidgetList; + +class CWidgetManager : public ConnectionTracker +{ +public: + /* + * Signals + */ + typedef Dali::Signal WidgetAddedSignal; + typedef Dali::Signal WidgetDeletedSignal; + +public: + CWidgetManager(); + ~CWidgetManager(); + + static CWidgetManager* GetInstance(); + + void Initialize(); + + WidgetAddedSignal& GetSignalWidgetAdded() { return mSignalWidgetAdded; } + WidgetDeletedSignal& GetSignalWidgetDeleted() { return mSignalWidgetDeleted; } + + int AddWidget(unsigned int id, const char *pkgname, const char *name, widget_size_type_e type, const char *content, + const char *icon, int pid, double period, int allow_duplicate); + + void WidgetEventCreated(void *handler); + void WidgetEventUpdated(void *handler); + void WidgetEventDeleted(void *handler); + void WidgetFaulted(const char *pkgname); + void EventPixmapAcquired(void *handler, unsigned int pixmapId); + + bool OnWidgetDeleted(WidgetViewerDali::CWidget& widget); + bool OnWidgetReload(WidgetViewerDali::CWidget& widget); + +private: + static CWidgetManager* m_pInstance; + + WidgetAddedSignal mSignalWidgetAdded; + WidgetDeletedSignal mSignalWidgetDeleted; + + CWidgetList* mWidgetList; +}; +} + +#endif \ No newline at end of file diff --git a/widget_viewer_dali/include/widget_viewer_dali_const.h b/widget_viewer_dali/include/widget_viewer_dali_const.h new file mode 100755 index 0000000..f120c5c --- /dev/null +++ b/widget_viewer_dali/include/widget_viewer_dali_const.h @@ -0,0 +1,113 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 _WIDGET_VIEWER_DALI_CONST_H_ +#define _WIDGET_VIEWER_DALI_CONST_H_ + +#include +#include + +#define BASE_HEIGHT CWidgetDaliConst::GetBaseHeight() +#define BASE_WIDTH CWidgetDaliConst::GetBaseWidth() + +#define SCREEN_HEIGHT CWidgetDaliConst::GetScreenHeight() +#define SCREEN_WIDTH CWidgetDaliConst::GetScreenWidth() + +#define SCREEN_RESOLUTION_TYPE CWidgetDaliConst::GetScreenResolutionType() + +#define INDICATOR_H CWidgetDaliConst::GetIndicatorHeight() + +#define WIDGET_LOADING_TEXT_WIDTH CWidgetDaliConst::GetWidgetLoadingTextWidth() +#define WIDGET_LOADING_TEXT_SIZE CWidgetDaliConst::GetWidgetLoadingTextSize() +#define WIDGET_DELETE_BUTTON_WIDTH CWidgetDaliConst::GetWidgetDeleteButtonWidth() +#define WIDGET_DELETE_BUTTON_HEIGHT CWidgetDaliConst::GetWidgetDeleteButtonHeight() +#define WIDGET_DELETE_BUTTON_X CWidgetDaliConst::GetWidgetDeleteButtonX() +#define WIDGET_DELETE_BUTTON_Y CWidgetDaliConst::GetWidgetDeleteButtonY() +#define WIDGET_DELETE_BUTTON_Z CWidgetDaliConst::GetWidgetDeleteButtonZ() + +#define TAPPED_BOUNDARY_WIDTH CWidgetDaliConst::GetTappedBoundaryWidth() +#define TAPPED_BOUNDARY_HEIGHT CWidgetDaliConst::GetTappedBoundaryHeight() + +using namespace Dali; + +namespace WidgetViewerDali +{ +class CWidgetDaliConst +{ +public: + typedef enum + { + RESOLUTION_BASE_480X640 = 0, /* 3 : 4 */ + RESOLUTION_BASE_320X480, /* 2 : 3 */ + RESOLUTION_BASE_480X800, /* 3 : 5 */ + RESOLUTION_BASE_540X960, /* 9 : 16 */ + RESOLUTION_BASE_MAX + } ScreenResolutionType; + +public: + static void SetScreenSize(Vector2 size); + static const int GetBaseWidth() { return mBaseWidth; } + static const int GetBaseHeight() { return mBaseHeight; } + static const float GetScreenWidth() { return mScreenSize.width; } + static const float GetScreenHeight() { return mScreenSize.height; } + static const unsigned int GetScreenResolutionType() { return mScreenResolutionType; } + + static const float GetIndicatorHeight(); + + static const float GetWidgetLoadingTextWidth(); + static const float GetWidgetLoadingTextSize(); + + static const float GetWidgetDeleteButtonWidth(); + static const float GetWidgetDeleteButtonHeight(); + static const float GetWidgetDeleteButtonX(); + static const float GetWidgetDeleteButtonY(); + static const float GetWidgetDeleteButtonZ(); + + static const float GetTappedBoundaryWidth(); + static const float GetTappedBoundaryHeight(); + +private : + CWidgetDaliConst(); + static void _SetBaseScreenSize(int width, int height); + static const unsigned int _GetResolutionType(int x, int y); + + static const float _GetX(float xPos) { return floor(xPos * SCREEN_WIDTH / BASE_WIDTH); } + static const float _GetY(float yPos) { return floor(yPos * SCREEN_HEIGHT / BASE_HEIGHT); } + static const float _GetZ(float zPos) { return zPos * SCREEN_WIDTH / BASE_WIDTH; } + static const float _GetWidth(float width) { return width * SCREEN_WIDTH / BASE_WIDTH; } + static const float _GetHeight(float height) { return height * SCREEN_HEIGHT / BASE_HEIGHT; } + + static Vector2 mScreenSize; + static int mBaseWidth; + static int mBaseHeight; + static unsigned int mScreenResolutionType; + + static float mIndicatorHeight[RESOLUTION_BASE_MAX]; + + static float mWidgetLoadingTextWidth[RESOLUTION_BASE_MAX]; + static float mWidgetLoadingTextSize[RESOLUTION_BASE_MAX]; + static float mWidgetDeleteButtonWidth[RESOLUTION_BASE_MAX]; + static float mWidgetDeleteButtonHeight[RESOLUTION_BASE_MAX]; + static float mWidgetDeleteButtonX[RESOLUTION_BASE_MAX]; + static float mWidgetDeleteButtonY[RESOLUTION_BASE_MAX]; + static float mWidgetDeleteButtonZ[RESOLUTION_BASE_MAX]; + static float mTappedBoundaryWidth[RESOLUTION_BASE_MAX]; + static float mTappedBoundaryHeight[RESOLUTION_BASE_MAX]; +}; +} +#endif /* _WIDGET_VIEWER_DALI_CONST_H_ */ + + diff --git a/widget_viewer_dali/include/widget_viewer_dali_generic.h b/widget_viewer_dali/include/widget_viewer_dali_generic.h new file mode 100755 index 0000000..1f17b60 --- /dev/null +++ b/widget_viewer_dali/include/widget_viewer_dali_generic.h @@ -0,0 +1,102 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 __WIDGET_VIEWER_DALI_GENERIC_H__ +#define __WIDGET_VIEWER_DALI_GENERIC_H__ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#define HS_KEY_MENU "XF86Menu" +#define HS_KEY_BACK "XF86Back" +#define HS_KEY_HOME "XF86Home" +#define HS_KEY_APPS "XF86Apps" + +#if !defined(EAPI) +#define EAPI __attribute__((visibility("default"))) +#endif + +#if defined(LOG_TAG) +#undef LOG_TAG +#endif + +#define LOG_TAG "WIDGET_DALI" + +#if !defined(SECURE_LOGD) +#define SECURE_LOGD LOGD +#endif + +#if !defined(SECURE_LOGW) +#define SECURE_LOGW LOGW +#endif + +#if !defined(SECURE_LOGE) +#define SECURE_LOGE LOGE +#endif + +#if !defined(S_) +#define S_(str) dgettext("sys_string", str) +#endif + +#if !defined(T_) +#define T_(str) dgettext(PKGNAME, str) +#endif + +#if !defined(N_) +#define N_(str) (str) +#endif + +#if !defined(_) +#define _(str) gettext(str) +#endif + + +#if !defined(DbgPrint) +#define DbgPrint(format, arg...) SECURE_LOGD(format, ##arg) +#endif + +#if !defined(ErrPrint) +#define ErrPrint(format, arg...) SECURE_LOGE(format, ##arg) +#endif + +#if !defined(WarnPrint) +#define WarnPrint(format, arg...) SECURE_LOGW(format, ##arg) +#endif + +#if !defined(WIDGET_VIEWER_RESDIR) +#define WIDGET_VIEWER_RESDIR "/usr/share/widget_viewer_dali/res" +#endif + +#if !defined(WIDGET_VIEWER_ICONDIR) +#define WIDGET_VIEWER_ICONDIR WIDGET_VIEWER_RESDIR"/image" +#endif + +#endif /* __WIDGET_VIEWER_DALI_GENERIC_H__ */ + diff --git a/widget_viewer_dali/res/image/btn_delete_nor.png b/widget_viewer_dali/res/image/btn_delete_nor.png new file mode 100755 index 0000000000000000000000000000000000000000..526e12cc7fc833becdf4fc6d625932eb00913367 GIT binary patch literal 2436 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 literal 0 HcmV?d00001 diff --git a/widget_viewer_dali/src/common/widget_viewer_dali_const.cpp b/widget_viewer_dali/src/common/widget_viewer_dali_const.cpp new file mode 100755 index 0000000..9bd2c2e --- /dev/null +++ b/widget_viewer_dali/src/common/widget_viewer_dali_const.cpp @@ -0,0 +1,147 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "widget_viewer_dali_const.h" + +using namespace Dali; +using namespace WidgetViewerDali; + +namespace WidgetViewerDali +{ + +const float SCREEN_RATIO[4] = { (4.0f/3.0f), (3.0f/2.0f), (5.0f/3.0f), (16.0f/9.0f) }; +const int SCREEN_RESOLUTION[4][2] = { {480, 640}, {320, 480}, {480, 800}, {540, 960} }; + +Vector2 CWidgetDaliConst::mScreenSize = Vector2(BASE_WIDTH, BASE_HEIGHT); +int CWidgetDaliConst::mBaseWidth = 480; +int CWidgetDaliConst::mBaseHeight = 800; +unsigned int CWidgetDaliConst::mScreenResolutionType = CWidgetDaliConst::RESOLUTION_BASE_480X800; + +/* + 0 : 480x640 - unsupported + 1 : 320x480 - unsupported + 2 : 480x800 - WVGA + 3 : 540x960 - qHD +*/ +float CWidgetDaliConst::mIndicatorHeight[CWidgetDaliConst::RESOLUTION_BASE_MAX] = { 0.0f, 0.0f, 33.33f, 40.0f }; +float CWidgetDaliConst::mWidgetLoadingTextWidth[CWidgetDaliConst::RESOLUTION_BASE_MAX] = { 0.0f, 0.0f, 470.0f, 528.75f }; +float CWidgetDaliConst::mWidgetLoadingTextSize[CWidgetDaliConst::RESOLUTION_BASE_MAX] = { 0.0f, 0.0f, 18.0f, 21.65f }; +float CWidgetDaliConst::mWidgetDeleteButtonWidth[CWidgetDaliConst::RESOLUTION_BASE_MAX] = { 0.0f, 0.0f, 40.0f, 45.0f }; +float CWidgetDaliConst::mWidgetDeleteButtonHeight[CWidgetDaliConst::RESOLUTION_BASE_MAX] = { 0.0f, 0.0f, 40.0f, 48.0f }; +float CWidgetDaliConst::mWidgetDeleteButtonX[CWidgetDaliConst::RESOLUTION_BASE_MAX] = { 0.0f, 0.0f, 15.0f, 16.875f }; +float CWidgetDaliConst::mWidgetDeleteButtonY[CWidgetDaliConst::RESOLUTION_BASE_MAX] = { 0.0f, 0.0f, 15.0f, 18.0f }; +float CWidgetDaliConst::mWidgetDeleteButtonZ[CWidgetDaliConst::RESOLUTION_BASE_MAX] = { 0.0f, 0.0f, 3.5f, 3.9375f }; +float CWidgetDaliConst::mTappedBoundaryWidth[CWidgetDaliConst::RESOLUTION_BASE_MAX] = { 0.0f, 0.0f, 10.0f, 11.5f }; +float CWidgetDaliConst::mTappedBoundaryHeight[CWidgetDaliConst::RESOLUTION_BASE_MAX] = { 0.0f, 0.0f, 10.0f, 12.0f }; + +CWidgetDaliConst::CWidgetDaliConst() +{ +} + +void CWidgetDaliConst::SetScreenSize(Vector2 size) +{ + mScreenSize = size; + + _SetBaseScreenSize(size.x, size.y); +} + +void CWidgetDaliConst::_SetBaseScreenSize(int width, int height) +{ + unsigned int type = _GetResolutionType(width, height); + + if( width < height ) + { + mBaseWidth = SCREEN_RESOLUTION[type][0]; + mBaseHeight = SCREEN_RESOLUTION[type][1]; + } + else + { + mBaseWidth = SCREEN_RESOLUTION[type][1]; + mBaseHeight = SCREEN_RESOLUTION[type][0]; + } + + mScreenResolutionType = type; +} + +const unsigned int CWidgetDaliConst::_GetResolutionType(int x, int y) +{ + if(x > y) + return CWidgetDaliConst::_GetResolutionType(y, x); + + float ratio = (float) y / (float) x; + + unsigned int type=0; + for(type=0; type < RESOLUTION_BASE_MAX - 1; type++) + { + if( fabs(ratio - SCREEN_RATIO[type]) < fabs(ratio - SCREEN_RATIO[type+1]) ) + break; + } + + return type; +} + +const float CWidgetDaliConst::GetIndicatorHeight() +{ + return _GetHeight(mIndicatorHeight[mScreenResolutionType]); +} + +const float CWidgetDaliConst::GetWidgetLoadingTextWidth() +{ + return _GetWidth(mWidgetLoadingTextWidth[mScreenResolutionType]); +} + +const float CWidgetDaliConst::GetWidgetLoadingTextSize() +{ + return _GetHeight(mWidgetLoadingTextSize[mScreenResolutionType]); +} + +const float CWidgetDaliConst::GetWidgetDeleteButtonWidth() +{ + return _GetWidth(mWidgetDeleteButtonWidth[mScreenResolutionType]); +} + +const float CWidgetDaliConst::GetWidgetDeleteButtonHeight() +{ + return _GetHeight(mWidgetDeleteButtonHeight[mScreenResolutionType]); +} + +const float CWidgetDaliConst::GetWidgetDeleteButtonX() +{ + return _GetX(mWidgetDeleteButtonX[mScreenResolutionType]); +} + +const float CWidgetDaliConst::GetWidgetDeleteButtonY() +{ + return _GetY(mWidgetDeleteButtonY[mScreenResolutionType]); +} + +const float CWidgetDaliConst::GetWidgetDeleteButtonZ() +{ + return _GetZ(mWidgetDeleteButtonZ[mScreenResolutionType]); +} + +const float CWidgetDaliConst::GetTappedBoundaryWidth() +{ + return _GetWidth(mTappedBoundaryWidth[mScreenResolutionType]); +} + +const float CWidgetDaliConst::GetTappedBoundaryHeight() +{ + return _GetHeight(mTappedBoundaryHeight[mScreenResolutionType]); +} + +} + diff --git a/widget_viewer_dali/src/widget_dali.cpp b/widget_viewer_dali/src/widget_dali.cpp new file mode 100755 index 0000000..99b8f3e --- /dev/null +++ b/widget_viewer_dali/src/widget_dali.cpp @@ -0,0 +1,209 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "widget_viewer_dali_generic.h" +#include "widget_dali.h" +#include "widget_dali_impl.h" +#include "debug.h" + +using namespace Dali; +using namespace WidgetViewerDali; + +namespace WidgetViewerDali +{ + +EAPI CWidget::CWidget() +{ +} + +EAPI CWidget::CWidget(const CWidget& widget) +: Dali::Toolkit::Control(widget) +{ +} + +EAPI CWidget::CWidget(Internal::CWidget& impl) +: Dali::Toolkit::Control(impl) +{ +} + +EAPI CWidget::CWidget(Dali::Internal::CustomActor* implementation) +: Dali::Toolkit::Control(implementation) +{ + VerifyCustomActorPointer(implementation); +} + +EAPI CWidget::~CWidget() +{ +} + +CWidget CWidget::New(unsigned int id, void* handle, const char *pkgname, widget_size_type_e size, double period) +{ + return Internal::CWidget::New(id, handle, pkgname, size, period); +} + +void CWidget::Initialize() +{ + GetImpl(*this).Initialize(); +} + +EAPI CWidget& CWidget::operator=( const CWidget& widget ) +{ + if( &widget != this ) + { + Dali::Toolkit::Control::operator=( widget ); + } + + return *this; +} + +EAPI CWidget CWidget::DownCast( BaseHandle handle ) +{ + return Dali::Toolkit::Control::DownCast(handle); +} + +EAPI int CWidget::GetRowLen() +{ + return GetImpl(*this).GetRowLen(); +} + +EAPI int CWidget::GetColLen() +{ + return GetImpl(*this).GetColLen(); +} + +EAPI void CWidget::SetGridPosition(int row, int col) +{ + GetImpl(*this).SetGridPosition(row, col); +} + +EAPI void CWidget::GetGridPosition(int *row, int *col) +{ + GetImpl(*this).GetGridPosition(row, col); +} + +unsigned int CWidget::GetPixmap() +{ + return GetImpl(*this).GetPixmap(); +} + +void CWidget::SetPixmap(unsigned int pixmap) +{ + GetImpl(*this).SetPixmap(pixmap); +} + +EAPI unsigned int CWidget::GetWidgetId() +{ + return GetImpl(*this).GetWidgetId(); +} + +void CWidget::SetWidgetId(unsigned int id) +{ + GetImpl(*this).SetWidgetId(id); +} + +void CWidget::UpdateByPixmap(unsigned int pixmap) +{ + GetImpl(*this).UpdateByPixmap(pixmap); +} + +EAPI void CWidget::SetEditMode(bool mode) +{ + GetImpl(*this).SetEditMode(mode); +} + +EAPI void CWidget::SetTouchable(bool able) +{ + GetImpl(*this).SetTouchable(able); +} + +EAPI void CWidget::CancelTouchOperation() +{ + GetImpl(*this).CancelTouchOperation(); +} + +CWidget::DeletedSignal& CWidget::SignalDeleted() +{ + return GetImpl(*this).SignalDeleted(); +} + +EAPI CWidget::TouchedSignal& CWidget::SignalTouched() +{ + return GetImpl(*this).SignalTouched(); +} + +EAPI CWidget::TappedSignal& CWidget::SignalTapped() +{ + return GetImpl(*this).SignalTapped(); +} + +EAPI CWidget::LongpressedSignal& CWidget::SignalLongpressed() +{ + return GetImpl(*this).SignalLongpressed(); +} + +CWidget::ReloadSignal& CWidget::SignalReload() +{ + return GetImpl(*this).SignalReload(); +} + +std::string CWidget::GetPkgName() +{ + return GetImpl(*this).GetPkgName(); +} + +double CWidget::GetPeriod() +{ + return GetImpl(*this).GetPeriod(); +} + +bool CWidget::IsFaulted() +{ + return GetImpl(*this).IsFaulted(); +} + +void CWidget::SetFault(bool fault) +{ + GetImpl(*this).SetFault(fault); +} + +void CWidget::SetWidgetHandler(void* handle) +{ + GetImpl(*this).SetWidgetHandler(handle); +} + +void* CWidget::GetWidgetHandle() +{ + return GetImpl(*this).GetWidgetHandle(); +} + +widget_size_type_e CWidget::GetSizeType() +{ + return GetImpl(*this).GetSizeType(); +} + +EAPI bool CWidget::OnTouch(const TouchEvent& event) +{ + return GetImpl(*this).OnTouch(event); +} + +void CWidget::OnFault() +{ + GetImpl(*this).OnFault(); +} + +} diff --git a/widget_viewer_dali/src/widget_dali_impl.cpp b/widget_viewer_dali/src/widget_dali_impl.cpp new file mode 100755 index 0000000..ad9f7f7 --- /dev/null +++ b/widget_viewer_dali/src/widget_dali_impl.cpp @@ -0,0 +1,491 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "widget_viewer_dali_generic.h" +#include "widget_viewer_dali_const.h" +#include "widget_dali_impl.h" +#include "debug.h" + +#if defined(LOG_TAG) +#undef LOG_TAG +#endif + +#define LOG_TAG "WIDGET_DALI" + +using namespace Dali; +using namespace WidgetViewerDali; + +namespace WidgetViewerDali +{ + +namespace Internal +{ + +EAPI CWidget::CWidget(unsigned int id, void* handle, const char *pkgname, widget_size_type_e size, double period) +: Dali::Toolkit::Internal::Control(ControlBehaviour(REQUIRES_TOUCH_EVENTS)), + mHandler(handle), + mSize(size), + mPixmap(0), + mRowLen(1), + mColLen(1), + mId(id), + mPkgName(pkgname), + mPeriod(period), + mIsTouched(false), + mIsTouchable(true), + mIsConnectedTouchSignal(false), + mIsFaulted(false), + mIsEditMode(false) +{ +} + +EAPI CWidget::~CWidget() +{ +} + +EAPI WidgetViewerDali::CWidget CWidget::New(unsigned int id, void* handler, const char *pkgname, widget_size_type_e size, double period) +{ + WidgetInternalPtr pWidget(new CWidget(id, handler, pkgname, size, period)); + + WidgetViewerDali::CWidget handle(*pWidget); + + pWidget->Initialize(); + + return handle; +} + +void CWidget::Initialize() +{ + DbgPrint("%x", mSize); + Actor self = Self(); + + self.SetParentOrigin( ParentOrigin::TOP_CENTER ); + self.SetAnchorPoint( AnchorPoint::TOP_CENTER ); + + mBaseImage = ImageActor::New(); + mBaseImage.SetParentOrigin( ParentOrigin::TOP_LEFT ); + mBaseImage.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + Constraint constraint = Constraint::New( mBaseImage, Actor::Property::SIZE, EqualToConstraint() ); + constraint.AddSource( ParentSource(Actor::Property::SIZE) ); + constraint.Apply(); + + self.Add(mBaseImage); + + mEventArea = Actor::New(); + + Constraint eventAreaConstraint = Constraint::New( mEventArea, Actor::Property::SIZE, EqualToConstraint() ); + eventAreaConstraint.AddSource( ParentSource(Actor::Property::SIZE) ); + eventAreaConstraint.Apply(); + + mEventArea.SetAnchorPoint(AnchorPoint::CENTER); + mEventArea.SetParentOrigin(ParentOrigin::CENTER); + mEventArea.SetPosition(0.0f, 0.0f, 0.5f); + + self.Add(mEventArea); + + /* supporting to operate normal and edit mode */ + mEventArea.TouchedSignal().Connect(this, &Internal::CWidget::_OnEventAreaTouchEvent); + mEventArea.SetLeaveRequired(true); + mIsConnectedTouchSignal = true; + + Vector2 resolution = Stage::GetCurrent().GetDpi(); + mLoadingTextLabel = Toolkit::TextLabel::New(_("IDS_ST_BODY_LOADING_ING")); + mLoadingTextLabel.SetProperty(Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER"); + mLoadingTextLabel.SetProperty(Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER"); + mLoadingTextLabel.SetProperty(Toolkit::TextLabel::Property::POINT_SIZE, WIDGET_LOADING_TEXT_SIZE * 72.0f/resolution.y); + mLoadingTextLabel.SetProperty(Toolkit::TextLabel::Property::TEXT_COLOR, Vector4(1.0f, 1.0f, 1.0f, 1.0f)); + mLoadingTextLabel.SetParentOrigin(ParentOrigin::CENTER); + mLoadingTextLabel.SetAnchorPoint(AnchorPoint::CENTER); + mLoadingTextLabel.SetSize(WIDGET_LOADING_TEXT_WIDTH, WIDGET_LOADING_TEXT_SIZE * 3); + mLoadingTextLabel.SetPosition(Vector3(0.0f, 0.0f, 0.0f)); + mBaseImage.Add(mLoadingTextLabel); + + Image iconImage; + mDeleteButton = Dali::Toolkit::PushButton::New(); + iconImage = ResourceImage::New(WIDGET_VIEWER_ICONDIR"/btn_delete_nor.png"); + mDeleteButton.SetButtonImage(iconImage); + iconImage = ResourceImage::New(WIDGET_VIEWER_ICONDIR"/btn_delete_press.png"); + mDeleteButton.SetSelectedImage(iconImage); + mDeleteButton.SetSize(Vector2(WIDGET_DELETE_BUTTON_WIDTH, WIDGET_DELETE_BUTTON_HEIGHT)); + mDeleteButton.SetAnchorPoint(AnchorPoint::TOP_LEFT); + mDeleteButton.SetParentOrigin(AnchorPoint::TOP_LEFT); + mDeleteButton.SetPosition(Vector3(WIDGET_DELETE_BUTTON_X, WIDGET_DELETE_BUTTON_Y, WIDGET_DELETE_BUTTON_Z)); + mDeleteButton.SetOpacity(0.0f); + + mDeleteButton.ClickedSignal().Connect( this, &Internal::CWidget::_OnDeleteButtonClicked ); + + mBaseImage.Add(mDeleteButton); + + switch (mSize) { + case WIDGET_SIZE_TYPE_1x1 : + mRowLen = 1; + mColLen = 1; + break; + case WIDGET_SIZE_TYPE_2x1 : + mRowLen = 1; + mColLen = 2; + break; + case WIDGET_SIZE_TYPE_2x2 : + mRowLen = 2; + mColLen = 2; + break; + case WIDGET_SIZE_TYPE_4x1 : + mRowLen = 1; + mColLen = 4; + break; + case WIDGET_SIZE_TYPE_4x2 : + mRowLen = 2; + mColLen = 4; + break; + case WIDGET_SIZE_TYPE_4x3 : + mRowLen = 3; + mColLen = 4; + break; + case WIDGET_SIZE_TYPE_4x4 : + mRowLen = 4; + mColLen = 4; + break; + case WIDGET_SIZE_TYPE_4x5 : + mRowLen = 5; + mColLen = 4; + break; + case WIDGET_SIZE_TYPE_4x6 : + mRowLen = 6; + mColLen = 4; + break; + default: + mRowLen = 1; + mColLen = 1; + break; + } + + if (!mLongTapTimer) + { + mLongTapTimer = Timer::New(1000); + mLongTapTimer.TickSignal().Connect(this, &Internal::CWidget::_OnLongTapTimerComplete); + } + + DbgPrint("rowLen, colLen [%d, %d]", mRowLen, mColLen); +} + +void CWidget::UpdateByPixmap(unsigned int pixmap) +{ + DbgPrint("Update widget by pixmap[%d]", pixmap); + mPixmap = pixmap; + mPixmapImage = PixmapImage::New(mPixmap); + mBaseNativeImageData = NativeImage::New(*mPixmapImage); + + if(mLoadingTextLabel) + { + mBaseImage.Remove(mLoadingTextLabel); + mLoadingTextLabel.Reset(); + } + + if(mFaultDimBg) + { + mFaultDimBg.SetOpacity(0.0f); + } + + mBaseImage.SetImage(mBaseNativeImageData); + + mIsFaulted = false; +} + +void CWidget::SetPixmap(unsigned int pixmap) +{ + DbgPrint("Set [%d]", pixmap); + mPixmap = pixmap; +} + +void CWidget::SetWidgetId(unsigned int id) +{ + DbgPrint("Set [%d]", id); + mId = id; +} + +unsigned int CWidget::GetWidgetId() +{ + DbgPrint("Get Id [%d]", mId); + return mId; +} + +void CWidget::SetWidgetHandler(void* handle) +{ + mHandler = handle; +} + +void CWidget::SetEditMode(bool mode) +{ + mIsEditMode = mode; + CancelTouchOperation(); + + mDeleteButton.SetOpacity(mode ? 1.0f : 0.0f); + + _ConnectTouchSignal(!mode); +} + +void CWidget::SetTouchable(bool able) +{ + mIsTouchable = able; + _ConnectTouchSignal(able); +} + +void CWidget::_ConnectTouchSignal(bool isConnect) +{ + if(isConnect && mIsTouchable) + { + mEventArea.TouchedSignal().Connect(this, &Internal::CWidget::_OnEventAreaTouchEvent); + mIsConnectedTouchSignal = true; + } + else if(mIsConnectedTouchSignal) + { + mEventArea.TouchedSignal().Disconnect(this, &Internal::CWidget::_OnEventAreaTouchEvent); + mIsConnectedTouchSignal = false; + } +} + +void CWidget::CancelTouchOperation() +{ + if (mLongTapTimer.IsRunning()) + { + mLongTapTimer.Stop(); + } + + if(mIsTouched) + { + mIsTouched = false; + + TouchEvent event; + Vector3 screenposition = _GetScreenPosition(); + event.points.push_back( TouchPoint ( 0, Dali::TouchPoint::Leave, screenposition.x, screenposition.y ) ); + DbgPrint("cancel x, y [%.2f, %.2f]", screenposition.x, screenposition.y); + _OnEventAreaTouchEvent(Self(), event); + } +} + +bool CWidget::_OnDeleteButtonClicked( Dali::Toolkit::Button button ) +{ + Actor self = Self(); + + WidgetViewerDali::CWidget handle ( GetOwner() ); + + mSignalDeleted.Emit(handle); + + return true; +} + +bool CWidget::_OnEventAreaTouchEvent(Dali::Actor actor, const TouchEvent& event) +{ + DbgPrint("_OnEventAreaTouchEvent!! widget id[%d]", mId); + WidgetViewerDali::CWidget handle ( GetOwner() ); + + mSignalTouched.Emit(handle, event.GetPoint(0).state, event.GetPoint(0).screen); + + if(event.GetPoint(0).state == Dali::TouchPoint::Down) + { + mLongTapTimer.Start(); + } + + Actor self = Self(); + + struct widget_mouse_event_info info; + + Vector3 screenposition = _GetScreenPosition(); + info.x = event.GetPoint(0).screen.x - screenposition.x; + info.y = event.GetPoint(0).screen.y - screenposition.y; + + info.ratio_w = 1.0f; + info.ratio_h = 1.0f; + info.device = 0; + + if(event.GetPoint(0).state == Dali::TouchPoint::Down) + { + mIsTouched = true; + mLongTapTimer.Start(); + mDownPos.x = info.x; + mDownPos.y = info.y; + + widget_viewer_feed_mouse_event(static_cast(mHandler), WIDGET_MOUSE_ENTER, &info); + widget_viewer_feed_mouse_event(static_cast(mHandler), WIDGET_MOUSE_DOWN, &info); + } + else if(event.GetPoint(0).state == Dali::TouchPoint::Up) + { + if(mIsTouched) + { + float gapX = fabs(info.x - mDownPos.x); + float gapY = fabs(info.y - mDownPos.y); + + if(gapX <= TAPPED_BOUNDARY_WIDTH && gapY <= TAPPED_BOUNDARY_HEIGHT) + { + mSignalTapped.Emit(handle, event.GetPoint(0).screen); + _OnWidgetTapped(); + } + } + mIsTouched = false; + + if (mLongTapTimer.IsRunning()) + { + mLongTapTimer.Stop(); + } + + widget_viewer_feed_mouse_event(static_cast(mHandler), WIDGET_MOUSE_UP, &info); + widget_viewer_feed_mouse_event(static_cast(mHandler), WIDGET_MOUSE_LEAVE, &info); + } + else if(event.GetPoint(0).state == Dali::TouchPoint::Motion) + { + if(mIsTouched && mLongTapTimer.IsRunning()) + { + float gapX = fabs(info.x - mDownPos.x); + float gapY = fabs(info.y - mDownPos.y); + + if(gapX > TAPPED_BOUNDARY_WIDTH || gapY > TAPPED_BOUNDARY_HEIGHT) + { + mLongTapTimer.Stop(); + } + } + widget_viewer_feed_mouse_event(static_cast(mHandler), WIDGET_MOUSE_MOVE, &info); + } + else if(event.GetPoint(0).state == Dali::TouchPoint::Leave || event.GetPoint(0).state == Dali::TouchPoint::Interrupted) + { + mIsTouched = false; + + if (mLongTapTimer.IsRunning()) + { + mLongTapTimer.Stop(); + } + + /*widget_viewer_feed_mouse_event(static_cast(mHandler), WIDGET_MOUSE_UP, &info);*/ + widget_viewer_feed_mouse_event(static_cast(mHandler), WIDGET_MOUSE_LEAVE, &info); + } + + return false; +} + +bool CWidget::OnTouch(const TouchEvent& event) +{ + return _OnEventAreaTouchEvent(Self(), event); +} + +void CWidget::_OnWidgetTapped() +{ + if(!mIsFaulted) + return ; + + if(mFaultedTextLabel) + { + mFaultedTextLabel.SetProperty(Toolkit::TextLabel::Property::TEXT, _("IDS_ST_BODY_LOADING_ING")); + } + + WidgetViewerDali::CWidget handle ( GetOwner() ); + mSignalReload.Emit(handle); +} + +void CWidget::SetGridPosition(int row, int col) +{ + mRow = row; + mCol = col; +} + +void CWidget::GetGridPosition(int *row, int *col) +{ + *row = mRow; + *col = mCol; +} + +Vector3 CWidget::_GetScreenPosition() +{ + Actor self = Self(); + Vector3 position = self.GetCurrentPosition(); + Actor actor = self.GetParent(); + + while(actor) + { + position += actor.GetCurrentPosition(); + + actor = actor.GetParent(); + + } + + return position; +} + +void CWidget::SetFault(bool fault) +{ + mIsFaulted = fault; +} + +bool CWidget::_OnLongTapTimerComplete() +{ + WidgetViewerDali::CWidget handle ( GetOwner() ); + mSignalLongpressed.Emit(handle, mDownPos); + return false; +} + +void CWidget::OnFault() +{ + mIsFaulted = true; + if(mLoadingTextLabel) + { + mLoadingTextLabel.SetOpacity(0.0f); + } + + if(!mFaultDimBg) + { + mFaultDimBg = Toolkit::CreateSolidColorActor(Vector4(0.3, 0.3, 0.3, 0.85)); + mFaultDimBg.SetZ(0.1f); + mFaultDimBg.SetParentOrigin(ParentOrigin::CENTER); + mFaultDimBg.SetAnchorPoint(AnchorPoint::CENTER); + + Constraint constraint = Constraint::New( mFaultDimBg, Actor::Property::SIZE, EqualToConstraint() ); + constraint.AddSource( ParentSource(Actor::Property::SIZE) ); + constraint.Apply(); + + mBaseImage.Add(mFaultDimBg); + } + + if(!mFaultedTextLabel) + { + Vector2 resolution = Stage::GetCurrent().GetDpi(); + mFaultedTextLabel = Toolkit::TextLabel::New(_("IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY")); + mFaultedTextLabel.SetProperty(Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER"); + mFaultedTextLabel.SetProperty(Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER"); + mFaultedTextLabel.SetProperty(Toolkit::TextLabel::Property::POINT_SIZE, WIDGET_LOADING_TEXT_SIZE * 72.0f/resolution.y); + mFaultedTextLabel.SetProperty(Toolkit::TextLabel::Property::TEXT_COLOR, Vector4(1.0f, 1.0f, 1.0f, 1.0f)); + + mFaultedTextLabel.SetAnchorPoint(AnchorPoint::CENTER); + mFaultedTextLabel.SetParentOrigin(ParentOrigin::CENTER); + + mFaultedTextLabel.SetSize(WIDGET_LOADING_TEXT_WIDTH, WIDGET_LOADING_TEXT_SIZE * 3); + mFaultedTextLabel.SetPosition(Vector3(0.0f, 0.0f, 0.0f)); + + mFaultedTextLabel.SetZ(0.1f); + + mFaultDimBg.Add(mFaultedTextLabel); + } + else + { + mFaultedTextLabel.SetProperty(Toolkit::TextLabel::Property::TEXT, _("IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY")); + } + + mFaultDimBg.SetOpacity(mIsEditMode ? 0.0f : 1.0f); +} + +} +} + diff --git a/widget_viewer_dali/src/widget_dali_list.cpp b/widget_viewer_dali/src/widget_dali_list.cpp new file mode 100755 index 0000000..73ce68a --- /dev/null +++ b/widget_viewer_dali/src/widget_dali_list.cpp @@ -0,0 +1,113 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "widget_dali_list.h" + +using namespace Dali; +using namespace WidgetViewerDali; + +namespace WidgetViewerDali +{ + +CWidgetList::CWidgetList() +{ + m_mWidgetList.clear(); +} + +CWidgetList::~CWidgetList() +{ +} + +int CWidgetList::Add(void* handle, CWidget widget) +{ + DbgPrint("size[%d]", m_mWidgetList.size()); + + m_mWidgetList[handle] = widget; + + DbgPrint("size[%d]", m_mWidgetList.size()); + + return m_mWidgetList.size(); +} + +void CWidgetList::Remove(void* handle) +{ + DbgPrint("size[%d]", m_mWidgetList.size()); + + std::map::iterator iter = m_mWidgetList.find(handle); + + m_mWidgetList.erase(iter); + + DbgPrint("size[%d]", m_mWidgetList.size()); +} + +CWidget CWidgetList::GetWidget(unsigned int id) +{ + std::map::iterator iter; + for(iter = m_mWidgetList.begin(); iter!= m_mWidgetList.end(); iter++) + { + if(iter->second.GetWidgetId() == id) + { + DbgPrint("Get id[%d]", id); + return iter->second; + } + } + + return NULL; +} + +unsigned int CWidgetList::GetWidgetId(void *handle) +{ + std::map::iterator iter; + for(iter = m_mWidgetList.begin(); iter!= m_mWidgetList.end(); iter++) + { + if(iter->first == handle) + { + return iter->second.GetWidgetId(); + } + } + + ErrPrint("Widget is wrong!"); + return 0; +} + +std::vector CWidgetList::GetWidgetList(const char * pkgname) +{ + std::vector list; + std::map::iterator iter; + for(iter = m_mWidgetList.begin(); iter!= m_mWidgetList.end(); iter++) + { + if(!iter->second.GetPkgName().compare(pkgname)) + { + list.push_back(iter->second); + } + } + + return list; +} + +void CWidgetList::Update(void* handle, void* newHandle, CWidget widget) +{ + DbgPrint("handle %p, newhandle %p", handle, newHandle); + + widget.SetWidgetHandler(newHandle); + m_mWidgetList[newHandle] = widget; + Remove(handle); +} + +} + diff --git a/widget_viewer_dali/src/widget_viewer_dali.cpp b/widget_viewer_dali/src/widget_viewer_dali.cpp new file mode 100755 index 0000000..24451c8 --- /dev/null +++ b/widget_viewer_dali/src/widget_viewer_dali.cpp @@ -0,0 +1,426 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "widget_viewer_dali_generic.h" +#include "widget_viewer_dali.h" +#include "widget_dali_list.h" +#include "debug.h" + +#define WIDGET_DEFAULT_CLUSTER "user,created" +#define WIDGET_DEFAULT_CATEGORY "default" + +#define FAULT_RETRY_MAX_COUNT 3 + + using namespace Dali; + using namespace WidgetViewerDali; + +CWidgetManager* CWidgetManager::m_pInstance = NULL; + +static int widget_is_exists(const char *pkgname) +{ + int ret=1; + char *widget; + widget = widget_service_get_widget_id(pkgname); + if(!widget) { + ret = 0; + } + free(widget); + return ret; +} + +static int WidgetProviderWidgetEventCB(widget_h handler, widget_event_type_e event, void *data) +{ + CWidgetManager *pWidgeProvider = static_cast(data); + + if(handler == NULL) + { + return EXIT_FAILURE; + } + + if(event == WIDGET_EVENT_WIDGET_UPDATED) + { + DbgPrint("handler : %p, event : update[%d]", handler, event); + pWidgeProvider->WidgetEventUpdated(handler); + } + else if(event == WIDGET_EVENT_DELETED) + { + DbgPrint("handler : %p, event : deleted[%d]", handler, event); + pWidgeProvider->WidgetEventDeleted(handler); + } + else if(event == WIDGET_EVENT_HOLD_SCROLL) + { + DbgPrint("handler : %p, event : hold scroll[%d]", handler, event); + /*pWidgeProvider->WidgetEventScrollLocked(handler, false);*/ + } + else if(event == WIDGET_EVENT_RELEASE_SCROLL) + { + DbgPrint("handler : %p, event : release scroll[%d]", handler, event); + /*pWidgeProvider->WidgetEventScrollLocked(handler, true);*/ + } + else + { + DbgPrint("Not supported event : %d", event); + } + + return EXIT_SUCCESS; +} + +static void WidgetProviderWidgetActivateCB(widget_h handle, int ret, void *data) +{ + if(ret == 0) + { + /* Success */ + DbgPrint("handle : %p, Activate", handle); + } + else + { + ErrPrint("Failed to widget_activate[%x]", ret); + } +} + +static int WidgetProviderWidgetFaultCB(widget_fault_type_e event, const char *pkgname, const char *filename, const char *funcname, void *data) +{ + CWidgetManager *pWidgeProvider = static_cast(data); + + if(pWidgeProvider && event == WIDGET_FAULT_DEACTIVATED) + { + DbgPrint("event[%d], pkgname[%s]", event, pkgname); + widget_viewer_activate_faulted_widget(pkgname, WidgetProviderWidgetActivateCB, data); + + pWidgeProvider->WidgetFaulted(pkgname); + } + else if(pWidgeProvider && event == WIDGET_FAULT_PROVIDER_DISCONNECTED) + { + /*pWidgeProvider->WidgetProviderDisconnected();*/ + } + + return EXIT_SUCCESS; +} + +static void WidgetProviderWidgetAddCB(widget_h handle, int ret, void *data) +{ + CWidgetManager *pWidgeProvider = static_cast(data); + + if(pWidgeProvider == NULL) + { + ErrPrint("invalid add callback data"); + return; + } + + switch (ret) { + case WIDGET_ERROR_NONE: + DbgPrint("handle : %p, Add", handle); + pWidgeProvider->WidgetEventCreated(handle); + break; + case WIDGET_ERROR_ALREADY_EXIST: + /*ret = notification_status_message_post("Dynamic Box is already exists"); + if(ret != NOTIFICATION_ERROR_NONE) + { + ErrPrint("Failed to make notification"); + } + pWidgeProvider->WidgetEventDeleted(handle);*/ + break; + case -1: /*fall through*/ + /* Temporarly used */ + pWidgeProvider->WidgetEventDeleted(handle); + break; + default: + /*ErrPrint("Failed to widget_viewer_add_widget[%d][%p]", ret, handle); + widgetDataProvider->WidgetEventDeleted(handle); + + pWidgeProvider->WidgetAddFailed(handle, ret);*/ + break; + } +} + +static void WidgetProviderWidgetDeleteCB(widget_h handle, int ret, void *data) +{ + if(ret == 0) + { + /* Success */ + DbgPrint("handle : %p, Delete", handle); + CWidgetManager *pWidgeProvider = static_cast(data); + + pWidgeProvider->WidgetEventDeleted(handle); + } + else + { + ErrPrint("Failed to widget_viewer_delete_widget[%d]", ret); + } +} + +static void WidgetProviderWidgetPixmapAcquiredCB(widget_h handle, int pixmapId, void *data) +{ + CWidgetManager *pWidgeProvider = static_cast(data); + pWidgeProvider->EventPixmapAcquired(handle, (unsigned int)pixmapId); +} + +namespace WidgetViewerDali +{ +CWidgetManager::CWidgetManager() +{ + widget_viewer_set_option(WIDGET_OPTION_DIRECT_UPDATE, 1); + /* initialize widget, (XDisplay, prevent_overwrite, event_filtering, use_thread) */ + widget_viewer_init(ecore_x_display_get(), 1, 0.01f, 1); + widget_viewer_add_event_handler(WidgetProviderWidgetEventCB, this); + widget_viewer_add_fault_handler(WidgetProviderWidgetFaultCB, this); +} + +CWidgetManager::~CWidgetManager() +{ + widget_viewer_remove_fault_handler(WidgetProviderWidgetFaultCB); + widget_viewer_remove_event_handler(WidgetProviderWidgetEventCB); + + widget_viewer_fini(); +} + +EAPI void CWidgetManager::Initialize() +{ + DbgPrint("Initialize"); + mWidgetList = new CWidgetList; +} + +EAPI int CWidgetManager::AddWidget(unsigned int id, const char *pkgname, const char *name, widget_size_type_e type, const char *content, + const char *icon, int pid, double period, int allow_duplicate) +{ + if(1 == widget_is_exists(pkgname)) + { + void* handle = widget_viewer_add_widget(pkgname, NULL, WIDGET_DEFAULT_CLUSTER, WIDGET_DEFAULT_CATEGORY, period, type, WidgetProviderWidgetAddCB, this); + + if(handle != NULL) + { + CWidget widget = CWidget::New(id, handle, pkgname, type, period); + widget.SignalDeleted().Connect(this, &CWidgetManager::OnWidgetDeleted); + widget.SignalReload().Connect(this, &CWidgetManager::OnWidgetReload); + mWidgetList->Add(handle, widget); + + mSignalWidgetAdded.Emit(widget); + } + + return 0; + } + + return -1; +} + +bool CWidgetManager::OnWidgetDeleted(WidgetViewerDali::CWidget& widget) +{ + unsigned int id = widget.GetWidgetId(); + DbgPrint("widget[%d] deleted", id); + + if(1 == widget_is_exists(widget.GetPkgName().c_str())) + { + if(widget.GetWidgetHandle()) + { + int ret = widget_viewer_delete_widget(static_cast(widget.GetWidgetHandle()), WIDGET_DELETE_PERMANENTLY, WidgetProviderWidgetDeleteCB, this); + DbgPrint("call widget_viewer_delete_widget[%d]", ret); + } + } + else + { + mWidgetList->Remove(widget.GetWidgetHandle()); + } + + mSignalWidgetDeleted.Emit(widget); + + return true; +} + +bool CWidgetManager::OnWidgetReload(WidgetViewerDali::CWidget& widget) +{ + unsigned int id = widget.GetWidgetId(); + DbgPrint("widget[%d] reload", id); + + if(1 == widget_is_exists(widget.GetPkgName().c_str())) + { + widget_viewer_activate_faulted_widget(widget.GetPkgName().c_str(), WidgetProviderWidgetActivateCB, this); + + void* handle = widget_viewer_add_widget(widget.GetPkgName().c_str(), widget.GetPkgName().c_str(), WIDGET_DEFAULT_CLUSTER, WIDGET_DEFAULT_CATEGORY, widget.GetPeriod(), widget.GetSizeType(), WidgetProviderWidgetAddCB, this); + + if(widget.GetWidgetHandle()) + { + int ret = widget_viewer_delete_widget(static_cast(widget.GetWidgetHandle()), WIDGET_DELETE_PERMANENTLY, WidgetProviderWidgetDeleteCB, this); + DbgPrint("call widget_viewer_delete_widget[%d]", ret); + } + + if(handle != NULL) + { + mWidgetList->Update(widget.GetWidgetHandle(), handle, widget); + } + } + + return true; +} + +void CWidgetManager::WidgetEventCreated(void *handler) +{ + widget_h hWidget = static_cast(handler); + widget_viewer_set_visibility(hWidget, WIDGET_SHOW); +} + +void CWidgetManager::WidgetEventUpdated(void *handler) +{ + unsigned int id = mWidgetList->GetWidgetId(handler); + + DbgPrint("WidgetEventUpdated [%d]\n", id); + + if(!id) + { + ErrPrint("widget is not valid"); + return; + } + + CWidget widget = mWidgetList->GetWidget(id); + + unsigned int resource_id =0; + widget_viewer_get_resource_id(static_cast(handler), 0, &resource_id); + DbgPrint("resource_id, pixmap [%d,%d]", resource_id, widget.GetPixmap()); + if(resource_id != widget.GetPixmap()) + { + if(widget_viewer_acquire_resource_id(static_cast(handler), 0, WidgetProviderWidgetPixmapAcquiredCB, this) < 0) + { + DbgPrint("Failed to acquire pixmap\n"); + } + } + else + { + if(resource_id != 0) + { + widget.UpdateByPixmap(resource_id); + } + else + { + ErrPrint("Failed to get widget"); + return; + } + } +} + +void CWidgetManager::WidgetEventDeleted(void *handler) +{ + unsigned int id = mWidgetList->GetWidgetId(handler); + + DbgPrint("WidgetEventDeleted [%p] [%d]", handler, id); + + if(!id) + { + ErrPrint("widget is not valid"); + return; + } + + CWidget widget = mWidgetList->GetWidget(id); + + if(widget.IsFaulted()) + { + widget.OnFault(); + + if(widget.GetPixmap() != 0) { + widget_viewer_release_resource_id((widget_h)handler, 0, widget.GetPixmap()); + widget.SetPixmap(0); + } + } + else + { + if(widget.GetPixmap() != 0) { + widget_viewer_release_resource_id((widget_h)handler, 0, widget.GetPixmap()); + widget.SetPixmap(0); + } + + mWidgetList->Remove(widget.GetWidgetHandle()); + } + +} + + +void CWidgetManager::WidgetFaulted(const char *pkgname) +{ + if(!pkgname) + { + ErrPrint("invalid pkgname"); + return; + } + + std::vector list = mWidgetList->GetWidgetList(pkgname); + std::vector::iterator iter; + + if(list.empty()) + { + DbgPrint("No boxes that pkgname is[%s]", pkgname); + } + else + { + for (iter = list.begin(); iter != list.end(); iter++) + { + if(iter->IsFaulted()) + { + DbgPrint("Already faulted widget[%d][%s]", iter->GetWidgetId(), iter->GetPkgName().c_str()); + } + else + { + DbgPrint("Set faulted widget[%d][%s]", iter->GetWidgetId(), iter->GetPkgName().c_str()); + iter->SetFault(true); + } + } + } +} + +void CWidgetManager::EventPixmapAcquired(void *handler, unsigned int pixmapId) +{ + DbgPrint("EventPixmapAcquired [%p] [%d]\n", handler, pixmapId); + unsigned int id = mWidgetList->GetWidgetId(handler); + + if(!id) + { + ErrPrint("widget is not valid"); + return; + } + + CWidget widget = mWidgetList->GetWidget(id); + + if(widget.GetPixmap()) + { + ErrPrint("Release pixmap [%d]", widget.GetPixmap()); + widget_viewer_release_resource_id(static_cast(handler), 0, widget.GetPixmap()); + } + + if(pixmapId != 0) + { + widget.UpdateByPixmap(pixmapId); + } + else + { + ErrPrint("Failed to get widget"); + return; + } +} + +EAPI CWidgetManager* CWidgetManager::GetInstance() +{ + if(m_pInstance == NULL) + { + m_pInstance = new CWidgetManager; + } + + return m_pInstance; +} + +} diff --git a/widget_viewer_dali/widget_viewer_dali.pc.in b/widget_viewer_dali/widget_viewer_dali.pc.in new file mode 100755 index 0000000..f93096f --- /dev/null +++ b/widget_viewer_dali/widget_viewer_dali.pc.in @@ -0,0 +1,12 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: widget_viewer_dali +Description: Support development of the widget Viewer DALi library +Version: @VERSION@ +Requires: widget_service widget_viewer +Libs: -L${libdir} -lwidget_viewer_dali +Cflags: -I${includedir} +cppflags: -I${includedir} diff --git a/widget_viewer_evas/doc/widget_viewer_evas_doc.h b/widget_viewer_evas/doc/widget_viewer_evas_doc.h index 8fbaef5..0fdcbe1 100644 --- a/widget_viewer_evas/doc/widget_viewer_evas_doc.h +++ b/widget_viewer_evas/doc/widget_viewer_evas_doc.h @@ -29,4 +29,8 @@ * * First of all, the Tizen Platform uses the EFL as a core UIFW. * So this API set also based on the EFL. + * + * @section CAPI_WIDGET_VIEWER_EVAS_MODULE_FEATURE Related Features + * This API is related with the following feature: + * - http://tizen.org/feature/shell.appwidget */ diff --git a/widget_viewer_evas/include/widget_viewer_evas.h b/widget_viewer_evas/include/widget_viewer_evas.h index 48540bd..68982f2 100644 --- a/widget_viewer_evas/include/widget_viewer_evas.h +++ b/widget_viewer_evas/include/widget_viewer_evas.h @@ -48,21 +48,91 @@ extern "C" { /** * @since_tizen 2.3.1 - * @brief Event names for smart callback of widget events. You can listen some events from widget by calling evas_object_smart_callback_add. + * @brief Event name for smart callback of widget events: Widget creation is aborted * @see #widget_evas_event_info_s * @see evas_object_smart_callback_add */ -#define WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED "widget,create,aborted" /**< Widget creation is aborted */ -#define WIDGET_SMART_SIGNAL_WIDGET_CREATED "widget,created" /**< Widget is created */ -#define WIDGET_SMART_SIGNAL_WIDGET_RESIZE_ABORTED "widget,resize,aborted" /**< Resizing widget is aborted */ -#define WIDGET_SMART_SIGNAL_WIDGET_RESIZED "widget,resized" /**< Widget is resized */ -#define WIDGET_SMART_SIGNAL_WIDGET_FAULTED "widget,faulted" /**< Widget has faulted */ -#define WIDGET_SMART_SIGNAL_UPDATED "updated" /**< Widget content is updated */ -#define WIDGET_SMART_SIGNAL_EXTRA_INFO_UPDATED "info,updated" /**< Widget extra info is updated */ -#define WIDGET_SMART_SIGNAL_PROVIDER_DISCONNECTED "provider,disconnected" /**< Provider is disconnected */ -#define WIDGET_SMART_SIGNAL_CONTROL_SCROLLER "control,scroller" /**< Control Scroller */ -#define WIDGET_SMART_SIGNAL_WIDGET_DELETED "widget,deleted" /**< Widget is deleted */ -#define WIDGET_SMART_SIGNAL_PERIOD_CHANGED "widget,period,changed" /**< Period is changed */ +#define WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED "widget,create,aborted" + +/** + * @since_tizen 2.3.1 + * @brief Event name for smart callback of widget events: Widget is created + * @see #widget_evas_event_info_s + * @see evas_object_smart_callback_add + */ +#define WIDGET_SMART_SIGNAL_WIDGET_CREATED "widget,created" + +/** + * @since_tizen 2.3.1 + * @brief Event name for smart callback of widget events: Resizing widget is aborted + * @see #widget_evas_event_info_s + * @see evas_object_smart_callback_add + */ +#define WIDGET_SMART_SIGNAL_WIDGET_RESIZE_ABORTED "widget,resize,aborted" + +/** + * @since_tizen 2.3.1 + * @brief Event name for smart callback of widget events: Widget is resized + * @see #widget_evas_event_info_s + * @see evas_object_smart_callback_add + */ +#define WIDGET_SMART_SIGNAL_WIDGET_RESIZED "widget,resized" + +/** + * @since_tizen 2.3.1 + * @brief Event name for smart callback of widget events: Widget has faulted + * @see #widget_evas_event_info_s + * @see evas_object_smart_callback_add + */ +#define WIDGET_SMART_SIGNAL_WIDGET_FAULTED "widget,faulted" + +/** + * @since_tizen 2.3.1 + * @brief Event name for smart callback of widget events: Widget content is updated + * @see #widget_evas_event_info_s + * @see evas_object_smart_callback_add + */ +#define WIDGET_SMART_SIGNAL_UPDATED "updated" + +/** + * @since_tizen 2.3.1 + * @brief Event name for smart callback of widget events: Widget extra info is updated + * @see #widget_evas_event_info_s + * @see evas_object_smart_callback_add + */ +#define WIDGET_SMART_SIGNAL_EXTRA_INFO_UPDATED "info,updated" + +/** + * @since_tizen 2.3.1 + * @brief Event name for smart callback of widget events: Provider is disconnected + * @see #widget_evas_event_info_s + * @see evas_object_smart_callback_add + */ +#define WIDGET_SMART_SIGNAL_PROVIDER_DISCONNECTED "provider,disconnected" + +/** + * @since_tizen 2.3.1 + * @brief Event name for smart callback of widget events: Control Scroller + * @see #widget_evas_event_info_s + * @see evas_object_smart_callback_add + */ +#define WIDGET_SMART_SIGNAL_CONTROL_SCROLLER "control,scroller" + +/** + * @since_tizen 2.3.1 + * @brief Event name for smart callback of widget events: Widget is deleted + * @see #widget_evas_event_info_s + * @see evas_object_smart_callback_add + */ +#define WIDGET_SMART_SIGNAL_WIDGET_DELETED "widget,deleted" + +/** + * @since_tizen 2.3.1 + * @brief Event name for smart callback of widget events: Period is changed + * @see #widget_evas_event_info_s + * @see evas_object_smart_callback_add + */ +#define WIDGET_SMART_SIGNAL_PERIOD_CHANGED "widget,period,changed" /** * @since_tizen 2.3.1 @@ -285,7 +355,7 @@ extern double widget_viewer_evas_get_period(Evas_Object *widget); */ extern void widget_viewer_evas_cancel_click_event(Evas_Object *widget); -/* +/** * @brief Hides the preview of the widget * @remarks This function should be called right after create the widget object before resizing it * @since_tizen 2.3.1 diff --git a/widget_viewer_evas/include/widget_viewer_evas_internal.h b/widget_viewer_evas/include/widget_viewer_evas_internal.h index 2e12237..5faae3b 100644 --- a/widget_viewer_evas/include/widget_viewer_evas_internal.h +++ b/widget_viewer_evas/include/widget_viewer_evas_internal.h @@ -34,6 +34,8 @@ extern "C" { #define WIDGET_VIEWER_EVAS_SHARED_CONTENT 0x0002 /**< Multiple instances will share the content of one real instance */ #define WIDGET_VIEWER_EVAS_SUPPORT_GBAR 0x0004 /**< GBAR will be used */ +#define WIDGET_VIEWER_EVAS_DISABLE_SCROLLER 0x4000 + typedef enum widget_access_result { WIDGET_ACCESS_RESULT_DONE = 0x00, WIDGET_ACCESS_RESULT_FIRST = 0x01, @@ -269,6 +271,7 @@ extern int widget_viewer_evas_set_preview_image(Evas_Object *widget, widget_size */ extern int widget_viewer_evas_hide_overlay(Evas_Object *widget); +extern int widget_viewer_evas_hide_faulted_overlay_once(Evas_Object *widget); #ifdef __cplusplus } #endif diff --git a/widget_viewer_evas/src/widget_viewer_evas.c b/widget_viewer_evas/src/widget_viewer_evas.c index 4e5efc2..c7e72bc 100644 --- a/widget_viewer_evas/src/widget_viewer_evas.c +++ b/widget_viewer_evas/src/widget_viewer_evas.c @@ -78,7 +78,6 @@ #define _(str) gettext(str) #endif - #if !defined(DbgPrint) #define DbgPrint(format, arg...) SECURE_LOGD(format, ##arg) #endif @@ -156,6 +155,12 @@ int errno; */ #define CLICK_REGION WIDGET_CONF_CLICK_REGION +#if defined(__LP64__) || defined(_LP64) +#define PTR_TYPE(a) ((long long)(a)) +#else +#define PTR_TYPE(a) ((int)(a)) +#endif + static struct { Evas_Smart_Class sc; Evas_Smart *smart; @@ -183,8 +188,9 @@ static struct { unsigned int render_animator:1; unsigned int auto_render_selector:1; unsigned int skip_acquire:1; + unsigned int disable_internal_scroller: 1; - unsigned int reserved:18; + unsigned int reserved:17; } field; unsigned int mask; } conf; @@ -195,6 +201,8 @@ static struct { Eina_List *gbar_dirty_objects; Eina_List *subscribed_category_list; Eina_List *subscribed_group_list; + Eina_List *updated_pixmap_list; + Eina_List *updated_pixmap_lock_list; int initialized; } s_info = { @@ -216,6 +224,8 @@ static struct { .gbar_dirty_objects = NULL, .subscribed_category_list = NULL, .subscribed_group_list = NULL, + .updated_pixmap_list = NULL, + .updated_pixmap_lock_list = NULL, .initialized = 0, }; @@ -355,7 +365,11 @@ struct widget_data { unsigned int hide_overlay_manually:1; - unsigned int reserved: 1; + /** + * @note + * Do not raise up the overlay for faulted. + */ + unsigned int hide_faulted_overlay: 1; } field; /* Do we really have the performance loss because of bit fields? */ unsigned int flags; @@ -974,11 +988,6 @@ struct widget_data *widget_unref(struct widget_data *data) data->overlay_timer = NULL; } - if (data->stage) { - DbgPrint("Remove Stage\n"); - evas_object_del(data->stage); - } - if (data->widget_layout) { Evas_Object *content; @@ -1005,6 +1014,8 @@ struct widget_data *widget_unref(struct widget_data *data) DbgPrint("Remove WIDGET Layout\n"); evas_object_del(data->widget_layout); + } else { + DbgPrint("Layout is already deleted\n"); } if (data->gbar_layout) { @@ -1020,6 +1031,15 @@ struct widget_data *widget_unref(struct widget_data *data) } DbgPrint("Remove GBAR Layout\n"); evas_object_del(data->gbar_layout); + } else { + DbgPrint("GBar layout is already deleted\n"); + } + + if (data->stage) { + DbgPrint("Remove Stage\n"); + evas_object_del(data->stage); + } else { + DbgPrint("Stage is already deleted\n"); } if (data->widget_fb) { @@ -2793,6 +2813,20 @@ static void gbar_create_pixmap_object(struct widget_data *data) } } +static void gbar_layout_del_cb(void *_data, Evas *e, Evas_Object *obj, void *event_info) +{ + struct widget_data *data = _data; + DbgPrint("GBar layout is deleted(%p - %p)\n", data->gbar_layout, obj); + /** + * @note + * We should not access the data->gbar_layout in this function. + * We can only believe the "obj" now.. + */ + evas_object_smart_member_del(obj); + evas_object_clip_unset(obj); + data->gbar_layout = NULL; +} + static void __widget_create_gbar_cb(struct widget *handle, int ret, void *cbdata) { struct widget_data *data = cbdata; @@ -2852,6 +2886,7 @@ static void __widget_create_gbar_cb(struct widget *handle, int ret, void *cbdata widget_unref(data); return; } + evas_object_event_callback_add(data->gbar_layout, EVAS_CALLBACK_DEL, gbar_layout_del_cb, data); if (elm_layout_file_set(data->gbar_layout, WIDGET_VIEWER_EVAS_RESOURCE_EDJ, WIDGET_VIEWER_EVAS_RESOURCE_GBAR) == EINA_FALSE) { ErrPrint("Failed to load edje object: %s(%s)\n", WIDGET_VIEWER_EVAS_RESOURCE_EDJ, WIDGET_VIEWER_EVAS_RESOURCE_GBAR); @@ -3187,7 +3222,7 @@ static void __widget_up_cb(void *cbdata, Evas *e, Evas_Object *obj, void *event_ data = widget_unref(data); } } else if (data->is.field.cancel_click == CANCEL_DISABLED) { - ret = widget_viewer_send_click_event(data->handle, minfo.x, minfo.y); + ret = widget_viewer_send_click_event(data->handle, WIDGET_VIEWER_CLICK_BUTTON_LEFT, minfo.x, minfo.y); } } @@ -3513,6 +3548,28 @@ static void __widget_overlay_clicked_cb(void *cbdata, Evas_Object *obj, const ch } } +static void widget_layout_del_cb(void *_data, Evas *e, Evas_Object *obj, void *event_info) +{ + struct widget_data *data = _data; + DbgPrint("Layout is deleted (%p - %p)\n", data->widget_layout, obj); + evas_object_smart_member_del(obj); + evas_object_clip_unset(obj); + data->widget_layout = NULL; +} + +static void stage_del_cb(void *_data, Evas *e, Evas_Object *obj, void *event_info) +{ + struct widget_data *data = _data; + + DbgPrint("Stage is deleted (%p - %p)\n", data->stage, obj); + if (data->widget_layout) { + evas_object_clip_unset(data->widget_layout); + } + + evas_object_smart_member_del(obj); + data->stage = NULL; +} + static void __widget_data_setup(struct widget_data *data) { data->e = evas_object_evas_get(data->widget); @@ -3551,7 +3608,7 @@ static void __widget_data_setup(struct widget_data *data) return; } - if (s_info.conf.field.is_scroll_x || s_info.conf.field.is_scroll_y) { + if (!s_info.conf.field.disable_internal_scroller && (s_info.conf.field.is_scroll_x || s_info.conf.field.is_scroll_y)) { Evas_Object *scroller; scroller = elm_scroller_add(data->parent); if (scroller) { @@ -3606,6 +3663,8 @@ static void __widget_data_setup(struct widget_data *data) evas_object_smart_member_add(data->widget_layout, data->widget); evas_object_clip_set(data->widget_layout, data->stage); + evas_object_event_callback_add(data->widget_layout, EVAS_CALLBACK_DEL, widget_layout_del_cb, data); + evas_object_event_callback_add(data->stage, EVAS_CALLBACK_DEL, stage_del_cb, data); } static Eina_Bool renderer_cb(void *_data) @@ -3638,7 +3697,7 @@ static void append_widget_dirty_object_list(struct widget_data *data, int idx) } if (widget_viewer_get_visibility(data->handle) != WIDGET_SHOW) { - DbgPrint("Box is not visible\n"); + DbgPrint("Box[%s] is not visible\n", data->widget_id); return; } @@ -3899,7 +3958,7 @@ static void __widget_del(Evas_Object *widget) } else { delete_type = WIDGET_DELETE_TEMPORARY; } - DbgPrint("Send delete request (0x%X)\n", delete_type); + DbgPrint("Send delete request (0x%X) - %s\n", delete_type, data->widget_id); if (data->is.field.created) { if (widget_viewer_delete_widget(data->handle, delete_type, __widget_destroy_widget_cb, widget_ref(data)) < 0) { @@ -4761,6 +4820,12 @@ static void acquire_widget_pixmap_cb(struct widget *handle, int pixmap, void *cb if (!s_info.conf.field.skip_acquire) { free(acquire_data); } + + if (WIDGET_CONF_ENABLE_RESOURCE_LOCK) { + if (!eina_list_data_find(s_info.updated_pixmap_list, (void *)(PTR_TYPE(pixmap)))) { + s_info.updated_pixmap_list = eina_list_append(s_info.updated_pixmap_list, (void *)(PTR_TYPE(pixmap))); + } + } } static void __widget_update_pixmap_object(struct widget_data *data, Evas_Object *widget_content, int w, int h) @@ -4769,53 +4834,71 @@ static void __widget_update_pixmap_object(struct widget_data *data, Evas_Object struct acquire_data *acquire_data; if (data->widget_latest_idx == WIDGET_PRIMARY_BUFFER) { - unsigned int resource_id; + unsigned int resource_id = 0u; + + if (widget_viewer_get_resource_id(data->handle, 0, &resource_id) < 0) { + ErrPrint("Failed to get resource_id\n"); + } else if (resource_id > 0) { + if (data->widget_pixmap == resource_id) { + if (data->widget_extra) { + /* Just replace the pixmap in this case, do not release old pixmap */ + replace_pixmap(NULL, 0, widget_content, data->widget_pixmap); + } + + update_widget_pixmap(widget_content, w, h); - widget_viewer_get_resource_id(data->handle, 0, &resource_id); - if (data->widget_pixmap == resource_id) { - if (data->widget_extra) { - /* Just replace the pixmap in this case, do not release old pixmap */ - replace_pixmap(NULL, 0, widget_content, data->widget_pixmap); + if (WIDGET_CONF_ENABLE_RESOURCE_LOCK) { + if (!eina_list_data_find(s_info.updated_pixmap_list, (void *)(PTR_TYPE(resource_id)))) { + s_info.updated_pixmap_list = eina_list_append(s_info.updated_pixmap_list, (void *)(PTR_TYPE(resource_id))); + } + } + return; } - update_widget_pixmap(widget_content, w, h); - return; - } + if (s_info.conf.field.skip_acquire && resource_id != 0) { + struct acquire_data local_acquire_data = { + .data = widget_ref(data), + .content = widget_content, + .w = w, + .h = h, + }; - if (s_info.conf.field.skip_acquire && resource_id != 0) { - struct acquire_data local_acquire_data = { - .data = widget_ref(data), - .content = widget_content, - .w = w, - .h = h, - }; + /** + * @note + * Resource lock will be acquired from below callback. + */ + acquire_widget_pixmap_cb(data->handle, resource_id, &local_acquire_data); + return; + } - acquire_widget_pixmap_cb(data->handle, resource_id, &local_acquire_data); - return; - } + if (data->is.field.widget_pixmap_acquire_requested) { + DbgPrint("Pixmap is not acquired (in-process)\n"); + return; + } - if (data->is.field.widget_pixmap_acquire_requested) { - DbgPrint("Pixmap is not acquired\n"); - return; - } + acquire_data = malloc(sizeof(*acquire_data)); + if (!acquire_data) { + ErrPrint("malloc: %d\n", errno); + return; + } - acquire_data = malloc(sizeof(*acquire_data)); - if (!acquire_data) { - ErrPrint("malloc: %d\n", errno); - return; - } + acquire_data->data = widget_ref(data); + acquire_data->content = widget_content; + acquire_data->w = w; + acquire_data->h = h; - acquire_data->data = widget_ref(data); - acquire_data->content = widget_content; - acquire_data->w = w; - acquire_data->h = h; + ret = widget_viewer_acquire_resource_id(data->handle, 0, acquire_widget_pixmap_cb, acquire_data); + if (ret != WIDGET_ERROR_NONE) { + widget_unref(data); + free(acquire_data); + } else { + data->is.field.widget_pixmap_acquire_requested = 1; + } - ret = widget_viewer_acquire_resource_id(data->handle, 0, acquire_widget_pixmap_cb, acquire_data); - if (ret != WIDGET_ERROR_NONE) { - widget_unref(data); - free(acquire_data); - } else { - data->is.field.widget_pixmap_acquire_requested = 1; + /** + * @note + * Resource lock should be acquired from acquire_widget_pixmap_cb + */ } } else { if (!data->widget_extra) { @@ -4825,7 +4908,13 @@ static void __widget_update_pixmap_object(struct widget_data *data, Evas_Object replace_pixmap(NULL, 0, widget_content, data->widget_extra[data->widget_latest_idx]); update_widget_pixmap(widget_content, w, h); + if (WIDGET_CONF_ENABLE_RESOURCE_LOCK) { + if (!eina_list_data_find(s_info.updated_pixmap_list, (void *)(PTR_TYPE(data->widget_extra[data->widget_latest_idx])))) { + s_info.updated_pixmap_list = eina_list_append(s_info.updated_pixmap_list, (void *)(PTR_TYPE(data->widget_extra[data->widget_latest_idx]))); + } + } } + } static int widget_system_created(struct widget *handle, struct widget_data *data) @@ -4921,11 +5010,21 @@ static void __widget_created_cb(struct widget *handle, int ret, void *cbdata) if (!data->is.field.faulted) { data->is.field.faulted = 1; + + DbgPrint("Display tap to load (%p) [%s]\n", data, data->widget_id); + smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED, &fault_event); + __widget_overlay_faulted(data); - } + } else { + smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED, &fault_event); - DbgPrint("Display tap to load (%p) [%s]\n", data, data->widget_id); - smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED, &fault_event); + /** + * @note + * While processing the faulted smart callback, the user can request hide_faulted_overlay + * So we should reset it from here. in other cases, the widget_overlay_faulted function deals with this. + */ + data->is.field.hide_faulted_overlay = 0; + } ret = WIDGET_ERROR_FAULT; } else { @@ -5318,6 +5417,12 @@ static void __widget_overlay_faulted(struct widget_data *data) Evas_Object *overlay; widget_type_e widget_type; + if (data->is.field.hide_faulted_overlay == 1) { + DbgPrint("Faulted overlay is hidden by request (%s)\n", data->widget_id); + data->is.field.hide_faulted_overlay = 0; + return; + } + if (data->is.field.widget_overlay_loaded) { __widget_overlay_disable(data, 1, 1); } @@ -6668,11 +6773,14 @@ static int widget_fault_handler(enum widget_fault_type fault, const char *pkgnam if (!strcmp(data->widget_id, pkgname)) { DbgPrint("Faulted: %s (%p)\n", pkgname, data); data->is.field.faulted = 1; - __widget_overlay_faulted(data); + info.error = WIDGET_ERROR_FAULT; info.widget_app_id = data->widget_id; info.event = WIDGET_FAULT_DEACTIVATED; + smart_callback_call(data, WIDGET_SMART_SIGNAL_WIDGET_FAULTED, &info); + + __widget_overlay_faulted(data); } } break; @@ -6686,11 +6794,14 @@ static int widget_fault_handler(enum widget_fault_type fault, const char *pkgnam if (!strcmp(data->widget_id, pkgname)) { DbgPrint("Disconnected: %s (%p)\n", pkgname, data); data->is.field.faulted = 1; - __widget_overlay_faulted(data); + info.error = WIDGET_ERROR_FAULT; info.widget_app_id = data->widget_id; info.event = WIDGET_FAULT_PROVIDER_DISCONNECTED; + smart_callback_call(data, WIDGET_SMART_SIGNAL_PROVIDER_DISCONNECTED, &info); + + __widget_overlay_faulted(data); } } break; @@ -6700,6 +6811,32 @@ static int widget_fault_handler(enum widget_fault_type fault, const char *pkgnam return 0; } +static void evas_render_post_cb(void *data, Evas *e, void *event_info) +{ + widget_resource_lock_t handle; + + EINA_LIST_FREE(s_info.updated_pixmap_lock_list, handle) { + widget_service_release_resource_lock(handle); + widget_service_destroy_resource_lock(handle, 0); + } +} + +static void evas_render_pre_cb(void *data, Evas *e, void *event_info) +{ + widget_resource_lock_t handle; + void *pixmap; + + EINA_LIST_FREE(s_info.updated_pixmap_list, pixmap) { + handle = widget_service_create_resource_lock((unsigned int)(PTR_TYPE(pixmap)), WIDGET_LOCK_READ); + if (handle) { + widget_service_acquire_resource_lock(handle); + s_info.updated_pixmap_lock_list = eina_list_append(s_info.updated_pixmap_lock_list, handle); + } else { + ErrPrint("Failed to create a resource lock\n"); + } + } +} + EAPI int widget_viewer_evas_init(Evas_Object *win) { int ret; @@ -6755,6 +6892,15 @@ EAPI int widget_viewer_evas_init(Evas_Object *win) s_info.conf.field.force_to_buffer = 0; s_info.win = win; + if (WIDGET_CONF_ENABLE_RESOURCE_LOCK) { + Evas *e; + e = evas_object_evas_get(win); + if (e) { + evas_event_callback_add(e, EVAS_CALLBACK_RENDER_PRE, evas_render_pre_cb, NULL); + evas_event_callback_add(e, EVAS_CALLBACK_RENDER_POST, evas_render_post_cb, NULL); + } + } + return ret; } @@ -6767,6 +6913,15 @@ EAPI int widget_viewer_evas_fini(void) } if (s_info.initialized) { + if (WIDGET_CONF_ENABLE_RESOURCE_LOCK && s_info.win) { + Evas *e; + e = evas_object_evas_get(s_info.win); + if (e) { + evas_event_callback_del(e, EVAS_CALLBACK_RENDER_PRE, evas_render_pre_cb); + evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, evas_render_post_cb); + } + } + widget_viewer_remove_event_handler(widget_event_handler); widget_viewer_remove_fault_handler(widget_fault_handler); widget_viewer_fini(); @@ -7034,6 +7189,10 @@ EAPI int widget_viewer_evas_set_option(widget_evas_conf_e type, int value) s_info.conf.field.skip_acquire = !!value; DbgPrint("Turn %s skip-acquire option\n", s_info.conf.field.skip_acquire ? "on" : "off"); break; + case WIDGET_VIEWER_EVAS_DISABLE_SCROLLER: + s_info.conf.field.disable_internal_scroller = !!value; + DbgPrint("Turn %s internal_scroller option\n", s_info.conf.field.disable_internal_scroller ? "off" : "on"); + break; default: ret = WIDGET_ERROR_INVALID_PARAMETER; break; @@ -8277,4 +8436,54 @@ EAPI int widget_viewer_evas_hide_overlay(Evas_Object *widget) return WIDGET_ERROR_NONE; } +/** + * @note + * This function must has to be called after the object is faulted. + * And this will not reset the faulted flag. it just dislable the faulted overlay if it is exists. + * + * The best usage of this function is called from smart-callback. + * Any faulted smart callback can call this. + * Then the widget_viewer_evas will check the flag to decide whether enable the faulted overlay or not. + */ +EAPI int widget_viewer_evas_hide_faulted_overlay_once(Evas_Object *widget) +{ + struct widget_data *data; + + if (!is_widget_feature_enabled()) { + return WIDGET_ERROR_NOT_SUPPORTED; + } + + if (!s_info.initialized) { + return WIDGET_ERROR_FAULT; + } + + data = get_smart_data(widget); + if (!data) { + ErrPrint("Invalid object\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + if (data->is.field.faulted == 0) { + ErrPrint("Object is not faulted\n"); + return WIDGET_ERROR_INVALID_PARAMETER; + } + + /** + * @note + * If the overlay (faulted) is already enabled, + * Turn it off first. + */ + if (data->is.field.widget_overlay_loaded) { + DbgPrint("Faulted overlay is disabled\n"); + __widget_overlay_disable(data, 1, 1); + } + + /** + * This flag will be checked before enable the faulted overlay. + * And this will be reset'd right after ignore the faulted overlay. + */ + data->is.field.hide_faulted_overlay = 1; + return WIDGET_ERROR_NONE; +} + /* End of a file */ diff --git a/widget_viewer_sdk/include/debug.h b/widget_viewer_sdk/include/debug.h index a6563ee..483309e 100644 --- a/widget_viewer_sdk/include/debug.h +++ b/widget_viewer_sdk/include/debug.h @@ -19,9 +19,9 @@ #define ErrPrint(format, arg...) SECURE_LOGE(format, ##arg) #else extern FILE *__file_log_fp; -#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) +#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [%s/%s:%d] " format, widget_util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) -#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) +#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [%s/%s:%d] " format, widget_util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) #endif diff --git a/widget_viewer_sdk/org.tizen.widget_viewer_sdk.efl b/widget_viewer_sdk/org.tizen.widget_viewer_sdk.efl index f5f5250..7179ee4 100644 --- a/widget_viewer_sdk/org.tizen.widget_viewer_sdk.efl +++ b/widget_viewer_sdk/org.tizen.widget_viewer_sdk.efl @@ -8,7 +8,6 @@ org.tizen.widget_viewer_sdk sound_server rw---- ------ org.tizen.widget_viewer_sdk syspopup::db rw---- ------ org.tizen.widget_viewer_sdk dbus rwx--- ------ org.tizen.widget_viewer_sdk pulseaudio rwxat- ------ -org.tizen.widget_viewer_sdk ail::db rw---- ------ org.tizen.widget_viewer_sdk connman r----- ------ org.tizen.widget_viewer_sdk system rwx--- ------ org.tizen.widget_viewer_sdk immvibed rw---- ------ @@ -16,15 +15,9 @@ org.tizen.widget_viewer_sdk svi-data r-x--- ------ org.tizen.widget_viewer_sdk org.tizen.clocksetting rwx--- ------ org.tizen.widget_viewer_sdk org.tizen.clocksetting::default-resources r-x--- ------ org.tizen.widget_viewer_sdk e17 r-x--- ------ -org.tizen.widget_viewer_sdk system::vconf rwx--- ------ -org.tizen.widget_viewer_sdk system::vconf_setting rw---- ------ -org.tizen.widget_viewer_sdk system::vconf_inhouse rw---- ------ -org.tizen.widget_viewer_sdk system::vconf_multimedia rw---- ------ org.tizen.widget_viewer_sdk deviced rwx--- ------ org.tizen.widget_viewer_sdk deviced::display rw---- ------ -org.tizen.widget_viewer_sdk testmode::vconf r----- ------ org.tizen.widget_viewer_sdk data-provider-master::db rw---- ------ -org.tizen.widget_viewer_sdk data-provider-master::share rwxat- ------ org.tizen.widget_viewer_sdk data-provider-master::data r-x--- ------ org.tizen.widget_viewer_sdk data-provider-master::client rw---- ------ org.tizen.widget_viewer_sdk data-provider-master rw---- ------ @@ -38,3 +31,4 @@ dbus org.tizen.widget_viewer_sdk rwx--- ------ system org.tizen.widget_viewer_sdk -w---- ------ org.tizen.data-provider-slave org.tizen.widget_viewer_sdk rwx--- ------ org.tizen.widget_viewer_sdk system::homedir rwx--- ------ +org.tizen.widget_viewer_sdk tizen::vconf::setting::admin r----l ------ diff --git a/widget_viewer_sdk/src/main.c b/widget_viewer_sdk/src/main.c index c1d6861..a4032c1 100644 --- a/widget_viewer_sdk/src/main.c +++ b/widget_viewer_sdk/src/main.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,9 @@ int errno; #define LAZY_WATCH_TIME 3.0f #define CR 13 #define LF 10 +#if !defined(VCONFKEY_WMS_CLOCKS_SET_IDLE) +#define VCONFKEY_WMS_CLOCKS_SET_IDLE "db/wms/clocks_set_idle" +#endif static struct info { int w; -- 2.7.4