--- /dev/null
+Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
--- /dev/null
+ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
+
+SUBDIRS = .
+
+initrd_recovery_libexecdir=$(prefix)/lib/initrd-recovery
+initrd_recovery_sharedir=$(prefix)/share/initrd-recovery
+initrd_recovery_install_dropindir=$(initrd_recovery_sharedir)/initrd.list.d
+
+DEFAULT_CFLAGS = \
+ $(LIBSYSTEM_CFLAGS) \
+ $(OUR_CFLAGS)
+
+DEFAULT_LDFLAGS = \
+ $(LIBSYSTEM_LDFLAGS) \
+ $(OUR_LDFLAGS)
+
+DEFAULT_LIBS = \
+ $(LIBSYSTEM_LIBS) \
+ libinitrd-recovery-shared.la
+
+AM_CPPFLAGS = \
+ -include $(top_builddir)/config.h \
+ -I $(top_srcdir)/src \
+ -I $(top_srcdir)/src/shared \
+ $(DEFAULT_CFLAGS)
+
+AM_CFLAGS = $(DEFAULT_CFLAGS)
+AM_LDFLAGS = $(DEFAULT_LDFLAGS)
+AM_LIBS = $(DEFAULT_LIBS)
+
+CLEANFILES =
+EXTRA_DIST =
+
+lib_LTLIBRARIES =
+noinst_LTLIBRARIES =
+
+bin_PROGRAMS =
+
+initrd_recovery_libexec_PROGRAMS =
+initrd_recovery_libexec_SCRIPTS =
+
+initrd_recovery_install_dropin_DATA =
+
+# ------------------------------------------------------------------------------
+noinst_LTLIBRARIES += \
+ libinitrd-recovery-shared.la
+
+libinitrd_recovery_shared_la_SOURCES = \
+ src/shared/log.c \
+ src/shared/log.h
+
+libinitrd_recovery_shared_la_CFLAGS = \
+ $(AM_CFLAGS)
+
+libinitrd_recovery_shared_la_LIBADD = \
+ $(LIBSYSTEM_LIBS)
+
+# ------------------------------------------------------------------------------
+initrd_recovery_libexec_SCRIPTS += \
+ src/initrd-recovery/init \
+ src/initrd-recovery/mkinitrd-recovery.sh
+
+initrd_recovery_install_dropin_DATA += \
+ src/initrd-recovery/00-initrd-recovery.list
+
+# ------------------------------------------------------------------------------
+minireboot_SOURCES = \
+ src/minireboot/minireboot.c
+
+minireboot_CFLAGS = \
+ $(AM_CFLAGS)
+
+minireboot_LDADD = \
+ $(AM_LIBS)
+
+initrd_recovery_libexec_PROGRAMS += \
+ minireboot
+
+# ------------------------------------------------------------------------------
+if RECOVERY_GUI
+noinst_LTLIBRARIES += \
+ librui.la
+
+librui_la_SOURCES = \
+ src/librui/graphics-fbdev-common.c \
+ src/librui/graphics-fbdev.c \
+ src/librui/graphics.c \
+ src/librui/input-events.c \
+ src/librui/resources.c \
+ src/librui/rui-description.c \
+ src/librui/rui-images.c \
+ src/librui/rui-menu.c \
+ src/librui/rui-progress-bar.c \
+ src/librui/rui-rulers.c \
+ src/librui/rui.c
+
+librui_la_CFLAGS = \
+ $(LIBPNG_CFLAGS) \
+ $(VCONF_INTERNAL_KEYS) \
+ $(AM_CFLAGS) \
+ -I src/librui \
+ -I src/fonts
+
+librui_la_LIBADD = \
+ $(LIBPNG_LIBS) \
+ $(AM_LIBS)
+endif
+
+# ------------------------------------------------------------------------------
+system_recovery_libexecdir = \
+ $(prefix)/lib/system-recovery
+
+if RECOVERY_GUI
+system_recovery_resdir = \
+ $(system_recovery_libexecdir)/res
+
+system_recovery_res_imagedir = \
+ $(system_recovery_resdir)/images
+
+system_recovery_SOURCES = \
+ src/system-recovery/process-util.c \
+ src/system-recovery/minvconf.c \
+ src/system-recovery/recovery-main.c \
+ src/system-recovery/recovery-rui.c
+
+system_recovery_CFLAGS = \
+ $(AM_CFLAGS) \
+ -I $(librui_la_CFLAGS) \
+ -I src/system-recovery
+
+system_recovery_LDADD = \
+ $(AM_LIBS) \
+ librui.la
+
+system_recovery_libexec_PROGRAMS = \
+ system-recovery
+
+system_recovery_res_image_DATA = \
+ src/system-recovery/res/images/font.png \
+ src/system-recovery/res/images/menu-title.png \
+ src/system-recovery/res/images/tizen-anim.png \
+ src/system-recovery/res/images/warning.png
+endif
+
+system_recovery_libexec_SCRIPTS = \
+ src/system-recovery/recovery-init
+
+initrd_recovery_install_dropin_DATA += \
+ src/system-recovery/50-system-recovery.list
+
+EXTRA_DIST += \
+ src/system-recovery/recovery-init.in \
+ src/system-recovery/50-system-recovery.list.m4
+
+CLEANFILES += \
+ src/system-recovery/recovery-init \
+ src/system-recovery/50-system-recovery.list
+
+# ------------------------------------------------------------------------------
+substitutions = \
+ '|PACKAGE_VERSION=$(PACKAGE_VERSION)|' \
+ '|PACKAGE_NAME=$(PACKAGE_NAME)|' \
+ '|PACKAGE_URL=$(PACKAGE_URL)|' \
+ '|includedir=$(includedir)|' \
+ '|VERSION=$(VERSION)|' \
+ '|MKDIR_P=$(MKDIR_P)|' \
+ '|RECOVERY_GUI=$(RECOVERY_GUI)|'
+
+SED_PROCESS = \
+ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
+ $(SED) $(subst '|,-e 's|@,$(subst =,\@|,$(subst |',|g',$(substitutions)))) \
+ < $< > $@
+
+src/%: src/%.in Makefile
+ $(SED_PROCESS)
+
+src/%: src/%.m4
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
+ $(AM_V_M4)$(M4) -P $(M4_DEFINES) < $< > $@
+
+install-exec-hook: $(INSTALL_EXEC_HOOKS)
--- /dev/null
+#!/bin/sh
+
+set -e
+
+if [ -f .git/hooks/pre-commit.sample ] && [ ! -f .git/hooks/pre-commit ]; then
+ # This part is allowed to fail
+ cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \
+ chmod +x .git/hooks/pre-commit && \
+ echo "Activated pre-commit hook." || :
+fi
+
+# README and INSTALL are required by automake, but may be deleted by
+# clean up rules. to get automake to work, simply touch these here,
+# they will be regenerated from their corresponding *.in files by
+# ./configure anyway.
+touch README INSTALL
+
+# Make sure m4 directory exist
+mkdir -p m4
+
+autoreconf --force --install --verbose || exit $?
--- /dev/null
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.69])
+AC_INIT([initrd-recovery], [2.1.1], [walyong.cho@samsung.com])
+
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_HEADERS([config.h])
+
+AC_USE_SYSTEM_EXTENSIONS
+AC_SYS_LARGEFILE
+AC_PREFIX_DEFAULT([/usr])
+AM_INIT_AUTOMAKE([foreign subdir-objects])
+
+LT_PREREQ(2.2)
+LT_INIT([disable-static])
+
+# Checks for programs.
+AC_PROG_AWK
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_MKDIR_P
+AC_PATH_PROG([M4], [m4])
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_CHECK_HEADERS([fcntl.h limits.h mntent.h stdint.h stdlib.h string.h sys/ioctl.h sys/mount.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_CHECK_HEADER_STDBOOL
+AC_C_INLINE
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_UINT32_T
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_FUNC_GETMNTENT
+AC_FUNC_MALLOC
+AC_FUNC_MMAP
+AC_CHECK_FUNCS([dup2 getmntent memset munmap strcasecmp strchr strdup strerror strrchr strstr])
+
+# ------------------------------------------------------------------------------
+our_cflags=" \
+ -g -O2 \
+ -Werror \
+ -fpie"
+
+our_ldflags=" \
+ -Wl,--as-needed \
+ -Wl,--no-undefined \
+ -Wl,--gc-sections \
+ -Wl,-z,relro \
+ -Wl,-z,now \
+ -pie"
+
+AC_SUBST([OUR_CFLAGS], "$our_cflags")
+AC_SUBST([OUR_LDFLAGS], "$our_ldflags")
+
+M4_DEFINES=
+
+# ------------------------------------------------------------------------------
+AC_ARG_ENABLE([recovery-gui],
+ AS_HELP_STRING([--disable-recovery-gui], [disable recovery gui mode]),
+ [case "${enableval}" in
+ yes) enable_recovery_gui=yes ;;
+ no) enable_recovery_gui=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --disable-recovery-gui) ;;
+ esac],
+ enable_recovery_gui=yes)
+if test "x$enable_recovery_gui" == "xyes"; then
+ M4_DEFINES="$M4_DEFINES -DRECOVERY_GUI"
+ AC_SUBST([OUR_CFLAGS], "$OUR_CFLAGS -DRECOVERY_GUI")
+ PKG_CHECK_MODULES(LIBSYSTEM, [libsystem])
+ PKG_CHECK_MODULES(LIBPNG, [libpng])
+ PKG_CHECK_MODULES(VCONF_INTERNAL_KEYS, [vconf-internal-keys])
+fi
+
+AC_SUBST([RECOVERY_GUI], ["GUI"])
+AM_CONDITIONAL([RECOVERY_GUI], [test "x$enable_recovery_gui" != "xno"])
+
+# ------------------------------------------------------------------------------
+AC_SUBST(M4_DEFINES)
+
+# ------------------------------------------------------------------------------
+AC_CONFIG_FILES([Makefile])
+
+AC_OUTPUT
+AC_MSG_RESULT([
+ $PACKAGE_NAME $VERSION
+
+ prefix: ${prefix}
+
+ recovery gui mode: ${enable_recovery_gui}
+
+ OUR CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
+])
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+Name: initrd-recovery
+Summary: Tools for system recovery
+Version: 0.1.0
+Release: 1
+Group: System/Utilities
+License: Apache-2.0
+ExclusiveArch: %{arm}
+
+Source0: %{name}-%{version}.tar.gz
+Source1001: initrd-recovery.manifest
+
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: libtool
+BuildRequires: pkgconfig(libsystem)
+
+Requires: system-recovery
+
+%description
+This is a special booting mode and executes system recovery mode on user
+selection like safe mode or phone initialization.
+
+%package -n system-recovery
+Summary: System recovery
+Group: System/Utilities
+License: Apache-2.0
+
+#!BuildIgnore: linux-glibc-devel
+#!BuildIgnore: kernel-headers
+BuildRequires: kernel-headers-tizen-dev
+BuildRequires: pkgconfig(libpng)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(vconf-internal-keys)
+BuildRequires: pkgconfig(libsystem)
+
+%description -n system-recovery
+A simple initrd menu for system recovery.
+
+%prep
+%setup -q
+
+%build
+cp %{SOURCE1001} .
+
+%define profile
+
+./autogen.sh
+%configure \
+%if ("%{?profile}" != "mobile")
+ --disable-recovery-gui \
+%endif
+
+make %{?_smp_mflags}
+
+%install
+mkdir -p %{buildroot}%{_datadir}/license
+cp -f LICENSE %{buildroot}%{_datadir}/license/initrd-recovery
+
+%make_install
+
+%posttrans
+%{_libdir}/initrd-recovery/mkinitrd-recovery.sh
+
+%files
+%defattr(-,root,root,-)
+%manifest initrd-recovery.manifest
+%{_datadir}/license/initrd-recovery
+%{_libdir}/initrd-recovery/init
+%{_libdir}/initrd-recovery/mkinitrd-recovery.sh
+%{_libdir}/initrd-recovery/minireboot
+%{_datadir}/initrd-recovery/initrd.list.d/00-initrd-recovery.list
+
+%files -n system-recovery
+%defattr(-,root,root,-)
+%manifest initrd-recovery.manifest
+%{_libdir}/system-recovery/recovery-init
+%{_datadir}/initrd-recovery/initrd.list.d/50-system-recovery.list
+%if ("%{?profile}" == "mobile")
+%{_libdir}/system-recovery/system-recovery
+%{_libdir}/system-recovery/res/images/*.png
+%endif
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+struct {
+ unsigned width;
+ unsigned height;
+ unsigned cwidth;
+ unsigned cheight;
+ unsigned char rundata[2973];
+} font = {
+ .width = 960,
+ .height = 18,
+ .cwidth = 10,
+ .cheight = 18,
+ .rundata = {
+ 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x55,0x82,0x06,0x82,0x02,0x82,0x10,0x82,
+ 0x11,0x83,0x08,0x82,0x0a,0x82,0x04,0x82,0x46,0x82,0x08,0x82,0x07,0x84,0x06,
+ 0x84,0x0a,0x81,0x03,0x88,0x04,0x84,0x04,0x88,0x04,0x84,0x06,0x84,0x1e,0x81,
+ 0x0e,0x81,0x0a,0x84,0x06,0x84,0x07,0x82,0x05,0x85,0x07,0x84,0x04,0x86,0x04,
+ 0x88,0x02,0x88,0x04,0x84,0x04,0x82,0x04,0x82,0x02,0x88,0x05,0x86,0x01,0x82,
+ 0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x04,0x84,0x04,
+ 0x86,0x06,0x84,0x04,0x86,0x06,0x84,0x04,0x88,0x02,0x82,0x04,0x82,0x02,0x82,
+ 0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,
+ 0x88,0x03,0x86,0x0e,0x86,0x06,0x82,0x11,0x82,0x10,0x82,0x18,0x82,0x0f,0x84,
+ 0x0d,0x82,0x1c,0x82,0x09,0x84,0x7f,0x16,0x84,0x05,0x82,0x05,0x84,0x07,0x83,
+ 0x02,0x82,0x19,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x01,0x82,0x03,0x86,0x04,
+ 0x83,0x02,0x82,0x03,0x82,0x01,0x82,0x07,0x82,0x09,0x82,0x06,0x82,0x3e,0x82,
+ 0x04,0x84,0x06,0x83,0x06,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x03,
+ 0x82,0x09,0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,
+ 0x1c,0x82,0x0e,0x82,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x05,0x84,0x04,
+ 0x82,0x02,0x82,0x05,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82,
+ 0x09,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x04,
+ 0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x03,0x82,0x02,0x82,
+ 0x03,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x02,
+ 0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
+ 0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x03,0x82,0x08,0x82,0x0c,
+ 0x82,0x05,0x84,0x11,0x82,0x0f,0x82,0x18,0x82,0x0e,0x82,0x02,0x82,0x0c,0x82,
+ 0x1c,0x82,0x0b,0x82,0x7f,0x15,0x82,0x08,0x82,0x08,0x82,0x05,0x82,0x01,0x82,
+ 0x01,0x82,0x19,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x01,0x82,0x02,0x82,0x01,
+ 0x82,0x01,0x82,0x02,0x82,0x01,0x82,0x01,0x82,0x03,0x82,0x01,0x82,0x07,0x82,
+ 0x08,0x82,0x08,0x82,0x3d,0x82,0x03,0x82,0x02,0x82,0x04,0x84,0x05,0x82,0x04,
+ 0x82,0x02,0x82,0x04,0x82,0x06,0x83,0x03,0x82,0x08,0x82,0x04,0x81,0x09,0x82,
+ 0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x1a,0x82,0x10,0x82,0x06,0x82,0x04,
+ 0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,
+ 0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02,
+ 0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x83,
+ 0x02,0x83,0x02,0x83,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,
+ 0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82,
+ 0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x04,
+ 0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x08,0x82,0x0c,0x82,0x04,0x82,0x02,0x82,
+ 0x11,0x82,0x0e,0x82,0x18,0x82,0x0e,0x82,0x02,0x82,0x0c,0x82,0x0b,0x82,0x0b,
+ 0x82,0x02,0x82,0x0b,0x82,0x4d,0x82,0x45,0x82,0x08,0x82,0x08,0x82,0x05,0x82,
+ 0x02,0x83,0x1a,0x82,0x07,0x81,0x02,0x81,0x07,0x82,0x01,0x82,0x02,0x82,0x01,
+ 0x82,0x05,0x82,0x01,0x84,0x04,0x82,0x01,0x82,0x07,0x82,0x08,0x82,0x08,0x82,
+ 0x06,0x82,0x02,0x82,0x06,0x82,0x28,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x01,
+ 0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x84,0x03,0x82,0x08,0x82,
+ 0x0d,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x19,0x82,0x12,0x82,0x05,
+ 0x82,0x04,0x82,0x02,0x82,0x02,0x84,0x03,0x82,0x02,0x82,0x03,0x82,0x03,0x82,
+ 0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x04,
+ 0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x83,0x02,0x83,
+ 0x02,0x84,0x02,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
+ 0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x0b,0x82,0x05,0x82,0x04,0x82,0x02,0x82,
+ 0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,
+ 0x82,0x04,0x82,0x09,0x82,0x0b,0x82,0x03,0x82,0x04,0x82,0x20,0x82,0x18,0x82,
+ 0x0e,0x82,0x10,0x82,0x0b,0x82,0x0b,0x82,0x02,0x82,0x0b,0x82,0x4d,0x82,0x45,
+ 0x82,0x08,0x82,0x08,0x82,0x26,0x82,0x10,0x88,0x01,0x82,0x01,0x82,0x06,0x83,
+ 0x01,0x82,0x04,0x84,0x08,0x81,0x08,0x82,0x0a,0x82,0x05,0x82,0x02,0x82,0x06,
+ 0x82,0x28,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x08,0x82,0x04,0x82,
+ 0x01,0x82,0x03,0x82,0x08,0x82,0x0d,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,
+ 0x82,0x18,0x82,0x06,0x88,0x06,0x82,0x04,0x82,0x04,0x82,0x02,0x82,0x01,0x85,
+ 0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x04,0x82,0x02,
+ 0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,
+ 0x02,0x82,0x04,0x82,0x08,0x88,0x02,0x84,0x02,0x82,0x02,0x82,0x04,0x82,0x02,
+ 0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x0b,0x82,
+ 0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x04,0x84,0x06,
+ 0x84,0x08,0x82,0x05,0x82,0x09,0x82,0x0b,0x82,0x2b,0x82,0x18,0x82,0x0e,0x82,
+ 0x10,0x82,0x1c,0x82,0x0b,0x82,0x4d,0x82,0x45,0x82,0x08,0x82,0x08,0x82,0x26,
+ 0x82,0x11,0x82,0x01,0x82,0x03,0x82,0x01,0x82,0x09,0x82,0x06,0x82,0x12,0x82,
+ 0x0a,0x82,0x06,0x84,0x07,0x82,0x27,0x82,0x04,0x82,0x04,0x82,0x05,0x82,0x0b,
+ 0x82,0x07,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x01,0x83,0x04,0x82,0x01,0x83,
+ 0x08,0x82,0x05,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x05,0x83,0x07,0x83,0x05,
+ 0x82,0x16,0x82,0x08,0x82,0x03,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,
+ 0x02,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,
+ 0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82,
+ 0x08,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,
+ 0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,
+ 0x0a,0x82,0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01,
+ 0x82,0x04,0x84,0x06,0x84,0x08,0x82,0x05,0x82,0x0a,0x82,0x0a,0x82,0x23,0x85,
+ 0x03,0x82,0x01,0x83,0x06,0x85,0x05,0x83,0x01,0x82,0x04,0x84,0x04,0x86,0x05,
+ 0x85,0x01,0x81,0x02,0x82,0x01,0x83,0x05,0x84,0x09,0x84,0x02,0x82,0x03,0x82,
+ 0x06,0x82,0x05,0x81,0x01,0x82,0x01,0x82,0x03,0x82,0x01,0x83,0x06,0x84,0x04,
+ 0x82,0x01,0x83,0x06,0x83,0x01,0x82,0x02,0x82,0x01,0x84,0x04,0x86,0x03,0x86,
+ 0x04,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
+ 0x82,0x02,0x82,0x04,0x82,0x03,0x87,0x05,0x82,0x08,0x82,0x08,0x82,0x26,0x82,
+ 0x11,0x82,0x01,0x82,0x04,0x86,0x07,0x82,0x05,0x83,0x12,0x82,0x0a,0x82,0x04,
+ 0x88,0x02,0x88,0x0c,0x88,0x10,0x82,0x04,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,
+ 0x06,0x83,0x04,0x82,0x03,0x82,0x03,0x83,0x02,0x82,0x03,0x83,0x02,0x82,0x07,
+ 0x82,0x06,0x84,0x05,0x82,0x02,0x83,0x05,0x83,0x07,0x83,0x04,0x82,0x18,0x82,
+ 0x06,0x82,0x04,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x86,0x04,
+ 0x82,0x08,0x82,0x04,0x82,0x02,0x86,0x04,0x86,0x04,0x82,0x02,0x84,0x02,0x88,
+ 0x05,0x82,0x0a,0x82,0x03,0x85,0x05,0x82,0x08,0x82,0x01,0x82,0x01,0x82,0x02,
+ 0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,
+ 0x04,0x82,0x02,0x82,0x03,0x82,0x05,0x84,0x07,0x82,0x05,0x82,0x04,0x82,0x03,
+ 0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01,0x82,0x05,0x82,0x08,0x82,0x08,0x82,
+ 0x06,0x82,0x0a,0x82,0x0a,0x82,0x22,0x82,0x03,0x82,0x02,0x83,0x02,0x82,0x04,
+ 0x82,0x03,0x82,0x03,0x82,0x02,0x83,0x03,0x82,0x02,0x82,0x05,0x82,0x06,0x82,
+ 0x03,0x83,0x02,0x83,0x02,0x82,0x06,0x82,0x0b,0x82,0x02,0x82,0x02,0x82,0x07,
+ 0x82,0x05,0x88,0x02,0x83,0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02,0x82,
+ 0x04,0x82,0x02,0x83,0x03,0x83,0x02,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x06,
+ 0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,
+ 0x03,0x82,0x04,0x82,0x08,0x82,0x02,0x84,0x09,0x82,0x09,0x84,0x23,0x82,0x11,
+ 0x82,0x01,0x82,0x06,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x01,0x82,0x11,0x82,
+ 0x0a,0x82,0x06,0x84,0x07,0x82,0x26,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x08,
+ 0x83,0x09,0x82,0x03,0x82,0x03,0x82,0x09,0x82,0x02,0x82,0x04,0x82,0x05,0x82,
+ 0x06,0x82,0x02,0x82,0x05,0x83,0x01,0x82,0x17,0x82,0x16,0x82,0x06,0x82,0x05,
+ 0x82,0x01,0x82,0x01,0x82,0x02,0x88,0x02,0x82,0x03,0x82,0x03,0x82,0x08,0x82,
+ 0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,
+ 0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x01,0x82,0x01,0x82,
+ 0x02,0x82,0x02,0x84,0x02,0x82,0x04,0x82,0x02,0x86,0x04,0x82,0x04,0x82,0x02,
+ 0x86,0x09,0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x82,
+ 0x01,0x82,0x04,0x84,0x07,0x82,0x07,0x82,0x07,0x82,0x0b,0x82,0x09,0x82,0x27,
+ 0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
+ 0x04,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,
+ 0x82,0x01,0x82,0x08,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,
+ 0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x07,
+ 0x82,0x0a,0x82,0x06,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x04,0x82,
+ 0x04,0x84,0x04,0x82,0x04,0x82,0x07,0x82,0x06,0x82,0x08,0x82,0x08,0x82,0x26,
+ 0x82,0x0f,0x88,0x05,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x02,0x82,0x01,0x82,
+ 0x0d,0x82,0x0a,0x82,0x05,0x82,0x02,0x82,0x06,0x82,0x26,0x82,0x05,0x82,0x04,
+ 0x82,0x05,0x82,0x07,0x82,0x0c,0x82,0x02,0x88,0x08,0x82,0x02,0x82,0x04,0x82,
+ 0x05,0x82,0x05,0x82,0x04,0x82,0x08,0x82,0x18,0x82,0x14,0x82,0x07,0x82,0x05,
+ 0x82,0x01,0x84,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,
+ 0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,
+ 0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x01,0x82,0x01,0x82,
+ 0x02,0x82,0x02,0x84,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,
+ 0x82,0x02,0x82,0x0a,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x82,
+ 0x01,0x82,0x01,0x82,0x04,0x84,0x07,0x82,0x07,0x82,0x07,0x82,0x0b,0x82,0x09,
+ 0x82,0x22,0x87,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x88,
+ 0x04,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,
+ 0x84,0x09,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,
+ 0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x08,0x86,0x05,
+ 0x82,0x06,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01,0x82,
+ 0x05,0x82,0x05,0x82,0x04,0x82,0x06,0x82,0x07,0x82,0x08,0x82,0x08,0x82,0x26,
+ 0x82,0x10,0x82,0x01,0x82,0x07,0x82,0x01,0x82,0x04,0x82,0x01,0x83,0x02,0x82,
+ 0x03,0x83,0x0f,0x82,0x08,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x25,0x82,0x07,
+ 0x82,0x02,0x82,0x06,0x82,0x06,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x09,0x82,
+ 0x02,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x04,0x82,0x08,0x82,0x19,0x82,0x05,
+ 0x88,0x05,0x82,0x08,0x82,0x05,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x02,0x82,
+ 0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,
+ 0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82,0x03,0x82,0x03,0x82,0x03,0x82,
+ 0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02,0x82,0x04,0x82,0x02,
+ 0x82,0x08,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x03,0x82,0x09,0x82,0x05,0x82,
+ 0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x83,0x02,0x83,0x03,0x82,0x02,0x82,0x06,
+ 0x82,0x06,0x82,0x08,0x82,0x0c,0x82,0x08,0x82,0x21,0x82,0x04,0x82,0x02,0x82,
+ 0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x0a,0x82,0x06,0x82,0x03,
+ 0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x85,0x08,0x82,0x05,0x82,
+ 0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
+ 0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x0d,0x82,0x04,0x82,0x06,0x82,0x04,0x82,
+ 0x04,0x84,0x04,0x82,0x01,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x05,
+ 0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x38,0x82,0x01,0x82,0x04,0x82,0x01,0x82,
+ 0x01,0x82,0x04,0x84,0x01,0x82,0x01,0x82,0x03,0x82,0x10,0x82,0x08,0x82,0x30,
+ 0x83,0x06,0x82,0x07,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x08,0x82,0x04,0x82,
+ 0x07,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x04,
+ 0x82,0x03,0x81,0x04,0x82,0x1a,0x82,0x10,0x82,0x10,0x82,0x08,0x82,0x04,0x82,
+ 0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,
+ 0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82,0x03,0x82,
+ 0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02,
+ 0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x02,0x84,0x02,0x82,0x03,0x82,0x03,0x82,
+ 0x04,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x05,0x83,0x02,0x83,0x03,
+ 0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x09,0x82,0x0c,0x82,0x08,0x82,0x21,0x82,
+ 0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x0a,
+ 0x82,0x07,0x85,0x04,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x82,0x02,0x82,
+ 0x07,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
+ 0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x0d,0x82,0x04,0x82,
+ 0x06,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x82,0x01,0x82,0x04,0x84,0x04,
+ 0x82,0x04,0x82,0x04,0x82,0x09,0x82,0x08,0x82,0x08,0x82,0x26,0x82,0x10,0x82,
+ 0x01,0x82,0x05,0x86,0x04,0x82,0x01,0x82,0x01,0x82,0x01,0x83,0x01,0x84,0x10,
+ 0x82,0x06,0x82,0x1d,0x83,0x11,0x83,0x05,0x82,0x09,0x84,0x07,0x82,0x05,0x82,
+ 0x09,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
+ 0x82,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x06,0x83,0x07,0x83,0x09,0x82,
+ 0x0e,0x82,0x0a,0x82,0x06,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x03,
+ 0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x09,0x82,
+ 0x02,0x83,0x02,0x82,0x04,0x82,0x05,0x82,0x06,0x82,0x01,0x82,0x04,0x82,0x04,
+ 0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,
+ 0x03,0x82,0x09,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x06,
+ 0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
+ 0x05,0x82,0x05,0x82,0x09,0x82,0x0d,0x82,0x07,0x82,0x21,0x82,0x04,0x82,0x02,
+ 0x83,0x02,0x82,0x04,0x82,0x03,0x82,0x03,0x82,0x02,0x83,0x03,0x82,0x03,0x82,
+ 0x04,0x82,0x06,0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x82,0x03,
+ 0x82,0x06,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x03,0x82,
+ 0x02,0x82,0x03,0x83,0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x07,0x82,0x04,
+ 0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x02,0x83,0x05,0x82,0x05,0x88,0x03,0x82,
+ 0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x0a,0x82,0x08,0x82,0x08,0x82,0x26,
+ 0x82,0x1c,0x82,0x06,0x82,0x02,0x83,0x03,0x84,0x02,0x82,0x10,0x82,0x04,0x82,
+ 0x1e,0x83,0x11,0x83,0x05,0x82,0x0a,0x82,0x05,0x88,0x02,0x88,0x04,0x84,0x09,
+ 0x82,0x05,0x84,0x06,0x84,0x05,0x82,0x09,0x84,0x06,0x84,0x07,0x83,0x07,0x83,
+ 0x0a,0x81,0x0e,0x81,0x0b,0x82,0x07,0x85,0x03,0x82,0x04,0x82,0x02,0x86,0x06,
+ 0x84,0x04,0x86,0x04,0x88,0x02,0x82,0x0a,0x84,0x01,0x81,0x02,0x82,0x04,0x82,
+ 0x02,0x88,0x04,0x83,0x05,0x82,0x04,0x82,0x02,0x88,0x02,0x82,0x04,0x82,0x02,
+ 0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x0a,0x85,0x03,0x82,0x04,0x82,0x04,0x84,
+ 0x07,0x82,0x07,0x84,0x07,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,
+ 0x82,0x05,0x88,0x03,0x86,0x09,0x82,0x03,0x86,0x22,0x85,0x01,0x81,0x02,0x82,
+ 0x01,0x83,0x06,0x85,0x05,0x83,0x01,0x82,0x04,0x85,0x05,0x82,0x07,0x86,0x03,
+ 0x82,0x04,0x82,0x02,0x88,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x88,0x02,0x82,
+ 0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x83,0x06,
+ 0x83,0x01,0x82,0x03,0x82,0x08,0x86,0x06,0x84,0x05,0x83,0x01,0x82,0x05,0x82,
+ 0x06,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x04,0x83,0x01,0x82,0x03,0x87,0x06,
+ 0x84,0x05,0x82,0x05,0x84,0x7f,0x15,0x83,0x7f,0x14,0x83,0x7f,0x5e,0x82,0x7f,
+ 0x05,0x89,0x47,0x82,0x04,0x82,0x17,0x82,0x03,0x82,0x34,0x82,0x0e,0x82,0x4e,
+ 0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0a,0x82,0x04,0x82,0x17,0x82,0x03,0x82,
+ 0x34,0x82,0x0e,0x82,0x48,0x82,0x04,0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0a,
+ 0x82,0x04,0x82,0x17,0x82,0x03,0x82,0x34,0x82,0x0e,0x82,0x49,0x82,0x02,0x82,
+ 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0c,0x86,0x19,0x85,0x35,0x82,0x0e,0x82,0x4a,
+ 0x84,0x3f,
+ 0x00,
+ }
+};
--- /dev/null
+# ---- Target contents ----------------------------------------------------- #
+VERBATIMS="
+/usr/lib/initrd-recovery/init
+"
+
+WITHLIBS="
+/usr/bin/bash
+/usr/bin/cat
+/usr/bin/cut
+/usr/bin/echo
+/usr/bin/gawk
+/usr/bin/grep
+/usr/bin/mkdir
+/usr/bin/mount
+/usr/bin/sleep
+/usr/bin/sync
+/usr/bin/tr
+/usr/bin/umount
+/usr/lib/initrd-recovery/minireboot
+/usr/sbin/partx
+"
+
+# LinkFileName:Target
+SYMLINKS="
+/bin/sh:bash
+/usr/bin/awk:/bin/gawk
+/sbin/init:/usr/lib/initrd-recovery/init
+/sbin/minireboot:/usr/lib/initrd-recovery/minireboot
+/sbin/reboot:/usr/lib/initrd-recovery/minireboot
+"
--- /dev/null
+#!/bin/bash
+
+FAKE_ROOT=/system
+FAKE_ROOT_RO=/system-ro
+
+STATUS_DIR=${FAKE_ROOT}/opt/data/recovery
+STATUS_FILE=${STATUS_DIR}/RW.STATUS
+DELTA_PATH_FILE=${STATUS_DIR}/DELTA.PATH
+
+CAT="/bin/cat"
+SYNC="/bin/sync"
+MKDIR="/bin/mkdir"
+MOUNT="/bin/mount"
+UMOUNT="/bin/umount"
+GREP="/bin/grep"
+REBOOT="/sbin/reboot"
+AWK="/usr/bin/awk"
+CUT="/usr/bin/cut"
+TR="/usr/bin/tr"
+PARTX="/usr/sbin/partx"
+
+#------------------------------------------------
+# get partition id
+#------------------------------------------------
+get_partition_id() {
+ EMMC_DEVICE="/dev/mmcblk0"
+ RET_PARTX=$("$PARTX" -s ${EMMC_DEVICE})
+ PART_ROOTFS=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "rootfs" {print $1}')
+ PART_SYSTEM_DATA=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "system-data" {print $1}')
+ PART_USER=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "user" {print $1}')
+ PART_CSC=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "csc" {print $1}')
+ PART_MODULES=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "module" {print $1}')
+}
+
+#------------------------------------------------
+# mount_blk_partitions
+#------------------------------------------------
+mount_blk_partitions() {
+ get_partition_id
+
+ echo "mount block device partitions"
+ "$MOUNT" -t ext4 ${PART_ROOTFS} ${FAKE_ROOT}
+ "$MOUNT" -t ext4 ${PART_SYSTEM_DATA} ${FAKE_ROOT}/opt
+ "$MOUNT" -t ext4 ${PART_USER} ${FAKE_ROOT}/opt/usr
+ "$MOUNT" -t ext4 ${PART_CSC} ${FAKE_ROOT}/opt/system/csc
+}
+
+#------------------------------------------------
+# mount_partitions
+#------------------------------------------------
+mount_partitions() {
+ "$MOUNT" -t proc none /proc
+ "$MOUNT" -t sysfs none /sys
+ "$MOUNT" -t smackfs smackfs /smack
+ "$MOUNT" -t tmpfs tmpfs /run -o rw,nosuid,nodev,mode=755
+ "$MOUNT" -t tmpfs tmpfs /tmp -o mode=1777,smackfsroot=*
+
+ "$MKDIR" /dev/pts
+ "$MOUNT" -t devpts devpts /dev/pts
+}
+
+#------------------------------------------------
+# do_reboot
+#------------------------------------------------
+do_reboot() {
+ echo "Reboot"
+ "$SYNC"
+ "$REBOOT"
+ while [ 1 ]
+ do
+ sleep 1
+ echo "."
+ done
+}
+
+#------------------------------------------------
+# Main Routine Start
+#------------------------------------------------
+echo "You entered into /sbin/init on initrd"
+
+mount_partitions
+
+"$CAT" /proc/cmdline
+
+cd /
+
+BOOT_MODE=$("$CAT" /proc/cmdline | "$TR" ' ' \\n | "$GREP" bootmode | "$CUT" -d= -f2)
+
+if [ "z$BOOT_MODE" == "z" ]; then
+ echo "BOOT_MODE was NOT defined!!"
+ echo "Do reboot!!"
+ do_reboot
+fi
+echo "BOOTMODE is ${BOOT_MODE}"
+exec /sbin/${BOOT_MODE}-init
--- /dev/null
+#!/bin/sh
+
+CP="/bin/cp"
+LN="/bin/ln"
+SED="/bin/sed"
+MKDIR="/bin/mkdir"
+AWK="/usr/bin/awk"
+PARTX="/usr/sbin/partx"
+DIRNAME="/usr/bin/dirname"
+MKDIR="/bin/mkdir"
+LD_LINUX="/lib/ld-linux.so.3"
+
+INITRD_ROOT="/mnt/initrd-recovery"
+
+OBJECTS_SPECIFY_DIR="/usr/share/initrd-recovery/initrd.list.d"
+OBJECTS_DIRECTORY=
+OBJECTS_VERBATIM=
+OBJECTS_WITHLIB=
+OBJECTS_LIBONLY=
+OBJECTS_SYMLINK=
+
+BASE_DIRECTORIES="
+/dev
+/etc
+/proc
+/sdcard
+/smack
+/sys
+/system
+/system-ro
+/run
+/tmp
+/usr/bin
+/usr/sbin
+/usr/lib
+/var/log
+"
+
+BASE_DIR_SYMLINKS="
+/bin:usr/bin
+/sbin:usr/sbin
+/lib:usr/lib
+/opt:system/opt
+"
+
+OPT="default"
+
+#-----------------------------------------------------------------------------
+# help
+#-----------------------------------------------------------------------------
+show_help() {
+ echo
+ echo "usage: `basename $0` [OPTION]"
+ echo "make initrd image"
+ echo
+ echo " -h, --help show help"
+ echo " -p, --post find initrd partition and format and make"
+ echo " initrd image to there"
+ echo
+}
+
+#-----------------------------------------------------------------------------
+# find initrd-recovery partition
+#-----------------------------------------------------------------------------
+find_initrd_recovery_partition() {
+ EMMC_DEVICE="/dev/mmcblk0"
+ RET_PARTX=$("$PARTX" -s ${EMMC_DEVICE})
+ PART_INITRD=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "ramdisk2" {print $1}')
+ if [ "z$PART_INITRD" == "z/dev/mmcblk0p" ]; then
+ PART_INITRD=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "ramdisk" {print $1}')
+ fi
+}
+
+#-----------------------------------------------------------------------------
+# Prepare parent directory
+#-----------------------------------------------------------------------------
+mkdir_p_parent() {
+ dst_dir=`"$DIRNAME" "$1"`
+ if [ ! -d "$dst_dir" -a ! -L "$dst_dir" ]; then
+ "$MKDIR" -p "$dst_dir"
+ fi
+}
+
+#-----------------------------------------------------------------------------
+# Copy content to root of mounted image
+#-----------------------------------------------------------------------------
+do_copy() {
+ src=$1
+ dst="$INITRD_ROOT/$src"
+
+ if [ ! -e "$src" -o -e "$dst" ]; then
+ return
+ fi
+
+ mkdir_p_parent $dst
+
+ "$CP" -f "$src" "$dst"
+}
+
+#-----------------------------------------------------------------------------
+# Get dependency libraries
+#-----------------------------------------------------------------------------
+get_dep_libs() {
+ "$LD_LINUX" --list $1 | "$SED" -r 's|^[^/]+([^ \(]+).*$|\1|'
+}
+
+#-----------------------------------------------------------------------------
+# Gather initrd objects
+#-----------------------------------------------------------------------------
+get_initrd_objects() {
+ for f in $(ls ${OBJECTS_SPECIFY_DIR}); do
+ DIRECTORIES=
+ DIR_SYMLINKS=
+ VERBATIMS=
+ WITHLIBS=
+ LIBONLYS=
+ SYMLINKS=
+ source "${OBJECTS_SPECIFY_DIR}"/$f
+ OBJECTS_DIRECTORY="$OBJECTS_DIRECTORY $DIRECTORIES"
+ OBJECTS_DIR_SYMLINK="$OBJECTS_DIR_SYMLINK $DIR_SYMLINKS"
+ OBJECTS_VERBATIM="$OBJECTS_VERBATIM $VERBATIMS"
+ OBJECTS_WITHLIB="$OBJECTS_WITHLIB $WITHLIBS"
+ OBJECTS_LIBONLY="$OBJECTS_LIBONLY $LIBONLYS"
+ OBJECTS_SYMLINK="$OBJECTS_SYMLINK $SYMLINKS"
+ done
+
+ OBJECTS_DIRECTORY=$(echo "$OBJECTS_DIRECTORY" | sort | uniq)
+ OBJECTS_DIR_SYMLINK=$(echo "$OBJECTS_DIR_SYMLINK" | sort | uniq)
+ OBJECTS_VERBATIM=$(echo "$OBJECTS_VERBATIM" | sort | uniq)
+ OBJECTS_WITHLIB=$(echo "$OBJECTS_WITHLIB" | sort | uniq)
+ OBJECTS_LIBONLY=$(echo "$OBJECTS_LIBONLY" | sort | uniq)
+ OBJECTS_SYMLINK=$(echo "$OBJECTS_SYMLINK" | sort | uniq)
+}
+
+#-----------------------------------------------------------------------------
+# Prepare directory objects
+#-----------------------------------------------------------------------------
+prepare_directory_objects() {
+ for dir in $@; do
+ "$MKDIR" -p "$INITRD_ROOT$dir"
+ done
+}
+
+#-----------------------------------------------------------------------------
+# Copy verbatim objects
+#-----------------------------------------------------------------------------
+verbatim_objects() {
+ for obj in $@; do
+ do_copy $obj
+ done
+}
+
+#-----------------------------------------------------------------------------
+# Copy withlib objects
+#-----------------------------------------------------------------------------
+withlib_objects() {
+ for content in $@; do
+ do_copy $content
+
+ DEP_LIBS=$(get_dep_libs $content)
+ for lib in $DEP_LIBS; do
+ do_copy $lib
+ done
+ done
+}
+
+#-----------------------------------------------------------------------------
+# Copy libonly objects
+#-----------------------------------------------------------------------------
+libonly_objects() {
+ for content in $@; do
+ DEP_LIBS=$(get_dep_libs $content)
+ for lib in $DEP_LIBS; do
+ do_copy $lib
+ done
+ done
+}
+
+#-----------------------------------------------------------------------------
+# Copy symlink objects
+#-----------------------------------------------------------------------------
+symlink_objects() {
+ for i in $@; do
+ if [ "z$i" == "z" ]; then
+ continue
+ fi
+
+ link=${i%:*}
+ target=${i#*:}
+ mkdir_p_parent "$INITRD_ROOT$link"
+ "$LN" -s "$target" "$INITRD_ROOT$link"
+ done
+}
+
+#-----------------------------------------------------------------------------
+# Copy content
+#-----------------------------------------------------------------------------
+make_initrd_recovery() {
+ echo "copy initrd objects to $INITRD_ROOT"
+ get_initrd_objects
+
+ prepare_directory_objects $BASE_DIRECTORIES
+ symlink_objects $BASE_DIR_SYMLINKS
+ prepare_directory_objects $OBJECTS_DIRECTORY
+ symlink_objects $OBJECTS_DIR_SYMLINK
+ verbatim_objects $OBJECTS_VERBATIM
+ withlib_objects $OBJECTS_WITHLIB
+ libonly_objects $OBJECTS_LIBONLY
+ symlink_objects $OBJECTS_SYMLINK
+}
+
+#-----------------------------------------------------------------------------
+# Check given parameter is mount point
+#-----------------------------------------------------------------------------
+check_mount_point() {
+ grep " $1 " /etc/mtab > /dev/null
+ if [ $? -ne 0 ]; then
+ echo "$1 is not mount point"
+ exit 0
+ fi
+}
+
+#-----------------------------------------------------------------------------
+# Main
+#-----------------------------------------------------------------------------
+ARGS=$(getopt -o hp -l "help,post" -n "$0" -- "$@");
+
+eval set -- "$ARGS";
+
+while true; do
+ case "$1" in
+ -h|--help)
+ show_help >&2
+ exit 0
+ ;;
+ -p|--post)
+ OPT="post"
+ shift
+ ;;
+ --)
+ shift;
+ break;
+ ;;
+ esac
+done
+
+if [ $# -gt 1 ]; then
+ echo "Error: too many argument was given."
+ show_help >&2
+ exit 1
+fi
+
+case $OPT in
+ post)
+ find_initrd_recovery_partition
+ if [ "z$PART_INITRD" == "z/dev/mmcblk0p" ]; then
+ echo "Error: failed to find initrd partition"
+ exit 1
+ else
+ echo "Info: initrd partition: $PART_INITRD"
+ fi
+ mke2fs $PART_INITRD
+ e2fsck $PART_INITRD
+ mount $PART_INITRD $INITRD_ROOT
+ make_initrd_recovery
+ umount $INITRD_ROOT
+ ;;
+ *)
+ check_mount_point $INITRD_ROOT
+ make_initrd_recovery
+ ;;
+esac
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UNUSED
+#define UNUSED __attribute__((unused))
+#endif /* UNUSED */
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#endif /* ARRAY_SIZE */
+
+#if __STDC_VERSION__ < 199901L
+#if __GNUC__ >= 2
+#define __func__ __FUNCTION__
+#else
+#define __func__ "<unknown>"
+#endif
+#endif
+
+#define ASSERT_ARRAYS_EQUAL_LENGTH(a1, a2) \
+ _Static_assert(ARRAY_SIZE(a1) == ARRAY_SIZE(a2), \
+ "Arrays " #a1 " and " #a2 " must have equal length.");
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2007 The Android Open Source Project
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+
+#include <linux/fb.h>
+
+#include "graphics.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ int fd,
+ displayed_buffer;
+ gr_surface gr_draw;
+ GRSurface gr_framebuffer[2];
+ struct fb_var_screeninfo vi;
+} fbdev_common;
+
+bool fbdev_init_common(gr_backend *backend);
+bool fbdev_exit_common(gr_backend *backend);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include "fbdev.h"
+#include "common.h"
+#include "graphics.h"
+
+bool fbdev_init_common(gr_backend *backend) {
+ fbdev_common *fb = (fbdev_common *)backend->data;
+
+ memset(fb->gr_framebuffer, 0, sizeof(fb->gr_framebuffer));
+
+ fb->fd = open("/dev/fb0", O_RDWR);
+ if (fb->fd < 0) {
+ perror("Cannot open fb0");
+ return false;
+ }
+
+ if (ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vi) < 0) {
+ perror("Failed to get fb0 info");
+ backend->exit(backend);
+ return false;
+ }
+
+ /* If you have a device that has other BPP patches welcome... */
+ if (fb->vi.bits_per_pixel != 32) {
+ printf("Non-32-bit framebuffers not supported yet. Sorry.\n");
+ backend->exit(backend);
+ return false;
+ }
+
+ fb->gr_framebuffer[0].width = fb->vi.xres;
+ fb->gr_framebuffer[0].height = fb->vi.yres;
+ fb->gr_framebuffer[0].pixel_bytes = fb->vi.bits_per_pixel / 8;
+ fb->gr_framebuffer[0].row_bytes = fb->gr_framebuffer[0].width * fb->gr_framebuffer[0].pixel_bytes;
+ memcpy(fb->gr_framebuffer + 1, fb->gr_framebuffer, sizeof(GRSurface));
+ fb->gr_draw = fb->gr_framebuffer + 1;
+ return true;
+}
+
+bool fbdev_exit_common(gr_backend *backend) {
+ fbdev_common *fb = (fbdev_common *)backend->data;
+
+ fb->gr_framebuffer[0].data = NULL;
+ fb->gr_framebuffer[1].data = NULL;
+ fb->gr_draw = NULL;
+
+ if (fb->fd != -1 && close(fb->fd) < 0) {
+ perror("Can't close framebuffer descriptor");
+ return false;
+ }
+
+ fb->fd = -1;
+ return true;
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 The Android Open Source Project
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <linux/fb.h>
+
+#include <sys/mman.h>
+#include <sys/cdefs.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include "fbdev.h"
+#include "common.h"
+#include "graphics.h"
+
+static gr_surface fbdev_init(gr_backend *);
+static gr_surface fbdev_flip(gr_backend *);
+static bool fbdev_exit(gr_backend *);
+
+fbdev_common fb_data = {
+ .fd = -1,
+ .displayed_buffer = 0,
+ .gr_draw = NULL
+};
+
+static gr_backend my_backend = {
+ .init = fbdev_init,
+ .flip = fbdev_flip,
+ .exit = fbdev_exit,
+ .data = (void *)&fb_data
+};
+
+gr_backend *open_fbdev(void) {
+ return &my_backend;
+}
+
+static void fbdev_blank(gr_backend *backend, bool blank) {
+ int ret;
+ fbdev_common *fb = (fbdev_common *)backend->data;
+
+ ret = ioctl(fb->fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN :
+ FB_BLANK_UNBLANK);
+ if (ret < 0)
+ perror("ioctl(): blank");
+}
+
+static void set_displayed_framebuffer(fbdev_common *fb, unsigned int n) {
+ if (n > 1)
+ return;
+
+ if ((signed int)fb->vi.yres_virtual <
+ fb->gr_framebuffer[0].height * 2)
+ fb->vi.yres_virtual = fb->gr_framebuffer[0].height * 2;
+
+ fb->vi.yoffset = n * fb->gr_framebuffer[0].height;
+ fb->vi.bits_per_pixel = fb->gr_framebuffer[0].pixel_bytes * 8;
+ if (ioctl(fb->fd, FBIOPUT_VSCREENINFO, &fb->vi) < 0)
+ perror("Active fb swap failed");
+
+ fb->displayed_buffer = n;
+}
+
+static gr_surface fbdev_init(gr_backend *backend) {
+ size_t bufsize;
+ fbdev_common *fb = (fbdev_common *)backend->data;
+
+ if (!fbdev_init_common(backend))
+ return NULL;
+
+ bufsize = fb->vi.xres * fb->vi.yres * fb->vi.bits_per_pixel / 8;
+
+ /* Double buffer allocated as single piece of memory */
+ fb->gr_framebuffer[0].data = mmap(0, bufsize * 2,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ fb->fd, 0);
+
+ if (fb->gr_framebuffer[0].data == MAP_FAILED) {
+ perror("Failed to mmap video memory");
+ fbdev_exit(backend);
+ return NULL;
+ }
+
+ fb->gr_framebuffer[1].data = fb->gr_framebuffer[0].data + bufsize;
+ gr_fill_alpha(&fb->gr_framebuffer[0]);
+ memcpy(fb->gr_framebuffer[1].data, fb->gr_framebuffer[0].data,
+ bufsize);
+ set_displayed_framebuffer(fb, 0);
+
+ printf("Framebuffer: %dx%d, %d BPP\n", fb->gr_draw->width,
+ fb->gr_draw->height, fb->vi.bits_per_pixel);
+
+ fbdev_blank(backend, true);
+ fbdev_blank(backend, false);
+ return fb->gr_draw;
+}
+
+static gr_surface fbdev_flip(gr_backend *backend) {
+ fbdev_common *fb = (fbdev_common *)backend->data;
+
+ /* Change gr_draw to point to the buffer currently displayed,
+ * then flip the driver so we're displaying the other buffer
+ * instead. */
+ fb->gr_draw = fb->gr_framebuffer + fb->displayed_buffer;
+ set_displayed_framebuffer(fb, 1 - fb->displayed_buffer);
+ return fb->gr_draw;
+}
+
+static bool fbdev_exit(gr_backend *backend) {
+ fbdev_common *fb = (fbdev_common *)backend->data;
+ size_t bufsize = fb->vi.xres * fb->vi.yres * fb->vi.bits_per_pixel / 8;
+
+ /* Unmap double buffer */
+ if (fb->gr_framebuffer[0].data &&
+ munmap(fb->gr_framebuffer[0].data, bufsize * 2) < 0) {
+ perror("Failed to unmmap video memory");
+ return false;
+ }
+
+ return fbdev_exit_common(backend);
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2007 The Android Open Source Project
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <time.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <linux/kd.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include "graphics.h"
+#include "rui-image.h"
+#include "font-10x18.h"
+
+typedef struct {
+ gr_surface texture;
+ int cwidth;
+ int cheight;
+} GRFont;
+
+static GRFont *gr_font = NULL;
+static gr_backend *g_backend = NULL;
+
+static color gr_current_color = WHITE;
+static gr_surface gr_draw = NULL;
+
+static bool outside(int x, int y) {
+ return x < 0 || x >= gr_draw->width || y < 0 || y >= gr_draw->height;
+}
+
+int gr_get_font_cwidth(void) {
+ return gr_font->cwidth;
+}
+
+int gr_get_font_cheight(void) {
+ return gr_font->cheight;
+}
+
+void gr_set_color(color c) {
+ gr_current_color = c;
+}
+
+void gr_draw_rectangle(int x, int y, int width, int height) {
+ int i, j;
+ unsigned char *px, *dst_p, *first_line;
+
+ if (outside(x, y) || outside(x + width - 1, y + height - 1))
+ return;
+
+ dst_p = gr_draw->data + y * gr_draw->row_bytes +
+ x * gr_draw->pixel_bytes;
+
+ for (i = 0, px = dst_p; i < width; i++) {
+ *px++ = gr_current_color.r;
+ *px++ = gr_current_color.g;
+ *px++ = gr_current_color.b;
+ px++; /* Alpha is not used on framebuffer */
+ }
+
+ first_line = dst_p;
+ dst_p += gr_draw->row_bytes;
+ for (j = 1; j < height; j++, dst_p += gr_draw->row_bytes)
+ memcpy(dst_p, first_line, width * gr_draw->pixel_bytes);
+}
+
+void gr_clear(void) {
+ gr_draw_rectangle(0, 0, gr_draw->width, gr_draw->height);
+}
+
+/* Set Alpha component of pixels to 255 to make overlay visible. */
+void gr_fill_alpha(gr_surface gr) {
+ int i, j;
+ unsigned char *px, *dst_p, *first_line;
+
+ dst_p = gr->data;
+ for (i = 0, px = dst_p; i < gr->width; i++) {
+ *px++ = 0;
+ *px++ = 0;
+ *px++ = 0;
+ *px++ = 255;
+ }
+
+ first_line = dst_p;
+ dst_p += gr->row_bytes;
+ for (j = 1; j < gr->height; j++, dst_p += gr->row_bytes)
+ memcpy(dst_p, first_line, gr->width * gr->pixel_bytes);
+}
+
+static void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy) {
+ int i;
+ unsigned char *src_p, *dst_p;
+
+ if (!source)
+ return;
+
+ if (gr_draw->pixel_bytes != source->pixel_bytes) {
+ printf("%s: source has wrong format: %d bytes per pixel\n",
+ __func__, source->pixel_bytes);
+ return;
+ }
+
+ if (outside(dx, dy) || outside(dx + w - 1, dy + h - 1))
+ return;
+
+ src_p = source->data + sy * source->row_bytes +
+ sx * source->pixel_bytes;
+ dst_p = gr_draw->data + dy * gr_draw->row_bytes +
+ dx * gr_draw->pixel_bytes;
+
+ for (i = 0; i < h; ++i) {
+ memcpy(dst_p, src_p, w * source->pixel_bytes);
+ src_p += source->row_bytes;
+ dst_p += gr_draw->row_bytes;
+ }
+}
+
+/* RGB + Alpha */
+static void gr_blend_rgba(gr_surface source, int w, int h, unsigned char *src_p,
+ unsigned char *dst_p) {
+ int i, j;
+
+ for (j = 0; j < h; j++) {
+ unsigned char *sx = src_p;
+ unsigned char *px = dst_p;
+
+ for (i = 0; i < w; i++) {
+ unsigned char r = *sx++, g = *sx++, b = *sx++,
+ a = *sx++;
+
+ if (a == 255) {
+ *px++ = r;
+ *px++ = g;
+ *px++ = b;
+ px++; /* Alpha is not used on framebuffer */
+ } else {
+ *px = (*px * (255 - a) + r * a) / 255;
+ ++px;
+ *px = (*px * (255 - a) + g * a) / 255;
+ ++px;
+ *px = (*px * (255 - a) + b * a) / 255;
+ px += 2;
+ }
+ }
+
+ src_p += source->row_bytes;
+ dst_p += gr_draw->row_bytes;
+ }
+}
+
+/* RGB: Using current color's Alpha as alpha */
+static void gr_blend_rgb(gr_surface source, int w, int h, unsigned char *src_p,
+ unsigned char *dst_p) {
+ int i, j;
+
+ for (j = 0; j < h; j++) {
+ unsigned char *sx = src_p;
+ unsigned char *px = dst_p;
+
+ for (i = 0; i < w; i++) {
+ unsigned char r = *sx++, g = *sx++, b = *sx++;
+
+ if (gr_current_color.a == 255) {
+ *px++ = r;
+ *px++ = g;
+ *px++ = b;
+ px++; /* Alpha is not used on framebuffer */
+ } else {
+ *px = (*px * (255 - gr_current_color.a) +
+ r * gr_current_color.a) / 255;
+ ++px;
+ *px = (*px * (255 - gr_current_color.a) +
+ g * gr_current_color.a) / 255;
+ ++px;
+ *px = (*px * (255 - gr_current_color.a) +
+ b * gr_current_color.a) / 255;
+ px += 2;
+ }
+ }
+
+ src_p += source->row_bytes;
+ dst_p += gr_draw->row_bytes;
+ }
+}
+
+/* Grayscale + Alpha */
+static void gr_blend_ga(gr_surface source, int w, int h, unsigned char *src_p,
+ unsigned char *dst_p) {
+ int i, j;
+
+ for (j = 0; j < h; j++) {
+ unsigned char *sx = src_p;
+ unsigned char *px = dst_p;
+
+ for (i = 0; i < w; i++) {
+ unsigned char gr = *sx++, a = *sx++;
+
+ if (a == 255) {
+ *px++ = gr;
+ *px++ = gr;
+ *px++ = gr;
+ px++; /* Alpha is not used on framebuffer */
+ } else {
+ *px = (*px * (255 - a) + gr * a) / 255;
+ ++px;
+ *px = (*px * (255 - a) + gr * a) / 255;
+ ++px;
+ *px = (*px * (255 - a) + gr * a) / 255;
+ px += 2;
+ }
+ }
+
+ src_p += source->row_bytes;
+ dst_p += gr_draw->row_bytes;
+ }
+}
+
+/* Grayscale.
+ * Using image as Alpha channel and current color for foreground. */
+static void gr_blend_g(gr_surface source, int w, int h, unsigned char *src_p,
+ unsigned char *dst_p) {
+ int i, j;
+
+ for (j = 0; j < h; j++) {
+ unsigned char *sx = src_p;
+ unsigned char *px = dst_p;
+
+ for (i = 0; i < w; i++) {
+ unsigned char a = *sx++;
+
+ if (gr_current_color.a < 255)
+ a = ((int)a * gr_current_color.a) / 255;
+
+ if (a == 255) {
+ *px++ = gr_current_color.r;
+ *px++ = gr_current_color.g;
+ *px++ = gr_current_color.b;
+ px++; /* Alpha is not used on framebuffer */
+ } else {
+ *px = (*px * (255 - a) +
+ gr_current_color.r * a) / 255;
+ ++px;
+ *px = (*px * (255 - a) +
+ gr_current_color.g * a) / 255;
+ ++px;
+ *px = (*px * (255 - a) +
+ gr_current_color.b * a) / 255;
+ px += 2;
+ }
+ }
+
+ src_p += source->row_bytes;
+ dst_p += gr_draw->row_bytes;
+ }
+}
+
+static void gr_blend(gr_surface source, int sx, int sy, int w, int h, int dx, int dy) {
+ unsigned char *src_p, *dst_p;
+
+ if (!source)
+ return;
+
+ if (outside(dx, dy) || outside(dx + w - 1, dy + h - 1))
+ return;
+
+ src_p = source->data + sy * source->row_bytes +
+ sx * source->pixel_bytes;
+ dst_p = gr_draw->data + dy * gr_draw->row_bytes +
+ dx * gr_draw->pixel_bytes;
+
+ if (source->pixel_bytes == 4)
+ gr_blend_rgba(source, w, h, src_p, dst_p);
+ else if (source->pixel_bytes == 3)
+ gr_blend_rgb(source, w, h, src_p, dst_p);
+ else if (source->pixel_bytes == 2)
+ gr_blend_ga(source, w, h, src_p, dst_p);
+ else if (source->pixel_bytes == 1)
+ gr_blend_g(source, w, h, src_p, dst_p);
+ else
+ printf("%s: source has wrong format: %d bytes per pixel\n",
+ __func__, source->pixel_bytes);
+}
+
+void gr_text(int x, int y, const char *s, gr_font_style style) {
+ GRFont *font = gr_font;
+ unsigned int off;
+ int start_x = x;
+
+ if (!font->texture || !s)
+ return;
+
+ if (gr_current_color.a == 0)
+ return;
+
+ if (style == GR_FONT_BOLD && font->texture->height == font->cheight)
+ style = GR_FONT_REGULAR; /* No bold font in image */
+
+ while ((off = *s++)) {
+ unsigned char *src_p, *dst_p;
+
+ if (off == '\n') {
+ x = start_x;
+ y += font->cheight;
+ continue;
+ }
+
+ if (outside(x, y) ||
+ outside(x + font->cwidth - 1, y + font->cheight - 1))
+ continue;
+
+ off -= 32;
+ if (off >= 96)
+ off = '_' - 32; /* Replacement for unknown symbols */
+
+ src_p = font->texture->data + off * font->cwidth +
+ (style == GR_FONT_BOLD ?
+ font->cheight * font->texture->row_bytes : 0);
+ dst_p = gr_draw->data + y * gr_draw->row_bytes +
+ x * gr_draw->pixel_bytes;
+ gr_blend_g(font->texture, font->cwidth, font->cheight, src_p,
+ dst_p);
+
+ x += font->cwidth;
+ }
+}
+
+static void gr_align_surface(gr_surface surface, int *posX, int *posY,
+ gr_align_horizontal xalign, gr_align_vertical yalign,
+ int offset_x, int offset_y) {
+ if (xalign == GR_ALIGN_LEFT)
+ *posX = 0;
+ else if (xalign == GR_ALIGN_CENTER)
+ *posX = (gr_fb_width() - gr_get_width(surface)) / 2;
+ else
+ *posX = gr_fb_width() - gr_get_width(surface);
+
+ if (yalign == GR_ALIGN_TOP)
+ *posY = 0;
+ else if (yalign == GR_ALIGN_MIDDLE)
+ *posY = (gr_fb_height() - gr_get_height(surface)) / 2;
+ else
+ *posY = gr_fb_height() - gr_get_height(surface);
+
+ *posX += offset_x;
+ *posY += offset_y;
+}
+
+void gr_blend_image_aligned(gr_surface source, gr_align_horizontal xalign,
+ gr_align_vertical yalign, int offset_x, int offset_y) {
+ int posX, posY;
+
+ gr_align_surface(source, &posX, &posY, xalign, yalign, offset_x,
+ offset_y);
+ gr_blend(source, 0, 0, gr_get_width(source), gr_get_height(source),
+ posX, posY);
+}
+
+void gr_blit_image_aligned(gr_surface source, gr_align_horizontal xalign,
+ gr_align_vertical yalign, int offset_x, int offset_y) {
+ int posX, posY;
+
+ gr_align_surface(source, &posX, &posY, xalign, yalign, offset_x,
+ offset_y);
+ gr_blit(source, 0, 0, gr_get_width(source), gr_get_height(source),
+ posX, posY);
+}
+
+unsigned int gr_get_width(gr_surface surface) {
+ if (!surface)
+ return 0;
+
+ return surface->width;
+}
+
+unsigned int gr_get_height(gr_surface surface) {
+ if (!surface)
+ return 0;
+
+ return surface->height;
+}
+
+static void gr_init_font(void) {
+ int res;
+
+ gr_font = calloc(sizeof(*gr_font), 1);
+ res = res_create_image_surface(RUI_IMAGES_DIR "/font.png",
+ &(gr_font->texture), GR_WITH_ALPHA);
+ if (res == 0) {
+ /* The font image should be a 96x2 array of character images.
+ * The columns are the printable ASCII characters 0x20 - 0x7f.
+ * The top row is regular text; the bottom row is bold. */
+ gr_font->cwidth = gr_font->texture->width / 96;
+ gr_font->cheight = gr_font->texture->height / 2;
+ } else {
+ unsigned char *bits, *in, data;
+
+ printf("Failed to read font: res=%d\n", res);
+
+ /* fall back to the compiled-in font. */
+ gr_font->texture = malloc(sizeof(*gr_font->texture));
+ gr_font->texture->width = font.width;
+ gr_font->texture->height = font.height;
+ gr_font->texture->row_bytes = font.width;
+ gr_font->texture->pixel_bytes = 1;
+
+ bits = malloc(font.width * font.height);
+ gr_font->texture->data = (void *)bits;
+
+ in = font.rundata;
+ while ((data = *in++)) {
+ memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f);
+ bits += (data & 0x7f);
+ }
+
+ gr_font->cwidth = font.cwidth;
+ gr_font->cheight = font.cheight;
+ }
+}
+
+void gr_flip(void) {
+ gr_draw = g_backend->flip(g_backend);
+}
+
+bool gr_init(void) {
+ gr_init_font();
+
+ g_backend = open_fbdev();
+ gr_draw = g_backend->init(g_backend);
+ if (gr_draw == NULL)
+ return false;
+
+ gr_flip();
+ gr_flip();
+
+ return true;
+}
+
+void gr_exit(void) {
+ g_backend->exit(g_backend);
+}
+
+int gr_fb_width(void) {
+ return gr_draw->width;
+}
+
+int gr_fb_height(void) {
+ return gr_draw->height;
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2007 The Android Open Source Project
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ int width;
+ int height;
+ int row_bytes;
+ int pixel_bytes;
+ unsigned char *data;
+} GRSurface;
+
+typedef GRSurface *gr_surface;
+
+typedef struct gr_backend {
+ /* Initializes the backend and returns a gr_surface to draw into. */
+ gr_surface (*init)(struct gr_backend *);
+
+ /* Causes the current drawing surface (returned by the most recent
+ * call to flip() or init()) to be displayed, and returns a new
+ * drawing surface. */
+ gr_surface (*flip)(struct gr_backend *);
+
+ /* Device cleanup when drawing is done. */
+ bool (*exit)(struct gr_backend *);
+
+ void *data; /* Private data for graphics backend */
+} gr_backend;
+
+typedef struct {
+ unsigned char r, g, b, a;
+} color;
+
+#define BLACK (color) { 0, 0, 0, 255 }
+#define RED (color) { 255, 0, 0, 255 }
+#define GREEN (color) { 0, 255, 0, 255 }
+#define YELLOW (color) { 255, 255, 0, 255 }
+#define BLUE (color) { 0, 0, 255, 255 }
+#define MAGENTA (color) { 255, 0, 255, 255 }
+#define CYAN (color) { 0, 255, 255, 255 }
+#define WHITE (color) { 255, 255, 255, 255 }
+
+gr_backend *open_fbdev(void);
+
+bool gr_init(void);
+void gr_exit(void);
+
+int gr_fb_width(void);
+int gr_fb_height(void);
+
+void gr_flip(void);
+
+void gr_fill_alpha(gr_surface gr);
+void gr_clear(); /* Clear entire surface to current color */
+void gr_set_color(color c); /* Set current color */
+void gr_draw_rectangle(int x, int y, int width, int height);
+
+typedef enum {
+ GR_FONT_REGULAR,
+ GR_FONT_BOLD
+} gr_font_style;
+
+void gr_text(int x, int y, const char *s, gr_font_style style);
+int gr_get_font_cwidth(void);
+int gr_get_font_cheight(void);
+
+typedef enum {
+ GR_ALIGN_LEFT,
+ GR_ALIGN_CENTER,
+ GR_ALIGN_RIGHT
+} gr_align_horizontal;
+
+typedef enum {
+ GR_ALIGN_TOP,
+ GR_ALIGN_MIDDLE,
+ GR_ALIGN_BOTTOM
+} gr_align_vertical;
+
+void gr_blit_image_aligned(gr_surface source, gr_align_horizontal xalign,
+ gr_align_vertical yalign, int offset_x,
+ int offset_y);
+void gr_blend_image_aligned(gr_surface source, gr_align_horizontal xalign,
+ gr_align_vertical yalign, int offset_x,
+ int offset_y);
+
+unsigned int gr_get_width(gr_surface surface);
+unsigned int gr_get_height(gr_surface surface);
+
+typedef enum {
+ GR_WITHOUT_ALPHA,
+ GR_WITH_ALPHA
+} gr_img_type;
+
+/* Load a single display surface from a PNG image. */
+int res_create_image_surface(const char *name, gr_surface *pSurface,
+ gr_img_type img_type);
+
+/* Load an array of display surfaces from a single PNG image. The PNG
+ * should have a "Frames" text chunk whose value is the number of
+ * frames this image represents. The pixel data itself is interlaced
+ * by row. */
+int res_create_anim_image_surfaces(const char *name, int *frames,
+ gr_surface **pSurface,
+ gr_img_type img_type);
+
+/* Load part of a grayscale PNG image that is the first match for the
+ * given locale. The image is expected to be a composite of multiple
+ * translations of the same text, with special added rows that encode
+ * the subimages' size and intended locale in the pixel data. */
+int res_create_localized_alpha_surface(const char *name, const char *locale,
+ gr_surface *pSurface);
+
+/* Free a surface allocated by any of the res_create_*_surface()
+ * functions. */
+void res_free_surface(gr_surface surface);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2007 The Android Open Source Project
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _POSIX_C_SOURCE 200809L
+
+#include <time.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <sys/poll.h>
+
+#include <linux/input.h>
+
+#include "input-events.h"
+
+#define MAX_DEVICES 16
+#define MAX_MISC_FDS 16
+
+#define BITS_PER_LONG (sizeof(unsigned long) * 8)
+#define BITS_TO_LONGS(x) (((x) + BITS_PER_LONG - 1) / BITS_PER_LONG)
+
+#define test_bit(bit, array) \
+ ((array)[(bit) / BITS_PER_LONG] & (1 << ((bit) % BITS_PER_LONG)))
+
+static struct pollfd ev_fds[MAX_DEVICES + MAX_MISC_FDS];
+
+static unsigned ev_count = 0;
+static unsigned ev_misc_count = 0;
+
+bool ev_init(void) {
+ DIR *dir;
+ struct dirent *de;
+ int fd;
+
+ dir = opendir("/dev/input");
+ if (!dir) {
+ printf("Can't open directory \"/dev/input\".\n");
+ return false;
+ }
+
+ while ((de = readdir(dir))) {
+ unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];
+
+/* fprintf(stderr,"/dev/input/%s\n", de->d_name);*/
+ if (strncmp(de->d_name, "event", 5))
+ continue;
+
+ fd = openat(dirfd(dir), de->d_name, O_RDONLY);
+ if (fd < 0)
+ continue;
+
+ /* read the evbits of the input device */
+ if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) < 0) {
+ close(fd);
+ continue;
+ }
+
+ /* TODO: add ability to specify event masks. For now, just
+ * assume that only EV_KEY and EV_REL event types are ever
+ * needed. */
+ if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits)) {
+ close(fd);
+ continue;
+ }
+
+ ev_fds[ev_count].fd = fd;
+ ev_fds[ev_count].events = POLLIN;
+ ev_count++;
+ if (ev_count == MAX_DEVICES)
+ break;
+ }
+
+ closedir(dir);
+ if (ev_count == 0) {
+ printf("No input devices found.\n");
+ return false;
+ }
+
+ return true;
+}
+
+void ev_exit(void) {
+ while (ev_count > 0)
+ close(ev_fds[--ev_count].fd);
+
+ ev_misc_count = 0;
+}
+
+static user_action last_action = ACTION_NONE;
+static time_t event_start = 0;
+
+static void ev_input_longpress_check(input_callback callback) {
+ if (event_start && time(NULL) - event_start >= LONGPRESS_TIME) {
+ callback(last_action, ACTION_TYPE_LONGPRESS);
+ event_start = time(NULL); /* Restarting the event */
+ }
+}
+
+static bool ev_input_process(struct input_event *ev, input_callback callback) {
+ user_action action = ACTION_NONE;
+
+ ev_input_longpress_check(callback);
+
+ if (!ev) { /* Timeout */
+ callback(ACTION_NONE, ACTION_TYPE_IDLE);
+ return true;
+ }
+
+ if (ev->type == EV_SYN)
+ return true;
+ else if (ev->type == EV_KEY && ev->code <= KEY_MAX) {
+ switch (ev->code) {
+ case KEY_DOWN:
+ case KEY_VOLUMEDOWN:
+ action = ACTION_DOWN;
+ break;
+ case KEY_UP:
+ case KEY_VOLUMEUP:
+ action = ACTION_UP;
+ break;
+ case KEY_ENTER:
+ case KEY_POWER:
+ action = ACTION_CONFIRM;
+ break;
+ case KEY_MENU:
+ action = ACTION_HOME;
+ break;
+ case KEY_PHONE:
+ action = ACTION_MENU;
+ break;
+ case KEY_BACK:
+ action = ACTION_BACK;
+ break;
+ default:
+/* printf("Unknown key %d.\n", ev->code);*/
+ break;
+ }
+
+ if (action != ACTION_NONE) {
+ if (ev->value == 1) {
+ last_action = action;
+ event_start = time(NULL);
+ } else if (action == last_action) {
+ last_action = ACTION_NONE;
+ event_start = 0;
+ }
+
+ if (callback)
+ callback(action, ev->value == 1 ?
+ ACTION_TYPE_BEGIN :
+ ACTION_TYPE_END);
+ }
+ } else if (ev->type == EV_REL) { /* Relative event */
+
+ } else if (ev->type == EV_ABS) { /* Absolute event */
+
+ }
+
+ return true;
+}
+
+static int ev_wait(int timeout) {
+ int ret;
+
+ if ((ret = poll(ev_fds, ev_count, timeout)) < 0)
+ perror("poll()");
+
+ return ret;
+}
+
+bool ev_dispatch(input_callback callback) {
+ int r;
+ unsigned n;
+
+ r = ev_wait(DISPATCH_TIMEOUT);
+ if (r < 0)
+ return false;
+ else if (r == 0) /* Timeout */
+ return ev_input_process(NULL, callback);
+
+ for (n = 0; n < ev_count; n++)
+ if (ev_fds[n].revents & POLLIN) {
+ int r;
+ struct input_event ev;
+
+ r = read(ev_fds[n].fd, &ev, sizeof(ev));
+ if (r != sizeof(ev))
+ continue;
+
+ if (!ev_input_process(&ev, callback))
+ return false;
+ }
+
+ return true;
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DISPATCH_TIMEOUT (1 * 1000) /* One second */
+#define LONGPRESS_TIME 3 /* Seconds */
+
+typedef enum {
+ ACTION_NONE,
+ ACTION_DOWN,
+ ACTION_UP,
+ ACTION_CONFIRM,
+ ACTION_HOME,
+ ACTION_MENU,
+ ACTION_BACK
+} user_action;
+
+typedef enum {
+ ACTION_TYPE_IDLE,
+ ACTION_TYPE_BEGIN,
+ ACTION_TYPE_END,
+ ACTION_TYPE_LONGPRESS
+} user_action_type;
+
+typedef void (*input_callback)(user_action action,
+ user_action_type action_type);
+
+bool ev_init(void);
+bool ev_dispatch(input_callback callback);
+void ev_exit(void);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2007 The Android Open Source Project
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <png.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <linux/fb.h>
+#include <linux/kd.h>
+
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include "graphics.h"
+
+extern char *locale;
+
+#define SURFACE_DATA_ALIGNMENT 8
+
+static gr_surface malloc_surface(size_t data_size) {
+ gr_surface surface;
+ unsigned char *temp;
+
+ temp = malloc(sizeof(GRSurface) + data_size + SURFACE_DATA_ALIGNMENT);
+ if (!temp)
+ return NULL;
+
+ surface = (gr_surface)temp;
+ surface->data = temp + sizeof(GRSurface) + (SURFACE_DATA_ALIGNMENT -
+ (sizeof(GRSurface) % SURFACE_DATA_ALIGNMENT));
+ return surface;
+}
+
+static int open_png(const char *name,
+ png_structp *png_ptr,
+ png_infop *info_ptr,
+ png_uint_32 *width,
+ png_uint_32 *height,
+ png_byte *channels) {
+
+ unsigned char header[8];
+ int result = 0, color_type, bit_depth;
+ size_t bytesRead;
+ FILE *fp;
+
+ fp = fopen(name, "rb");
+ if (fp == NULL) {
+ result = -1;
+ goto exit2;
+ }
+
+ bytesRead = fread(header, 1, sizeof(header), fp);
+ if (bytesRead != sizeof(header)) {
+ result = -2;
+ goto exit2;
+ }
+
+ if (png_sig_cmp(header, 0, sizeof(header))) {
+ result = -3;
+ goto exit2;
+ }
+
+ *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
+ NULL);
+ if (!*png_ptr) {
+ result = -4;
+ goto exit1;
+ }
+
+ *info_ptr = png_create_info_struct(*png_ptr);
+ if (!*info_ptr) {
+ png_destroy_read_struct(png_ptr, NULL, NULL);
+ result = -5;
+ goto exit2;
+ }
+
+ if (setjmp(png_jmpbuf(*png_ptr))) {
+ result = -6;
+ goto exit1;
+ }
+
+ png_init_io(*png_ptr, fp);
+ png_set_sig_bytes(*png_ptr, sizeof(header));
+ png_read_info(*png_ptr, *info_ptr);
+
+ png_get_IHDR(*png_ptr, *info_ptr, width, height, &bit_depth,
+ &color_type, NULL, NULL, NULL);
+
+ *channels = png_get_channels(*png_ptr, *info_ptr);
+
+ if (bit_depth == 8 && *channels == 3 &&
+ color_type == PNG_COLOR_TYPE_RGB) {
+ /* 8-bit RGB: great, nothing to do. */
+ } else if (bit_depth == 8 && *channels == 4 &&
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+ /* 8-bit RGB with alpha: great, nothing to do. */
+ } else if (bit_depth == 8 && *channels == 2 &&
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+ /* 8-bit gray with alpha: great, nothing to do. */
+ } else if (bit_depth == 8 && *channels == 1 &&
+ color_type == PNG_COLOR_TYPE_GRAY) {
+ /* 8-bit gray with: great, nothing to do. */
+ } else if (bit_depth < 8 && *channels == 2 &&
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+ /* 1-, 2- or 4-bit gray with alpha: expand to 8-bit gray. */
+ png_set_expand_gray_1_2_4_to_8(*png_ptr);
+ } else if (bit_depth < 8 && *channels == 1 &&
+ color_type == PNG_COLOR_TYPE_GRAY) {
+ /* 1-, 2- or 4-bit gray: expand to 8-bit gray. */
+ png_set_expand_gray_1_2_4_to_8(*png_ptr);
+ } else if (bit_depth <= 8 && *channels == 1 &&
+ color_type == PNG_COLOR_TYPE_PALETTE) {
+ int color_num;
+ png_colorp palette;
+
+ if (png_get_PLTE(*png_ptr, *info_ptr, &palette,
+ &color_num)) {
+ int i, rgb = 0;
+
+ for (i = 0; i < color_num; i++)
+ if (palette[i].red != palette[i].green ||
+ palette[i].red != palette[i].blue) {
+ rgb = 1;
+ break;
+ }
+
+ if (!rgb) {
+ png_set_rgb_to_gray_fixed(*png_ptr, 1, -1, -1);
+ *channels = 1;
+ } else
+ *channels = 3;
+
+ /* paletted images: expand to 8-bit RGB. */
+ png_set_palette_to_rgb(*png_ptr);
+
+ /* Expand paletted or RGB images with transparency to full
+ * alpha channels so the data will be available as RGBA
+ * quartets. */
+ if (*channels == 3 &&
+ png_get_valid(*png_ptr, *info_ptr, PNG_INFO_tRNS)) {
+ png_set_tRNS_to_alpha(*png_ptr);
+ *channels = 4;
+ }
+ }
+ } else {
+ fprintf(stderr,
+ "RUI doesn't support PNG depth %d channels %d "
+ "color_type %d of image \"%s\"\n",
+ bit_depth, *channels, color_type, name);
+ result = -7;
+ goto exit1;
+ }
+
+ return result;
+
+exit1:
+ if (result < 0)
+ png_destroy_read_struct(png_ptr, info_ptr, NULL);
+
+exit2:
+ if (fp != NULL)
+ fclose(fp);
+
+ return result;
+}
+
+/* "display" surfaces are transformed into the framebuffer's required
+ * pixel format (currently only RGBX is supported) at load time, so
+ * gr_blit() can be nothing more than a memcpy() for each row. The
+ * next two functions are the only ones that know anything about the
+ * framebuffer pixel format; they need to be modified if the
+ * framebuffer format changes (but nothing else should). */
+
+/* Allocate and return a gr_surface sufficient for storing an image of
+ * the indicated size in the framebuffer pixel format. */
+static gr_surface init_display_surface(png_uint_32 width, png_uint_32 height, int channels) {
+ gr_surface surface;
+
+ if (!(surface = malloc_surface(width * height * channels)))
+ return NULL;
+
+ surface->width = width;
+ surface->height = height;
+ surface->row_bytes = width * channels;
+ surface->pixel_bytes = channels;
+
+ return surface;
+}
+
+/* Copy 'input_row' to 'output_row', transforming it to the
+ * framebuffer pixel format. The input format depends on the value of
+ * 'channels':
+ *
+ * 1 - input is 8-bit grayscale
+ * 2 - input is 8-bit grayscale + 8-bit alpha
+ * 3 - input is 24-bit RGB
+ * 4 - input is 32-bit RGBA/RGBX
+ *
+ * 'width' is the number of pixels in the row. */
+static void transform_rgb_to_draw(unsigned char *input_row,
+ unsigned char *output_row,
+ int channels,
+ int width) {
+ int x;
+ unsigned char *ip = input_row, *op = output_row;
+
+ switch (channels) {
+ case 1: /* expand gray level to RGBX */
+ for (x = 0; x < width; x++) {
+ *op++ = *ip;
+ *op++ = *ip;
+ *op++ = *ip++;
+ *op++ = 0xff;
+ }
+
+ break;
+ case 2: /* expand gray level plus alpha to RGBX */
+ for (x = 0; x < width; ++x) {
+ *op++ = *ip;
+ *op++ = *ip;
+ *op++ = *ip++;
+ *op++ = *ip++;
+ }
+
+ break;
+ case 3: /* expand RGBA to RGBX */
+ for (x = 0; x < width; ++x) {
+ *op++ = *ip++;
+ *op++ = *ip++;
+ *op++ = *ip++;
+ *op++ = 0xff;
+ }
+
+ break;
+ case 4: /* copy RGBA to RGBX */
+ memcpy(output_row, input_row, width * 4);
+ break;
+ }
+}
+
+int res_create_anim_image_surfaces(const char *name, int *frames,
+ gr_surface **pSurface, gr_img_type img_type) {
+ int result = 0, i, num_text;
+ unsigned char *p_row = NULL;
+ unsigned int y;
+ gr_surface *surface = NULL;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_uint_32 width, height;
+ png_byte channels;
+ png_textp text;
+
+ *pSurface = NULL;
+ *frames = -1;
+
+ result = open_png(name, &png_ptr, &info_ptr, &width, &height,
+ &channels);
+ if (result < 0) {
+ printf("Can't load image \"%s\": %d.\n", name, result);
+ return result;
+ }
+
+ *frames = 1;
+
+ if (png_get_text(png_ptr, info_ptr, &text, &num_text))
+ for (i = 0; i < num_text; i++)
+ if (text[i].key && !strcmp(text[i].key, "Frames") &&
+ text[i].text) {
+ *frames = atoi(text[i].text);
+ break;
+ }
+
+ if (height % *frames) {
+ printf("Bad image height (%d) for frame count (%d)\n",
+ (int)height, *frames);
+ result = -9;
+ goto exit;
+ }
+
+ if (!(surface = malloc(*frames * sizeof(gr_surface)))) {
+ result = -8;
+ goto exit;
+ }
+
+ for (i = 0; i < *frames; i++)
+ if (!(surface[i] = init_display_surface(width,
+ height / *frames,
+ (img_type == GR_WITH_ALPHA ?
+ channels : 4)))) {
+ result = -8;
+ goto exit;
+ }
+
+ if (img_type == GR_WITHOUT_ALPHA)
+ p_row = malloc(width * channels);
+
+ for (y = 0; y < height; y++) {
+ int frame = y % *frames;
+ unsigned char *p_dst = surface[frame]->data + (y / *frames) *
+ surface[frame]->row_bytes;
+
+ if (img_type == GR_WITH_ALPHA)
+ png_read_row(png_ptr, p_dst, NULL);
+ else {
+ png_read_row(png_ptr, p_row, NULL);
+ transform_rgb_to_draw(p_row, p_dst, channels, width);
+ }
+ }
+
+ if (img_type == GR_WITHOUT_ALPHA)
+ free(p_row);
+
+ *pSurface = (gr_surface *)surface;
+
+exit:
+ if (png_get_io_ptr(png_ptr))
+ fclose((FILE *)png_get_io_ptr(png_ptr));
+
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+
+ if (result < 0 && surface) {
+ for (i = 0; i < *frames; i++)
+ if (surface[i])
+ free(surface[i]);
+
+ free(surface);
+ }
+
+ return result;
+}
+
+int res_create_image_surface(const char *name, gr_surface *pSurface,
+ gr_img_type img_type) {
+ gr_surface surface = NULL;
+ int result = 0;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_uint_32 width, height;
+ png_byte channels;
+ unsigned char *p_row = NULL;
+ unsigned int y;
+
+ *pSurface = NULL;
+
+ result = open_png(name, &png_ptr, &info_ptr, &width, &height,
+ &channels);
+ if (result < 0) {
+ printf("Can't load image \"%s\": %d.\n", name, result);
+ return result;
+ }
+
+ if (!(surface = init_display_surface(width, height,
+ (img_type == GR_WITH_ALPHA ?
+ channels : 4)))) {
+ result = -8;
+ goto exit;
+ }
+
+ if (img_type == GR_WITHOUT_ALPHA)
+ p_row = malloc(width * channels);
+
+ for (y = 0; y < height; y++) {
+ unsigned char *p_dst = surface->data + y * surface->row_bytes;
+
+ if (img_type == GR_WITH_ALPHA)
+ png_read_row(png_ptr, p_dst, NULL);
+ else {
+ png_read_row(png_ptr, p_row, NULL);
+ transform_rgb_to_draw(p_row, p_dst, channels, width);
+ }
+ }
+
+ if (img_type == GR_WITHOUT_ALPHA)
+ free(p_row);
+
+ *pSurface = surface;
+exit:
+ if (png_get_io_ptr(png_ptr))
+ fclose((FILE *)png_get_io_ptr(png_ptr));
+
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+
+ return result;
+}
+
+#if 0 /* Currently unneeded */
+static int matches_locale(const char *loc, const char *locale) {
+ int i;
+
+ if (locale == NULL)
+ return 0;
+
+ if (!strcmp(loc, locale))
+ return 1;
+
+ /* if loc does *not* have an underscore, and it matches the start
+ * of locale, and the next character in locale *is* an underscore,
+ * that's a match. For instance, loc == "en" matches locale ==
+ * "en_US". */
+
+ for (i = 0; loc[i] != 0 && loc[i] != '_'; ++i)
+ ;
+
+ if (loc[i] == '_')
+ return 0;
+
+ return (!strncmp(locale, loc, i) && locale[i] == '_');
+}
+
+int res_create_localized_alpha_surface(const char *name, const char *locale,
+ gr_surface *pSurface) {
+ gr_surface surface = NULL;
+ int result = 0;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_uint_32 width, height;
+ png_byte channels;
+ unsigned char *row;
+ png_uint_32 y;
+
+ *pSurface = NULL;
+
+ if (locale == NULL) {
+ surface = malloc_surface(0);
+ surface->width = 0;
+ surface->height = 0;
+ surface->row_bytes = 0;
+ surface->pixel_bytes = 1;
+ goto exit;
+ }
+
+ result = open_png(name, &png_ptr, &info_ptr, &width, &height,
+ &channels);
+ if (result < 0) {
+ printf("Can't load image \"%s\": %d.\n", name, result);
+ return result;
+ }
+
+ if (channels != 1) {
+ result = -7;
+ goto exit;
+ }
+
+ row = malloc(width);
+ for (y = 0; y < height; ++y) {
+ int w, h;
+ char *loc;
+
+ png_read_row(png_ptr, row, NULL);
+ w = (row[1] << 8) | row[0];
+ h = (row[3] << 8) | row[2];
+ loc = (char *)row + 5;
+
+ if (y + 1 + h >= height || matches_locale(loc, locale)) {
+ int i;
+
+ printf(" %20s: %s (%d x %d @ %d)\n", name, loc, w, h,
+ (int)y);
+
+ surface = malloc_surface(w * h);
+ if (surface == NULL) {
+ result = -8;
+ goto exit;
+ }
+
+ surface->width = w;
+ surface->height = h;
+ surface->row_bytes = w;
+ surface->pixel_bytes = 1;
+
+ for (i = 0; i < h; i++, y++) {
+ png_read_row(png_ptr, row, NULL);
+ memcpy(surface->data + i * w, row, w);
+ }
+
+ *pSurface = (gr_surface)surface;
+ break;
+ } else {
+ int i;
+
+ for (i = 0; i < h; i++, y++)
+ png_read_row(png_ptr, row, NULL);
+ }
+ }
+
+exit:
+ if (png_get_io_ptr(png_ptr))
+ fclose((FILE *)png_get_io_ptr(png_ptr));
+
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ if (result < 0 && surface != NULL)
+ free(surface);
+
+ return result;
+}
+#endif /* 0 Currently unneeded */
+
+void res_free_surface(gr_surface surface) {
+ free(surface);
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "graphics.h"
+#include "rui-description.h"
+
+void rui_description_draw(rui_description *d) {
+ if (!d)
+ return;
+
+ gr_set_color(d->style->c_title);
+ gr_text(d->pos_x, d->pos_y, d->title, GR_FONT_BOLD);
+ gr_set_color(d->style->c_text);
+ gr_text(d->pos_x, d->pos_y + gr_get_font_cheight(), d->text,
+ GR_FONT_BOLD);
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "graphics.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ color c_title;
+ color c_text;
+} rui_description_style;
+
+typedef struct {
+ int pos_x;
+ int pos_y;
+ rui_description_style *style;
+ const char *title;
+ const char *text;
+} rui_description;
+
+void rui_description_draw(rui_description *d);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "graphics.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* #define RUI_IMAGES_DIR "/usr/share/librui/res/images" */
+#define RUI_IMAGES_DIR "/usr/lib/system-recovery/res/images"
+
+typedef enum {
+ RUI_IMAGE_NONE = -1
+} rui_image_id;
+
+typedef enum {
+ RUI_ANIMATION_NONE = -1
+} rui_animation_id;
+
+typedef struct {
+ const char *fname;
+ color c_bg;
+ gr_align_horizontal align_hor;
+ gr_align_vertical align_ver;
+ int offset_x,
+ offset_y;
+ gr_img_type img_type;
+ gr_surface surface;
+} rui_image;
+
+typedef struct {
+ const char *fname;
+ color c_bg;
+ gr_align_horizontal align_hor;
+ gr_align_vertical align_ver;
+ int frames_num,
+ current_frame;
+ int offset_x,
+ offset_y;
+ gr_img_type img_type;
+ gr_surface *surfaces;
+} rui_animation;
+
+void rui_images_init(rui_image *images, int images_num,
+ rui_animation *animations, int animations_num);
+void rui_images_exit(void);
+void rui_images_draw(void);
+void rui_animations_draw(void);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <stdlib.h>
+#include <string.h>
+
+#include "rui.h"
+#include "common.h"
+#include "graphics.h"
+#include "rui-image.h"
+
+static rui_image *rui_images = NULL;
+static rui_animation *rui_animations = NULL;
+static int rui_images_num = 0, rui_animations_num = 0;
+
+void rui_images_draw(void) {
+ size_t i = 0;
+ rui_screen *cs;
+ rui_image_id img_id;
+
+ cs = get_current_screen();
+ if (!cs->images)
+ return;
+
+ while ((img_id = cs->images[i]) != RUI_IMAGE_NONE) {
+ rui_image *img = &rui_images[img_id];
+
+ if (!img->surface) {
+ i++;
+ continue;
+ }
+
+ if (img->img_type == GR_WITH_ALPHA) {
+ gr_set_color(img->c_bg);
+ gr_blend_image_aligned(img->surface, img->align_hor,
+ img->align_ver, img->offset_x,
+ img->offset_y);
+ } else
+ gr_blit_image_aligned(img->surface, img->align_hor,
+ img->align_ver, img->offset_x,
+ img->offset_y);
+
+ i++;
+ }
+}
+
+void rui_animations_draw(void) {
+ int i = 0;
+ rui_screen *cs;
+ rui_animation_id anim_id;
+
+ cs = get_current_screen();
+ if (!cs->animations)
+ return;
+
+ while ((anim_id = cs->animations[i]) != RUI_ANIMATION_NONE) {
+ rui_animation *anim = &rui_animations[anim_id];
+
+ if (!anim->surfaces) {
+ i++;
+ continue;
+ }
+
+ if (anim->img_type == GR_WITH_ALPHA) {
+ gr_set_color(anim->c_bg);
+ gr_blend_image_aligned(anim->surfaces[anim->current_frame],
+ anim->align_hor,
+ anim->align_ver,
+ anim->offset_x,
+ anim->offset_y);
+ } else
+ gr_blit_image_aligned(anim->surfaces[anim->current_frame],
+ anim->align_hor,
+ anim->align_ver,
+ anim->offset_x,
+ anim->offset_y);
+
+ i++;
+ if (++anim->current_frame >= anim->frames_num)
+ anim->current_frame = 0;
+ }
+}
+
+void rui_images_init(rui_image *images,
+ int images_num,
+ rui_animation *animations,
+ int animations_num) {
+ int i;
+
+ rui_images = images;
+ rui_images_num = images_num;
+ rui_animations = animations;
+ rui_animations_num = animations_num;
+
+ for (i = 0; i < rui_images_num; i++)
+ if (res_create_image_surface(rui_images[i].fname,
+ &rui_images[i].surface,
+ rui_images[i].img_type) < 0)
+ rui_images[i].surface = NULL;
+
+ for (i = 0; i < rui_animations_num; i++)
+ if (res_create_anim_image_surfaces(rui_animations[i].fname,
+ &rui_animations[i].frames_num,
+ &rui_animations[i].surfaces,
+ rui_animations[i].img_type) < 0)
+ rui_animations[i].surfaces = NULL;
+}
+
+void rui_images_exit(void) {
+ int i;
+
+ for (i = 0; i < rui_images_num; i++)
+ if (rui_images[i].surface) {
+ res_free_surface(rui_images[i].surface);
+ rui_images[i].surface = NULL;
+ }
+
+ rui_images = NULL;
+ rui_images_num = 0;
+
+ for (i = 0; i < rui_animations_num; i++)
+ if (rui_animations[i].surfaces) {
+ int j;
+
+ for (j = 0; j < rui_animations[i].frames_num; j++)
+ res_free_surface(rui_animations[i].surfaces[j]);
+
+ free(rui_animations[i].surfaces);
+ rui_animations[i].surfaces = NULL;
+ }
+
+ rui_animations = NULL;
+ rui_animations_num = 0;
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <stdlib.h>
+
+#include "rui.h"
+#include "graphics.h"
+#include "rui-menu.h"
+
+static void rui_menu_draw_item(int i, rui_menu *m) {
+ gr_set_color((i == m->item_selected) ? m->style->c_bg_selected :
+ m->style->c_bg_unselected);
+ gr_draw_rectangle(m->pos_x,
+ m->pos_y + i * (m->style->item_height +
+ m->style->item_spacing),
+ gr_fb_width() - m->pos_x, m->style->item_height);
+
+ gr_set_color((i == m->item_selected) ? m->style->c_text_selected :
+ m->style->c_text_unselected);
+ gr_text(m->style->text_pos_x,
+ m->pos_y +
+ i * (m->style->item_height + m->style->item_spacing) +
+ (m->style->item_height - gr_get_font_cheight()) / 2,
+ m->items[i],
+ (i == m->item_selected) ? GR_FONT_BOLD : GR_FONT_REGULAR);
+}
+
+void rui_menu_draw(rui_menu *menu) {
+ int i;
+
+ if (!menu)
+ return;
+
+ for (i = 0; i < menu->items_num; i++)
+ rui_menu_draw_item(i, menu);
+}
+
+int rui_menu_cursor_up(rui_menu *menu) {
+ if (!menu)
+ return 0; /* Don't need to repaint */
+
+ if (--menu->item_selected < 0)
+ menu->item_selected = menu->items_num - 1;
+
+ return 1; /* Need repaint */
+}
+
+int rui_menu_cursor_down(rui_menu *menu) {
+ if (!menu)
+ return 0; /* Don't need to repaint */
+
+ if (++menu->item_selected >= menu->items_num)
+ menu->item_selected = 0;
+
+ return 1; /* Need repaint */
+}
+
+int rui_menu_action_run(rui_menu *menu) {
+ int item_selected;
+
+ if (!menu || !menu->actions)
+ return 0; /* Don't need to repaint */
+
+ item_selected = menu->item_selected;
+ rui_screen_switch(menu->actions[item_selected].screen_switch_to);
+ if (menu->actions[item_selected].action_handler)
+ menu->actions[item_selected].action_handler();
+
+ return 1; /* Repaint unconditionally. Just in case. */
+}
+
+void rui_menu_init(rui_menu *menu) {
+ if (!menu)
+ return;
+
+ if (menu->item_default != RUI_MENU_ITEM_DO_NOT_CHANGE)
+ menu->item_selected = menu->item_default;
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "graphics.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ int item_height,
+ item_spacing,
+ text_pos_x;
+ color c_bg_selected,
+ c_bg_unselected,
+ c_text_selected,
+ c_text_unselected;
+} rui_menu_style;
+
+typedef enum {
+ RUI_MENU_ITEM_DO_NOT_CHANGE = -1
+} rui_menu_item_id;
+
+struct rui_menu_t;
+typedef void (*rui_menu_action_handler)(void);
+
+typedef struct {
+ int screen_switch_to;
+ rui_menu_action_handler action_handler;
+} rui_menu_action;
+
+typedef struct rui_menu_t {
+ rui_menu_style *style;
+ int pos_x,
+ pos_y,
+ items_num,
+ item_selected,
+ item_default;
+ const char **items;
+ rui_menu_action *actions;
+} rui_menu;
+
+void rui_menu_draw(rui_menu *menu);
+int rui_menu_cursor_up(rui_menu *menu);
+int rui_menu_cursor_down(rui_menu *menu);
+int rui_menu_action_run(rui_menu *menu);
+void rui_menu_init(rui_menu *menu);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "rui.h"
+#include "graphics.h"
+#include "rui-progress-bar.h"
+
+void rui_progress_bar_draw(rui_progress_bar *b) {
+ int width, progress_width;
+
+ if (!b)
+ return;
+
+ gr_set_color(b->style->c_border);
+ width = gr_fb_width() - 2 * b->pos_x;
+ /* Draw progress bar symmetrically to center. */
+ gr_draw_rectangle(b->pos_x, b->pos_y, width, b->height);
+ progress_width = b->progress *
+ (width - 2 * b->style->border_width) / 100;
+
+ if (b->progress != 0) { /* Draw bar. */
+ gr_set_color(b->style->c_bar);
+ gr_draw_rectangle(b->pos_x + b->style->border_width,
+ b->pos_y + b->style->border_width,
+ progress_width,
+ b->height - 2 * b->style->border_width);
+ }
+
+ if (b->progress != 100) { /* Draw background. */
+ gr_set_color(b->style->c_background);
+ gr_draw_rectangle(b->pos_x + b->style->border_width +
+ progress_width,
+ b->pos_y + b->style->border_width,
+ width - 2 * b->style->border_width -
+ progress_width,
+ b->height - 2 * b->style->border_width);
+ }
+}
+
+int rui_progress_bar_get_progress(rui_progress_bar *b) {
+ return b->progress;
+}
+
+/* Set progress value for progress bar on the current screen. */
+void rui_progress_bar_set_progress(rui_progress_bar *b, int progress) {
+ if (!b || progress < 0 || progress > 100)
+ return;
+
+ b->progress = progress;
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "graphics.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ color c_background,
+ c_border,
+ c_bar;
+ int border_width;
+} rui_progress_bar_style;
+
+typedef struct {
+ int pos_x,
+ pos_y,
+ height,
+ progress; /* 0 - 100 */
+ rui_progress_bar_style *style;
+} rui_progress_bar;
+
+void rui_progress_bar_draw(rui_progress_bar *b);
+int rui_progress_bar_get_progress(rui_progress_bar *b);
+void rui_progress_bar_set_progress(rui_progress_bar *b, int progress);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "graphics.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ color c_ruler;
+} rui_ruler_style;
+
+typedef struct {
+ int pos_x,
+ pos_y,
+ height;
+ rui_ruler_style *style;
+} rui_ruler;
+
+void rui_rulers_draw(rui_ruler *rulers);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "graphics.h"
+#include "rui-ruler.h"
+
+void rui_rulers_draw(rui_ruler *rulers) {
+ rui_ruler *r = rulers;
+
+ while (r) {
+ if (!r->style)
+ break;
+
+ gr_set_color(r->style->c_ruler);
+ /* Draw ruler symmetrically to center. */
+ gr_draw_rectangle(r->pos_x, r->pos_y,
+ gr_fb_width() - 2 * r->pos_x, r->height);
+ r++;
+ }
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "rui.h"
+#include "common.h"
+#include "rui-menu.h"
+#include "graphics.h"
+#include "rui-image.h"
+#include "rui-ruler.h"
+#include "input-events.h"
+#include "rui-description.h"
+
+static rui_screen *rui_screens = NULL;
+static int rui_screens_num = 0, rui_current_screen = 0;
+
+rui_screen * get_current_screen(void) {
+ return &rui_screens[rui_current_screen];
+}
+
+int get_current_screen_id(void) {
+ return rui_current_screen;
+}
+
+void rui_draw(void) {
+ rui_screen *cs;
+
+ cs = get_current_screen();
+ gr_set_color(cs->style->c_background);
+ gr_clear();
+ rui_images_draw();
+ rui_animations_draw();
+
+ if (cs->rulers)
+ rui_rulers_draw(cs->rulers);
+
+ if (cs->menu)
+ rui_menu_draw(cs->menu);
+
+ if (cs->description)
+ rui_description_draw(cs->description);
+
+ if (cs->progress_bar)
+ rui_progress_bar_draw(cs->progress_bar);
+
+ if (cs->draw)
+ cs->draw();
+
+ gr_flip();
+}
+
+/* Returns need_repaint */
+bool rui_screen_switch(int screen) {
+ if (screen == RUI_SCREEN_CURRENT || screen == get_current_screen_id())
+ return false; /* Don't need to repaint */
+
+ if (screen == RUI_SCREEN_BACK) {
+ rui_screen *cs;
+
+ cs = get_current_screen();
+ return rui_screen_switch(cs->screen_back);
+ }
+
+ rui_current_screen = screen;
+ if (rui_screens[screen].menu)
+ rui_menu_init(rui_screens[screen].menu);
+
+ if (rui_screens[screen].progress_bar)
+ rui_progress_bar_set_progress(
+ rui_screens[screen].progress_bar, 0);
+
+ if (rui_screens[screen].on_enter)
+ rui_screens[screen].on_enter();
+
+ return true; /* Need to repaint */
+}
+
+bool rui_init(rui_screen *screens, int screens_num, int current_screen,
+ rui_image *images, int images_num,
+ rui_animation *animations, int animations_num) {
+
+ if (!gr_init())
+ return false;
+
+ rui_screens = screens;
+ rui_screens_num = screens_num;
+ rui_current_screen = current_screen;
+ rui_images_init(images, images_num, animations, animations_num);
+ return true;
+}
+
+void rui_exit(void) {
+ rui_images_exit();
+ gr_exit();
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+
+#include "graphics.h"
+#include "rui-menu.h"
+#include "rui-image.h"
+#include "rui-ruler.h"
+#include "rui-description.h"
+#include "rui-progress-bar.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*rui_screen_on_enter)(void);
+typedef void (*rui_screen_draw)(void);
+
+typedef struct {
+ color c_background;
+} rui_screen_style;
+
+typedef enum {
+ RUI_SCREEN_BACK = -2,
+ RUI_SCREEN_CURRENT = -1
+} rui_screen_id;
+
+typedef struct {
+ rui_screen_style *style;
+ rui_menu *menu;
+ rui_description *description;
+ rui_ruler *rulers;
+ rui_progress_bar *progress_bar;
+ int *images;
+ rui_animation_id *animations;
+ int rulers_num;
+ rui_screen_on_enter on_enter;
+ rui_screen_draw draw;
+ int screen_back;
+} rui_screen;
+
+bool rui_init(rui_screen *screens, int screens_num, int current_screen,
+ rui_image *images, int images_num,
+ rui_animation *animations, int animations_num);
+void rui_exit(void);
+void rui_draw(void);
+bool rui_screen_switch(int screen); /* Returns need_repaint */
+rui_screen *get_current_screen(void);
+int get_current_screen_id(void);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <linux/reboot.h>
+
+#include <sys/reboot.h>
+#include <sys/syscall.h>
+
+typedef enum {
+ ACTION_REBOOT,
+ ACTION_HALT,
+ ACTION_POWEROFF
+} action;
+
+enum {
+ OPT_HELP = 0x100,
+ OPT_HALT,
+ OPT_REBOOT,
+ OPT_NO_WALL
+};
+
+static struct option long_options[] = {
+ { "force", no_argument, NULL, 'f' },
+ { "halt", no_argument, NULL, OPT_HALT },
+ { "help", no_argument, NULL, OPT_HELP },
+ { "no-sync", no_argument, NULL, 'n' },
+ { "no-wall", no_argument, NULL, OPT_NO_WALL },
+ { "no-wtmp", no_argument, NULL, 'd' },
+ { "poweroff", no_argument, NULL, 'p' },
+ { "reboot", no_argument, NULL, OPT_REBOOT },
+ { NULL, 0, 0, 0 }
+};
+
+static const char *exe = NULL;
+
+/* ------------------------------------------------------------------------ */
+
+void
+usage(void)
+{
+ printf("Usage: %s [OPTION...] [ARG]\n"
+ " -d --no-wtmp Ignored in this version\n"
+ " -f --force Ignored in this version\n"
+ " -n --no-sync Ignored in this version\n"
+ " -p --poweroff Switch off the device\n"
+ " --reboot Reboot the device\n"
+ " --halt Halt the device\n"
+ " --no-wall Ignored in this version\n"
+ " --help Display this help and exit\n", exe);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int
+reboot_or_poweroff(action mode, const char *cmd)
+{
+ sync();
+ if (mode == ACTION_REBOOT) {
+ if (cmd) {
+ printf("Rebooting with command \"%s\".", cmd);
+ syscall(__NR_reboot, LINUX_REBOOT_MAGIC1,
+ LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_RESTART2, cmd);
+ perror("syscall(SYS_reboot)");
+ }
+
+ printf("Rebooting.\n");
+ reboot(RB_AUTOBOOT);
+ } else if (mode == ACTION_HALT) {
+ printf("Halting.\n");
+ reboot(RB_HALT_SYSTEM);
+ } else {
+ printf("Powering off.\n");
+ reboot(RB_POWER_OFF);
+ }
+
+ perror("reboot()");
+ return 1;
+}
+
+/* ------------------------------------------------------------------------ */
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ char *cmd = NULL;
+ action mode = ACTION_REBOOT;
+
+ exe = strrchr(argv[0], '/') ? strrchr(argv[0], '/') + 1 : argv[0];
+ opterr = 0;
+ while ((c = getopt_long(argc, argv, "dfnp", long_options,
+ NULL)) >= 0) {
+ switch (c) {
+ case OPT_HALT:
+ mode = ACTION_HALT;
+ break;
+ case OPT_REBOOT:
+ mode = ACTION_REBOOT;
+ break;
+ case 'p':
+ mode = ACTION_POWEROFF;
+ break;
+ case 'd':
+ case 'f':
+ case 'n':
+ case OPT_NO_WALL:
+ break; /* Ignore option */
+ case OPT_HELP:
+ usage();
+ exit(0);
+ default:
+ usage();
+ exit(1);
+ }
+ }
+
+ if (mode == ACTION_REBOOT && argc == optind + 1)
+ cmd = argv[optind];
+ else if (optind < argc) {
+ printf("Too many arguments.\n");
+ usage();
+ exit(1);
+ }
+
+ return reboot_or_poweroff(mode, cmd);
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * libsystem
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#include <assert.h>
+#include <limits.h>
+#include <time.h>
+
+#include <libsystem/libsystem.h>
+
+#include "log.h"
+
+#define FILEBUF 1024
+
+static FILE *log_f[LOG_TYPE_MAX];
+static int stdout_bak = -1;
+static int stderr_bak = -1;
+
+static int log_level = LOG_DEBUG;
+
+static const char const *log_priority_name[] = {
+ [LOG_ALERT] = "alert",
+ [LOG_CRIT] = "crit",
+ [LOG_DEBUG] = "debug",
+ [LOG_EMERG] = "emerg",
+ [LOG_ERR] = "err",
+ [LOG_INFO] = "info",
+ [LOG_NOTICE] = "notice",
+ [LOG_WARNING] = "warning"
+};
+
+void set_log_level(int level) {
+ log_level = level;
+}
+
+int get_log_level(void) {
+ return log_level;
+}
+
+static int stdpath_dup_and_backup(FILE *f) {
+ int r, fd;
+
+ stdout_bak = dup(STDOUT_FILENO);
+ stderr_bak = dup(STDERR_FILENO);
+
+ fd = fileno(f);
+ r = dup2(fd, STDOUT_FILENO);
+ if (r < 0)
+ return -errno;
+
+ r = dup2(fd, STDERR_FILENO);
+ if (r < 0)
+ return -errno;
+
+ return 0;
+}
+
+static int stdpath_restore(void) {
+ int r;
+
+ if (stdout_bak >= 0) {
+ r = dup2(stdout_bak, STDOUT_FILENO);
+ if (r < 0)
+ return -errno;
+
+ close(stdout_bak);
+ stdout_bak = -1;
+ }
+
+ if (stderr_bak >= 0) {
+ r = dup2(stderr_bak, STDERR_FILENO);
+ if (r < 0)
+ return -errno;
+
+ close(stderr_bak);
+ stderr_bak = -1;
+ }
+
+ return 0;
+}
+
+int log_open(enum log_mask log_set, const char *path) {
+ int r;
+
+ if (log_set & LOG_MASK_FILE) {
+ assert(path);
+
+ log_f[LOG_TYPE_FILE] = fopen(path, "w+");
+ if (!log_f[LOG_TYPE_FILE])
+ return -errno;
+
+ /* If standard output/error were not set, redirect
+ * standard output/error to log file */
+ if (!(log_set & LOG_MASK_STANDARD)) {
+ r = stdpath_dup_and_backup(log_f[LOG_TYPE_FILE]);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ if (log_set & LOG_MASK_KMSG) {
+ log_f[LOG_TYPE_KMSG] = fopen("/dev/kmsg", "we");
+ if (!log_f[LOG_TYPE_KMSG])
+ return -errno;
+
+ /* If standard output/error or log file were not set,
+ * redirect standard output/error to kmsg */
+ if (!(log_set & LOG_MASK_STANDARD) &&
+ !(log_set & LOG_MASK_FILE)) {
+ r = stdpath_dup_and_backup(log_f[LOG_TYPE_KMSG]);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ return 0;
+}
+
+int log_close(void) {
+ enum log_type type;
+
+ for (type = 0; type < LOG_TYPE_MAX; type++) {
+ if (type == LOG_TYPE_STANDARD || !log_f[type])
+ continue;
+
+ fclose(log_f[type]);
+ log_f[type] = NULL;
+ }
+
+ return stdpath_restore();
+}
+
+static int _log_write(
+ int level,
+ const char *file,
+ int line,
+ const char *func,
+ const char *format,
+ va_list ap) {
+
+ char buff[LINE_MAX];
+ enum log_type type;
+
+ vsnprintf(buff, LINE_MAX, format, ap);
+
+ for (type = 0; type < LOG_TYPE_MAX; type++) {
+ if (type != LOG_TYPE_STANDARD && !log_f[type])
+ continue;
+
+ switch (type) {
+ case LOG_TYPE_STANDARD:
+ fprintf(level <= LOG_ERR ? stderr : stdout,
+ "%s\n", buff);
+ break;
+ case LOG_TYPE_FILE:
+ fprintf(log_f[LOG_TYPE_FILE],
+ "%-8s: %s\n", log_priority_name[level], buff);
+ fflush(log_f[LOG_TYPE_FILE]);
+ break;
+ case LOG_TYPE_KMSG:
+ fprintf(log_f[LOG_TYPE_KMSG],
+ "initrd: %s\n", buff);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int log_write(
+ int level,
+ const char*file,
+ int line,
+ const char *func,
+ const char *format, ...) {
+
+ va_list ap;
+ int r;
+
+ va_start(ap, format);
+ r = _log_write(level, file, line, func, format, ap);
+ va_end(ap);
+
+ return r;
+}
+
+int log_move(const char *to) {
+ _cleanup_free_ char *buf = NULL;
+ FILE *w = NULL;
+ size_t len;
+ int r;
+
+ assert(to);
+
+ if (!log_f[LOG_TYPE_FILE])
+ return 0;
+
+ buf = new(char, FILEBUF);
+ if (!buf) {
+ r = -ENOMEM;
+ goto error;
+ }
+
+ w = fopen(to, "a+");
+ if (!w) {
+ r = -errno;
+ goto error;
+ }
+
+ r = fseek(log_f[LOG_TYPE_FILE], 0, SEEK_SET);
+ if (r < 0) {
+ r = -errno;
+ goto error;
+ }
+
+ r = fflush(log_f[LOG_TYPE_FILE]);
+ if (r < 0) {
+ r = -errno;
+ goto error;
+ }
+
+ while((len = fread(buf, sizeof(char), FILEBUF, log_f[LOG_TYPE_FILE])) > 0) {
+ if (fwrite(buf, sizeof(char), len, w) != len) {
+ r = -errno;
+ goto error;
+ }
+ }
+
+ fclose(log_f[LOG_TYPE_FILE]);
+ log_f[LOG_TYPE_FILE] = w;
+
+ r = stdpath_dup_and_backup(log_f[LOG_TYPE_FILE]);
+ if (r < 0)
+ goto error;
+
+ return 0;
+
+error:
+ if (w)
+ fclose(w);
+
+ log_dbg("Failed to move log: %s\n", strerror(-r));
+
+ return r;
+}
+
+enum log_mask parse_log_type(const char *type) {
+ char *word, *state;
+ enum log_mask mask = 0;
+ size_t l;
+
+ if (!type)
+ return LOG_MASK_INVALID;
+
+ FOREACH_WORD_SEPARATOR(word, l, type, "+", state) {
+
+ if (strncaseeq(word, "standard", l))
+ mask |= LOG_MASK_STANDARD;
+ else if (strncaseeq(word, "file", l))
+ mask |= LOG_MASK_FILE;
+ else if (strncaseeq(word, "kmsg", l))
+ mask |= LOG_MASK_KMSG;
+ else
+ return LOG_MASK_INVALID;
+ }
+
+ return mask;
+}
+
+int config_parse_log_type(
+ const char *filename,
+ unsigned line,
+ const char *section,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data) {
+
+ enum log_mask *mask = data;
+
+ if (isempty(rvalue))
+ return 0;
+
+ *mask = parse_log_type(rvalue);
+
+ return *mask == LOG_MASK_INVALID ? -EINVAL : 0;
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * libsystem
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <sys/syslog.h>
+#include <stdbool.h>
+
+enum log_type {
+ LOG_TYPE_INVALID = -1,
+ LOG_TYPE_STANDARD = 0,
+ LOG_TYPE_FILE,
+ LOG_TYPE_KMSG,
+ LOG_TYPE_MAX
+};
+
+enum log_mask {
+ LOG_MASK_INVALID = -1,
+ LOG_MASK_STANDARD = 1 << LOG_TYPE_STANDARD,
+ LOG_MASK_FILE = 1 << LOG_TYPE_FILE,
+ LOG_MASK_KMSG = 1 << LOG_TYPE_KMSG,
+};
+
+#define log_full(level, ...) \
+ do { \
+ log_write((level), __FILE__, __LINE__, __func__, __VA_ARGS__); \
+ } while (0)
+
+void set_log_level(int level);
+int get_log_level(void);
+int log_open(enum log_mask log_set, const char *path);
+int log_close(void);
+int log_write(int level, const char*file, int line, const char *func, const char *format, ...);
+int log_move(const char *to);
+enum log_mask parse_log_type(const char *type);
+int config_parse_log_type(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data);
+
+#define log_dbg(format, ...) \
+ do { \
+ if (get_log_level() >= LOG_DEBUG) \
+ log_full(LOG_DEBUG, format, ##__VA_ARGS__); \
+ } while(0)
+
+#define log_err(format, ...) \
+ do { \
+ if (get_log_level() >= LOG_ERR) \
+ log_full(LOG_ERR, format, ##__VA_ARGS__); \
+ } while(0)
+
+#define log_info(format, ...) \
+ do { \
+ if (get_log_level() >= LOG_INFO) \
+ log_full(LOG_INFO, format, ##__VA_ARGS__); \
+ } while(0)
--- /dev/null
+/50-system-recovery.list
+/recovery-init
\ No newline at end of file
--- /dev/null
+# ---- Target contents ----------------------------------------------------- #
+DIRECTORIES="
+/dev
+/etc
+/proc
+/smack
+/sys
+/system
+/tmp
+/usr/bin
+/usr/lib
+/usr/sbin
+"
+
+DIR_SYMLINKS="
+/bin:usr/bin
+/lib:usr/lib
+/sbin:usr/sbin
+"
+
+VERBATIMS="
+/usr/lib/system-recovery/recovery-init
+m4_ifdef(`RECOVERY_GUI',
+`/usr/lib/system-recovery/res/images/font.png
+/usr/lib/system-recovery/res/images/menu-title.png
+/usr/lib/system-recovery/res/images/tizen-anim.png
+/usr/lib/system-recovery/res/images/warning.png')
+"
+
+WITHLIBS="
+/usr/bin/awk
+/usr/bin/bash
+/usr/bin/grep
+/usr/bin/mount
+/usr/bin/sync
+/usr/bin/touch
+/usr/bin/umount
+/usr/lib/initrd-recovery/minireboot
+/usr/sbin/partx
+m4_ifdef(`RECOVERY_GUI', `/usr/lib/system-recovery/system-recovery')
+m4_ifdef(`WITH_DM_VERITY', `/usr/bin/verityctl')
+"
+
+# LinkFileName:Target
+SYMLINKS="
+/usr/bin/system-recovery:/usr/lib/system-recovery/system-recovery
+/sbin/recovery-init:/usr/lib/system-recovery/recovery-init
+"
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _POSIX_SOURCE
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <linux/limits.h>
+
+#include <vconf/vconf.h>
+
+#include "minvconf.h"
+#include "system-recovery.h"
+
+#define COMBINE_FOLDER
+
+#ifdef COMBINE_FOLDER
+
+static bool convert_key_name(char *path) {
+ if (!(path = strchr(path, '/'))) {
+ printf("Wrong key path: \"%s\"!", path);
+ return false;
+ }
+
+ while ((path = strchr(path + 1, '/')))
+ *path = '+';
+
+ return true;
+}
+
+#endif /* COMBINE_FOLDER */
+
+/* The path of the key file is returned with ROOT_MOUNT_DIR prefix. */
+static bool get_key_path(const char *keyname, char *path, size_t bufsize) {
+ const char *key = keyname;
+ int key_offset;
+
+ if (!keyname || !path)
+ return false;
+
+ /* Not supported "memory/..." keys because they are not stored
+ * on the disk and can't be accessed in recovery mode. */
+ if (strstr(key, VCONF_BACKEND_DB_PREFIX) == key ||
+ strstr(key, VCONF_BACKEND_FILE_PREFIX) == key)
+ snprintf(path, bufsize, ROOT_MOUNT_DIR "%s%n%s",
+ VCONF_BACKEND_SYSTEM_DIR, &key_offset, key);
+ else {
+ printf("Wrong prefix of vconf key \"%s\"", key);
+ return false;
+ }
+
+#ifdef COMBINE_FOLDER
+ if (!convert_key_name(path + key_offset))
+ return false;
+#endif /* COMBINE_FOLDER */
+
+ return true;
+}
+
+/* Acquire shared (read) lock for entire file. */
+static bool file_lock_read(FILE *f) {
+ struct flock lock = {
+ .l_type = F_RDLCK,
+ .l_start = 0,
+ .l_whence = SEEK_SET,
+ .l_len = 0 /* Whole file */
+ };
+
+ if (fcntl(fileno(f), F_SETLK, &lock) < 0) {
+ perror("Can't acquire read-lock for a file");
+ return false;
+ }
+
+ return true;
+}
+
+static bool file_unlock(FILE *f) {
+ struct flock lock = {
+ .l_type = F_UNLCK,
+ .l_start = 0,
+ .l_whence = SEEK_SET,
+ .l_len = 0 /* Whole file */
+ };
+
+ if (fcntl(fileno(f), F_SETLK, &lock) < 0) {
+ perror("Can't unlock file");
+ return false;
+ }
+
+ return true;
+}
+
+bool mvconf_get_int(const char *key, int *val) {
+ int type;
+ char fname[PATH_MAX];
+ bool ret = false;
+ FILE *f;
+
+ if (!key || !val)
+ return false;
+
+ if (!get_key_path(key, fname, sizeof(fname))) {
+ printf("Can't get file path for vconf key \"%s\".\n", key);
+ return false;
+ }
+
+ if (!(f = fopen(fname, "r"))) {
+ printf("Can't open vconf key file \"%s\": %m.\n", fname);
+ return false;
+ }
+
+ if (!file_lock_read(f))
+ goto exit_close;
+
+ if (fread(&type, sizeof(int), 1, f) != 1) {
+ printf("Can't read type of vconf key from the file \"%s\".\n",
+ fname);
+ goto exit_unlock;
+ }
+
+ if (type != VCONF_TYPE_INT) {
+ printf("Wrong type %d of vconf key \"%s\".\n", type, key);
+ goto exit_unlock;
+ }
+
+ if (fread(val, sizeof(int), 1, f) != 1) {
+ printf("Can't read value of vconf key from the file "
+ "\"%s\".\n", fname);
+ goto exit_unlock;
+ }
+
+ ret = true;
+
+exit_unlock:
+ file_unlock(f);
+exit_close:
+ fclose(f);
+ return ret;
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+
+/* These prefixes are defined in vconf-internals.h which is not installed,
+ * so redefining it here with VCONF_ prefix. */
+#define VCONF_BACKEND_DB_PREFIX "db/"
+#define VCONF_BACKEND_FILE_PREFIX "file/"
+
+#define VCONF_BACKEND_SYSTEM_DIR "/opt/var/kdb/"
+
+bool mvconf_get_int(const char *key, int *val);
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _POSIX_SOURCE
+
+#include <errno.h>
+#include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/wait.h>
+#include <sys/types.h>
+
+#include "process-util.h"
+#include "system-recovery.h" /* For LOGD */
+
+int process_exec(process_exec_type sync, char *argv[]) {
+ pid_t pid;
+ struct sigaction act, oldact;
+ int r = 0;
+
+ if (!argv)
+ return -EINVAL;
+
+ /* Use default signal handler */
+ act.sa_handler = SIG_DFL;
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+
+ if (sigaction(SIGCHLD, &act, &oldact) < 0)
+ return -errno;
+
+ pid = fork();
+ if (pid < 0) { /* Error */
+ LOGD("Failed to fork\n");
+ r = -errno;
+ } else if (!pid) { /* Child */
+ int i;
+
+ for (i = 0; i < _NSIG; i++)
+ signal(i, SIG_DFL);
+
+ r = execv(argv[0], (char **)argv);
+ if (r < 0)
+ exit(EXIT_FAILURE);
+ } else { /* Parent */
+ int status;
+
+ if (sync == PROCESS_NON_WAIT)
+ return pid;
+
+ /* Wait for child */
+ if (waitpid(pid, &status, 0) != -1) {
+ if (WIFEXITED(status)) { /* Terminated normally */
+ LOGD("%d terminated by exit(%d)\n", pid,
+ WEXITSTATUS(status));
+ return WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status))
+ LOGD("%d terminated by signal %d\n", pid,
+ WTERMSIG(status));
+ else if (WIFSTOPPED(status))
+ LOGD("%d stopped by signal %d\n", pid,
+ WSTOPSIG(status));
+ } else
+ LOGD("%d waitpid() failed : %s\n", pid,
+ strerror(errno));
+ }
+
+ if (sigaction(SIGCHLD, &oldact, NULL) < 0)
+ LOGD("failed to restore sigaction\n");
+
+ return r;
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ PROCESS_NON_WAIT,
+ PROCESS_WAIT_CHILD
+} process_exec_type;
+
+int process_exec(process_exec_type sync, char *argv[]);
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+#!/bin/bash
+
+SYSTEM_RECOVERY="/usr/bin/system-recovery"
+FAKE_ROOT=/system
+
+AWK="/usr/bin/awk"
+GREP="/usr/bin/grep"
+MOUNT="/usr/bin/mount"
+PARTX="/usr/sbin/partx"
+REBOOT="/usr/lib/initrd-recovery/minireboot"
+SYNC="/usr/bin/sync"
+TOUCH="/usr/bin/touch"
+UMOUNT="/usr/bin/umount"
+VERITYCTL="/usr/bin/verityctl"
+
+#------------------------------------------------
+# get partition id
+#------------------------------------------------
+get_partition_id() {
+ EMMC_DEVICE="/dev/mmcblk0"
+ RET_PARTX=$("$PARTX" -s ${EMMC_DEVICE})
+ PART_ROOTFS=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "rootfs" {print $1}')
+ PART_SYSTEM_DATA=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "system-data" {print $1}')
+ PART_USER=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "user" {print $1}')
+ PART_CSC=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "csc" {print $1}')
+ PART_MODULES=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | "$AWK" 'tolower($6) == "module" {print $1}')
+}
+
+#------------------------------------------------
+# mount_partitions
+#------------------------------------------------
+mount_partitions() {
+ echo "mount partitions"
+ get_partition_id
+
+ if [ -e "$VERITYCTL" ]; then
+ "$VERITYCTL" dump ${PART_ROOTFS} | "$GREP" "HASH mode" | "$GREP" "on" > /dev/null
+ if [ $? -eq 0 ]; then
+ "$VERITYCTL" create rootfs ${PART_ROOTFS}
+ "$MOUNT" -t ext4 /dev/mapper/rootfs ${FAKE_ROOT} -o ro
+ else
+ "$MOUNT" -t ext4 ${PART_ROOTFS} ${FAKE_ROOT} -o ro
+ fi
+ else
+ "$MOUNT" -t ext4 ${PART_ROOTFS} ${FAKE_ROOT} -o ro
+ fi
+
+ "$MOUNT" -t ext4 ${PART_SYSTEM_DATA} ${FAKE_ROOT}/opt
+ "$MOUNT" -t ext4 ${PART_USER} ${FAKE_ROOT}/opt/usr
+ "$MOUNT" -t ext4 ${PART_CSC} ${FAKE_ROOT}/opt/system/csc
+
+ "$MOUNT" -t proc none ${FAKE_ROOT}/proc
+ "$MOUNT" -t sysfs none ${FAKE_ROOT}/sys
+ "$MOUNT" -t smackfs smackfs ${FAKE_ROOT}/sys/fs/smackfs
+ "$MOUNT" -t devtmpfs devtmpfs ${FAKE_ROOT}/dev
+ "$MOUNT" -t devpts devpts ${FAKE_ROOT}/dev/pts
+ "$MOUNT" -t tmpfs tmpfs ${FAKE_ROOT}/tmp -o mode=1777,smackfsroot=*
+}
+
+#------------------------------------------------
+# umount_partitions
+#------------------------------------------------
+umount_partitions() {
+ echo "umount partitions"
+ "$SYNC"
+ get_partition_id
+
+ "$UMOUNT" ${FAKE_ROOT}/opt/system/csc
+ "$UMOUNT" ${FAKE_ROOT}/opt/usr
+ "$UMOUNT" ${FAKE_ROOT}/opt
+ "$UMOUNT" ${FAKE_ROOT}
+}
+
+#------------------------------------------------
+# do_reboot
+#------------------------------------------------
+do_reboot() {
+ echo "Reboot"
+ "$SYNC"
+ "$REBOOT"
+ while [ 1 ]
+ do
+ sleep 1
+ echo "."
+ done
+}
+
+#------------------------------------------------
+# system-recovery initrc
+#------------------------------------------------
+echo "Starting system recovery."
+mount_partitions
+if [ "z@RECOVERY_GUI@" == "zGUI" ]; then
+ "$SYSTEM_RECOVERY"
+else
+ $TOUCH ${FAKE_ROOT}/opt/.factoryreset
+ if [ $? -ne 0 ]; then
+ echo "Error: failed to put factory reset file flag."
+ fi
+fi
+umount_partitions
+do_reboot
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 _POSIX_SOURCE
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/reboot.h>
+
+#include <vconf/vconf-keys.h>
+
+#include "rui.h"
+#include "common.h"
+#include "graphics.h"
+#include "minvconf.h"
+#include "input-events.h"
+#include "process-util.h"
+#include "system-recovery.h"
+#include "rui-progress-bar.h"
+
+bool volatile running = true;
+
+void sys_power_reboot(void) {
+ reboot(RB_AUTOBOOT);
+}
+
+void boot_safe_mode(void) {
+ int fd;
+
+ if ((fd = creat(SAFE_MODE_FILE, 0664)) < 0) {
+ LOGD("Can't enable safe mode.\n");
+ return; /* TODO: Display error message! */
+ }
+
+ LOGD("Safe-mode enabled.\n");
+ close(fd);
+ running = false;
+}
+
+void run_factory_reset(void) {
+ /* int r UNUSED; */
+ /* char *argv[2] = { FACTORY_RESET, NULL }; */
+
+ /* if (pivot_root(ROOT_MOUNT_DIR, INITRD_MOUNT_DIR)) { */
+ /* perror("pivot_root() failed"); */
+ /* return; /\* TODO: Display error message! *\/ */
+ /* } */
+
+ /* r = chdir("/"); */
+ /* process_exec(PROCESS_NON_WAIT, argv); */
+
+ /* creat(INITRD_MOUNT_DIR "/opt/.factoryreset-test", 0644); */
+ int fd;
+
+ if ((fd = creat("/opt/.factoryreset", 0644)) < 0) {
+ LOGD("Can't factory reset.\n");
+ return;
+ }
+ sync();
+ close(fd);
+ reboot(RB_AUTOBOOT);
+}
+
+int main(void) {
+ LOGD("[main] recovery started.\n");
+ if (!recovery_rui_init()) {
+ LOGD("Can't initialize GUI.\n");
+ return 1;
+ }
+
+ if (!ev_init()) {
+ LOGD("Can't initialize input subsystem.\n");
+ recovery_rui_exit();
+ return 1;
+ }
+
+ rui_draw();
+
+ while (running)
+ if (!ev_dispatch(recovery_rui_input_callback))
+ break;
+
+ ev_exit();
+ recovery_rui_exit();
+ LOGD("[main] recovery finished.\n");
+ return 0;
+}
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "graphics.h"
+
+#define RUI_COLOR_BACKGROUND BLACK
+#define RUI_COLOR_TITLE (color) { 27, 199, 204, 255 }
+#define RUI_COLOR_RULER RUI_COLOR_TITLE
+
+#define RUI_COLOR_MENU_BG_SELECTED RUI_COLOR_TITLE
+#define RUI_COLOR_MENU_BG_UNSELECTED BLACK
+#define RUI_COLOR_MENU_TEXT_SELECTED WHITE
+#define RUI_COLOR_MENU_TEXT_UNSELECTED WHITE
+
+#define RUI_COLOR_DESCRIPTION_TITLE RUI_COLOR_TITLE
+#define RUI_COLOR_DESCRIPTION_TEXT WHITE
+
+#define RUI_COLOR_PROGRESS_BAR_BAR YELLOW
+#define RUI_COLOR_PROGRESS_BAR_BORDER RUI_COLOR_TITLE
+#define RUI_COLOR_PROGRESS_BAR_BACKGROUND BLACK
+
+#ifdef FEATURE_DISPLAY_720X1280
+#define RUI_MENU_ITEM_HEIGHT 60
+#define RUI_MENU_ITEM_SPACING 8
+#define RUI_MENU_TEXT_POS_X 15
+
+#define RUI_COMMON_MENU_POS_X 0
+
+#define RUI_MAIN_MENU_POS_X RUI_COMMON_MENU_POS_X
+#define RUI_MAIN_MENU_POS_Y 100
+
+#define RUI_REBOOT_MENU_POS_X RUI_COMMON_MENU_POS_X
+#define RUI_REBOOT_MENU_POS_Y 480
+
+#define RUI_SAFE_MENU_POS_X RUI_COMMON_MENU_POS_X
+#define RUI_SAFE_MENU_POS_Y 480
+
+#define RUI_FACTORY_MENU_POS_X RUI_COMMON_MENU_POS_X
+#define RUI_FACTORY_MENU_POS_Y 480
+
+#define RUI_SD_RESTORE_MENU_POS_X RUI_COMMON_MENU_POS_X
+#define RUI_SD_RESTORE_MENU_POS_Y 480
+
+#define RUI_MAIN_SCREEN_DESCRIPTION_POS_X 15
+#define RUI_MAIN_SCREEN_DESCRIPTION_POS_Y 480
+
+#define RUI_COMMON_SCREEN_DESCRIPTION_POS_X 15
+#define RUI_COMMON_SCREEN_DESCRIPTION_POS_Y 100
+
+#define RUI_RULER_HEIGHT 2
+
+#define RUI_RULER_TOP_POS_X 0
+#define RUI_RULER_TOP_POS_Y 80
+#define RUI_MAIN_SCREEN_RULER_POS_Y 420
+
+#define RUI_PROGRESS_BAR_BORDER_WIDTH 1
+#define RUI_PROGRESS_BAR_HEIGHT 20
+
+#define RUI_SD_RESTORE_RUN_SCREEN_PROGRESS_BAR_POS_X 5
+#define RUI_SD_RESTORE_RUN_SCREEN_PROGRESS_BAR_POS_Y 600
+
+#else
+#define RUI_MENU_ITEM_HEIGHT 50
+#define RUI_MENU_ITEM_SPACING 5
+#define RUI_MENU_TEXT_POS_X 5
+
+#define RUI_COMMON_MENU_POS_X 0
+
+#define RUI_MAIN_MENU_POS_X RUI_COMMON_MENU_POS_X
+#define RUI_MAIN_MENU_POS_Y 100
+
+#define RUI_REBOOT_MENU_POS_X RUI_COMMON_MENU_POS_X
+#define RUI_REBOOT_MENU_POS_Y 160
+
+#define RUI_SAFE_MENU_POS_X RUI_COMMON_MENU_POS_X
+#define RUI_SAFE_MENU_POS_Y 240
+
+#define RUI_FACTORY_MENU_POS_X RUI_COMMON_MENU_POS_X
+#define RUI_FACTORY_MENU_POS_Y 240
+
+#define RUI_SD_RESTORE_MENU_POS_X RUI_COMMON_MENU_POS_X
+#define RUI_SD_RESTORE_MENU_POS_Y 240
+
+#define RUI_MAIN_SCREEN_DESCRIPTION_POS_X 5
+#define RUI_MAIN_SCREEN_DESCRIPTION_POS_Y 372
+
+#define RUI_COMMON_SCREEN_DESCRIPTION_POS_X 5
+#define RUI_COMMON_SCREEN_DESCRIPTION_POS_Y 100
+
+#define RUI_RULER_HEIGHT 2
+
+#define RUI_RULER_TOP_POS_X 0
+#define RUI_RULER_TOP_POS_Y 60
+#define RUI_MAIN_SCREEN_RULER_POS_Y 347
+
+#define RUI_PROGRESS_BAR_BORDER_WIDTH 1
+#define RUI_PROGRESS_BAR_HEIGHT 20
+
+#define RUI_SD_RESTORE_RUN_SCREEN_PROGRESS_BAR_POS_X 5
+#define RUI_SD_RESTORE_RUN_SCREEN_PROGRESS_BAR_POS_Y 600
+#endif
+
+#define RUI_REBOOT_SCREEN_DESCRIPTION_POS_X RUI_COMMON_SCREEN_DESCRIPTION_POS_X
+#define RUI_REBOOT_SCREEN_DESCRIPTION_POS_Y RUI_COMMON_SCREEN_DESCRIPTION_POS_Y
+
+#define RUI_SAFE_SCREEN_DESCRIPTION_POS_X RUI_COMMON_SCREEN_DESCRIPTION_POS_X
+#define RUI_SAFE_SCREEN_DESCRIPTION_POS_Y RUI_COMMON_SCREEN_DESCRIPTION_POS_Y
+
+#define RUI_FACTORY_SCREEN_DESCRIPTION_POS_X RUI_COMMON_SCREEN_DESCRIPTION_POS_X
+#define RUI_FACTORY_SCREEN_DESCRIPTION_POS_Y RUI_COMMON_SCREEN_DESCRIPTION_POS_Y
+
+#define RUI_FACTORY_RUN_SCREEN_DESCRIPTION_POS_X RUI_COMMON_SCREEN_DESCRIPTION_POS_X
+#define RUI_FACTORY_RUN_SCREEN_DESCRIPTION_POS_Y RUI_COMMON_SCREEN_DESCRIPTION_POS_Y
+
+#define RUI_SD_RESTORE_SCREEN_DESCRIPTION_POS_X RUI_COMMON_SCREEN_DESCRIPTION_POS_X
+#define RUI_SD_RESTORE_SCREEN_DESCRIPTION_POS_Y RUI_COMMON_SCREEN_DESCRIPTION_POS_Y
+
+#define RUI_SD_RESTORE_RUN_SCREEN_DESCRIPTION_POS_X RUI_COMMON_SCREEN_DESCRIPTION_POS_X
+#define RUI_SD_RESTORE_RUN_SCREEN_DESCRIPTION_POS_Y RUI_COMMON_SCREEN_DESCRIPTION_POS_Y
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "rui.h"
+#include "common.h"
+#include "rui-menu.h"
+#include "graphics.h"
+#include "rui-image.h"
+#include "rui-ruler.h"
+#include "input-events.h"
+#include "rui-description.h"
+#include "system-recovery.h"
+#include "rui-progress-bar.h"
+#include "recovery-rui-skin.h"
+
+static rui_image rui_images[] = {
+ [RECOVERY_RUI_IMAGE_BACKGROUND_DEFAULT] = {
+ .fname = RUI_RECOVERY_IMAGES_DIR "/warning.png",
+ .c_bg = RUI_COLOR_BACKGROUND,
+ .align_hor = GR_ALIGN_CENTER,
+ .align_ver = GR_ALIGN_BOTTOM,
+ .offset_x = 0,
+ .offset_y = 0,
+ .img_type = GR_WITH_ALPHA,
+ .surface = NULL
+ }, [RECOVERY_RUI_IMAGE_MENU_TITLE] = {
+ .fname = RUI_RECOVERY_IMAGES_DIR "/menu-title.png",
+ .c_bg = RUI_COLOR_TITLE,
+ .align_hor = GR_ALIGN_CENTER,
+ .align_ver = GR_ALIGN_TOP,
+ .offset_x = 0,
+ .offset_y = 20,
+ .img_type = GR_WITH_ALPHA,
+ .surface = NULL
+ }
+};
+
+static rui_animation rui_animations[] = {
+ [RECOVERY_RUI_ANIMATION_WORKING] = {
+ .fname = RUI_RECOVERY_IMAGES_DIR "/tizen-anim.png",
+ .c_bg = RUI_COLOR_BACKGROUND,
+ .align_hor = GR_ALIGN_CENTER,
+ .align_ver = GR_ALIGN_MIDDLE,
+ .offset_x = 0,
+ .offset_y = 0,
+ .frames_num = 0,
+ .current_frame = 0,
+ .img_type = GR_WITH_ALPHA,
+ .surfaces = NULL
+ }
+};
+
+static rui_menu_style rui_menu_common_style = {
+ .item_height = RUI_MENU_ITEM_HEIGHT,
+ .item_spacing = RUI_MENU_ITEM_SPACING,
+ .text_pos_x = RUI_MENU_TEXT_POS_X,
+ .c_bg_selected = RUI_COLOR_MENU_BG_SELECTED,
+ .c_bg_unselected = RUI_COLOR_MENU_BG_UNSELECTED,
+ .c_text_selected = RUI_COLOR_MENU_TEXT_SELECTED,
+ .c_text_unselected = RUI_COLOR_MENU_TEXT_UNSELECTED
+};
+
+static const char *rui_main_menu_items[] = {
+ "Reboot system now",
+ "Safe mode",
+ "Phone reinitialization",
+};
+
+static const char *rui_confirm_menu_items[] = {
+ "Yes",
+ "No"
+};
+
+static rui_menu_action rui_main_menu_actions[] = {
+ {
+ .screen_switch_to = RECOVERY_RUI_SCREEN_REBOOT,
+ .action_handler = NULL
+ }, {
+ .screen_switch_to = RECOVERY_RUI_SCREEN_SAFE,
+ .action_handler = NULL
+ }, {
+ .screen_switch_to = RECOVERY_RUI_SCREEN_FACTORY,
+ .action_handler = NULL
+ }
+};
+
+ASSERT_ARRAYS_EQUAL_LENGTH(rui_main_menu_actions, rui_main_menu_items);
+
+static rui_menu rui_main_menu = {
+ .pos_x = RUI_MAIN_MENU_POS_X,
+ .pos_y = RUI_MAIN_MENU_POS_Y,
+ .style = &rui_menu_common_style,
+ .items = rui_main_menu_items,
+ .items_num = ARRAY_SIZE(rui_main_menu_items),
+ .item_selected = 0,
+ .item_default = RUI_MENU_ITEM_DO_NOT_CHANGE,
+ .actions = rui_main_menu_actions
+};
+
+static rui_menu_action rui_reboot_menu_actions[] = {
+ {
+ .screen_switch_to = RUI_SCREEN_CURRENT,
+ .action_handler = sys_power_reboot
+ }, {
+ .screen_switch_to = RUI_SCREEN_BACK,
+ .action_handler = NULL
+ }
+};
+
+ASSERT_ARRAYS_EQUAL_LENGTH(rui_reboot_menu_actions, rui_confirm_menu_items);
+
+static rui_menu rui_reboot_menu = {
+ .pos_x = RUI_REBOOT_MENU_POS_X,
+ .pos_y = RUI_REBOOT_MENU_POS_Y,
+ .style = &rui_menu_common_style,
+ .items = rui_confirm_menu_items,
+ .items_num = ARRAY_SIZE(rui_confirm_menu_items),
+ .item_selected = 1,
+ .item_default = 1,
+ .actions = rui_reboot_menu_actions
+};
+
+static rui_menu_action rui_safe_menu_actions[] = {
+ {
+ .screen_switch_to = RUI_SCREEN_CURRENT,
+ .action_handler = boot_safe_mode
+ }, {
+ .screen_switch_to = RUI_SCREEN_BACK,
+ .action_handler = NULL
+ }
+};
+
+ASSERT_ARRAYS_EQUAL_LENGTH(rui_safe_menu_actions, rui_confirm_menu_items);
+
+static rui_menu rui_safe_menu = {
+ .pos_x = RUI_SAFE_MENU_POS_X,
+ .pos_y = RUI_SAFE_MENU_POS_Y,
+ .style = &rui_menu_common_style,
+ .items = rui_confirm_menu_items,
+ .items_num = ARRAY_SIZE(rui_confirm_menu_items),
+ .item_selected = 1,
+ .item_default = 1,
+ .actions = rui_safe_menu_actions
+};
+
+static rui_menu_action rui_factory_menu_actions[] = {
+ {
+ .screen_switch_to = RECOVERY_RUI_SCREEN_FACTORY_RUN,
+ .action_handler = run_factory_reset
+ }, {
+ .screen_switch_to = RUI_SCREEN_BACK,
+ .action_handler = NULL
+ }
+};
+
+ASSERT_ARRAYS_EQUAL_LENGTH(rui_factory_menu_actions, rui_confirm_menu_items);
+
+static rui_menu rui_factory_menu = {
+ .pos_x = RUI_FACTORY_MENU_POS_X,
+ .pos_y = RUI_FACTORY_MENU_POS_Y,
+ .style = &rui_menu_common_style,
+ .items = rui_confirm_menu_items,
+ .items_num = ARRAY_SIZE(rui_confirm_menu_items),
+ .item_selected = 1,
+ .item_default = 1,
+ .actions = rui_factory_menu_actions
+};
+
+static rui_description_style rui_description_common_style = {
+ .c_title = RUI_COLOR_DESCRIPTION_TITLE,
+ .c_text = RUI_COLOR_DESCRIPTION_TEXT
+};
+
+static rui_description rui_main_screen_description = {
+ .pos_x = RUI_MAIN_SCREEN_DESCRIPTION_POS_X,
+ .pos_y = RUI_MAIN_SCREEN_DESCRIPTION_POS_Y,
+ .style = &rui_description_common_style,
+ .title = "Controls:",
+ .text = "Volume Up/Down to move menu cursor\n"
+ "Power button to select"
+};
+
+static rui_description rui_reboot_screen_description = {
+ .pos_x = RUI_REBOOT_SCREEN_DESCRIPTION_POS_X,
+ .pos_y = RUI_REBOOT_SCREEN_DESCRIPTION_POS_Y,
+ .style = &rui_description_common_style,
+ .title = "The phone will be restarted.",
+ .text = "Continue?"
+};
+
+static rui_description rui_safe_screen_description = {
+ .pos_x = RUI_SAFE_SCREEN_DESCRIPTION_POS_X,
+ .pos_y = RUI_SAFE_SCREEN_DESCRIPTION_POS_Y,
+ .style = &rui_description_common_style,
+ .title = "Safe mode:",
+ .text = "The phone will be started in safe mode.\n"
+ "Home screen will be changed to default\n"
+ "setting and just allow a user to use\n"
+ "only preloaded applications.\n"
+ "Continue?"
+};
+
+static rui_description rui_factory_screen_description = {
+ .pos_x = RUI_FACTORY_SCREEN_DESCRIPTION_POS_X,
+ .pos_y = RUI_FACTORY_SCREEN_DESCRIPTION_POS_Y,
+ .style = &rui_description_common_style,
+ .title = "Factory reset (except SD-card)",
+ .text = "This will erase all data from your\n"
+ "phone's internal storage, including\n"
+ "settings of downloaded and preloaded\n"
+ "applications and system configuration.\n"
+ "Continue?"
+};
+
+static rui_description rui_factory_run_screen_description = {
+ .pos_x = RUI_FACTORY_RUN_SCREEN_DESCRIPTION_POS_X,
+ .pos_y = RUI_FACTORY_RUN_SCREEN_DESCRIPTION_POS_Y,
+ .style = &rui_description_common_style,
+ .title = "Restoring settings to factory default.",
+ .text = "Please wait. Do not turn off.\n"
+ "(Hold power button for 3 seconds\n"
+ "to reboot the device. Not recommended.)"
+};
+
+static rui_ruler_style rui_ruler_common_style = {
+ .c_ruler = RUI_COLOR_RULER
+};
+
+static rui_ruler rui_main_screen_rulers[] = {
+ { /* After menu title */
+ .pos_x = RUI_RULER_TOP_POS_X,
+ .pos_y = RUI_RULER_TOP_POS_Y,
+ .height = RUI_RULER_HEIGHT,
+ .style = &rui_ruler_common_style
+ }, { /* After main menu */
+ .pos_x = RUI_RULER_TOP_POS_X,
+ .pos_y = RUI_MAIN_SCREEN_RULER_POS_Y,
+ .height = RUI_RULER_HEIGHT,
+ .style = &rui_ruler_common_style
+ }, { /* End marker */
+ .pos_x = 0,
+ .pos_y = 0,
+ .height = 0,
+ .style = NULL
+ }
+};
+
+/* Both for reboot and safe mode screens */
+static rui_ruler rui_confirm_screens_rulers[] = {
+ { /* After menu title */
+ .pos_x = RUI_RULER_TOP_POS_X,
+ .pos_y = RUI_RULER_TOP_POS_Y,
+ .height = RUI_RULER_HEIGHT,
+ .style = &rui_ruler_common_style
+ }, { /* End marker */
+ .pos_x = 0,
+ .pos_y = 0,
+ .height = 0,
+ .style = NULL
+ }
+};
+
+static rui_screen_style rui_screen_common_style = {
+ .c_background = RUI_COLOR_BACKGROUND
+};
+
+static int rui_common_screen_images[] = {
+ RECOVERY_RUI_IMAGE_BACKGROUND_DEFAULT,
+ RECOVERY_RUI_IMAGE_MENU_TITLE,
+ RUI_IMAGE_NONE /* Stop element */
+};
+
+static int rui_common_run_screen_images[] = {
+ RECOVERY_RUI_IMAGE_MENU_TITLE,
+ RUI_IMAGE_NONE /* Stop element */
+};
+
+static int rui_factory_run_screen_animations[] = {
+ RECOVERY_RUI_ANIMATION_WORKING,
+ RUI_ANIMATION_NONE /* Stop element */
+};
+
+static rui_screen rui_screens[] = {
+ [RECOVERY_RUI_SCREEN_MAIN] = {
+ .style = &rui_screen_common_style,
+ .menu = &rui_main_menu,
+ .description = &rui_main_screen_description,
+ .rulers = rui_main_screen_rulers,
+ .progress_bar = NULL,
+ .images = rui_common_screen_images,
+ .animations = NULL,
+ .on_enter = NULL,
+ .draw = NULL,
+ .screen_back = RUI_SCREEN_CURRENT
+ }, [RECOVERY_RUI_SCREEN_REBOOT] = {
+ .style = &rui_screen_common_style,
+ .menu = &rui_reboot_menu,
+ .description = &rui_reboot_screen_description,
+ .rulers = rui_confirm_screens_rulers,
+ .progress_bar = NULL,
+ .images = rui_common_screen_images,
+ .animations = NULL,
+ .on_enter = NULL,
+ .draw = NULL,
+ .screen_back = RECOVERY_RUI_SCREEN_MAIN
+ }, [RECOVERY_RUI_SCREEN_SAFE] = {
+ .style = &rui_screen_common_style,
+ .menu = &rui_safe_menu,
+ .description = &rui_safe_screen_description,
+ .rulers = rui_confirm_screens_rulers,
+ .progress_bar = NULL,
+ .images = rui_common_screen_images,
+ .animations = NULL,
+ .on_enter = NULL,
+ .draw = NULL,
+ .screen_back = RECOVERY_RUI_SCREEN_MAIN
+ }, [RECOVERY_RUI_SCREEN_FACTORY] = {
+ .style = &rui_screen_common_style,
+ .menu = &rui_factory_menu,
+ .description = &rui_factory_screen_description,
+ .rulers = rui_confirm_screens_rulers,
+ .progress_bar = NULL,
+ .images = rui_common_screen_images,
+ .animations = NULL,
+ .on_enter = NULL,
+ .draw = NULL,
+ .screen_back = RECOVERY_RUI_SCREEN_MAIN
+ }, [RECOVERY_RUI_SCREEN_FACTORY_RUN] = {
+ .style = &rui_screen_common_style,
+ .menu = NULL,
+ .description = &rui_factory_run_screen_description,
+ .rulers = rui_confirm_screens_rulers,
+ .progress_bar = NULL,
+ .images = rui_common_run_screen_images,
+ .animations = rui_factory_run_screen_animations,
+ .on_enter = NULL,
+ .draw = NULL,
+ .screen_back = RUI_SCREEN_CURRENT
+ }
+};
+
+void recovery_rui_input_callback(user_action action, user_action_type action_type) {
+ int need_repaint = 1;
+ rui_screen *cs;
+
+ /* We interested only in button downs, long presses and idle events */
+ if (action_type != ACTION_TYPE_BEGIN &&
+ action_type != ACTION_TYPE_LONGPRESS &&
+ action_type != ACTION_TYPE_IDLE)
+ return;
+
+ cs = get_current_screen();
+ if (action == ACTION_DOWN && cs->menu)
+ rui_menu_cursor_down(cs->menu);
+ else if (action == ACTION_UP && cs->menu)
+ rui_menu_cursor_up(cs->menu);
+ else if (get_current_screen_id() == RECOVERY_RUI_SCREEN_FACTORY_RUN &&
+ action == ACTION_CONFIRM &&
+ action_type == ACTION_TYPE_LONGPRESS)
+ sys_power_reboot();
+ else if ((action == ACTION_CONFIRM || action == ACTION_HOME) &&
+ cs->menu)
+ rui_menu_action_run(cs->menu);
+ else if (action == ACTION_BACK)
+ rui_screen_switch(RUI_SCREEN_BACK);
+ else if (action != ACTION_NONE || action_type != ACTION_TYPE_IDLE ||
+ !cs->animations)
+ need_repaint = 0;
+
+ if (need_repaint)
+ rui_draw();
+}
+
+bool recovery_rui_init(void) {
+ return rui_init(rui_screens, ARRAY_SIZE(rui_screens),
+ RECOVERY_RUI_SCREEN_MAIN,
+ rui_images, ARRAY_SIZE(rui_images),
+ rui_animations, ARRAY_SIZE(rui_animations));
+}
+
+void recovery_rui_exit(void) {
+ rui_exit();
+}
--- /dev/null
+This directory contains some source files for images used by system-recovery
+framebuffer GUI.
+
+The menu title image can be generated by ./make-menu-title.sh shell-script.
+The required font SamsungSans_Md.ttf can be found
+in magnolia/framework/graphics/all-fonts-slp project.
+
+It is possible to draw menu title by using fixed-width font but
+label typed with TrueType font looks better.
+
+To draw progress animation system-recovery uses interlaced PNG-image
+with all frames combined. For making tizen-anim.png you can use ./make-anim.sh
+shell-script which uses ./interlace-frames.py python-script.
--- /dev/null
+#!/usr/bin/python
+#
+# Copyright (C) 2014 The Android Open Source Project
+# Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Script to take a set of frames (PNG files) for a recovery animation
+and turn it into a single output image which contains the input frames
+interlaced by row. Run with the names of all the input frames on the
+command line, in order, followed by the name of the output file."""
+
+import sys
+try:
+ import Image
+ import PngImagePlugin
+except ImportError:
+ print "This script requires the Python Imaging Library to be installed."
+ sys.exit(1)
+
+frames = [Image.open(fn).convert("RGBA") for fn in sys.argv[1:-1]]
+assert len(frames) > 0, "Must have at least one input frame."
+sizes = set()
+for fr in frames:
+ sizes.add(fr.size)
+
+assert len(sizes) == 1, "All input images must have the same size."
+w, h = sizes.pop()
+N = len(frames)
+
+out = Image.new("RGBA", (w, h * N))
+for j in range(h):
+ for i in range(w):
+ for fn, f in enumerate(frames):
+ out.putpixel((i, j * N + fn), f.getpixel((i, j)))
+
+# When loading this image, the graphics library expects to find a text
+# chunk that specifies how many frames this animation represents. If
+# you post-process the output of this script with some kind of
+# optimizer tool (eg pngcrush or zopflipng) make sure that your
+# optimizer preserves this text chunk.
+
+meta = PngImagePlugin.PngInfo()
+meta.add_text("Frames", str(N))
+
+out.save(sys.argv[-1], pnginfo=meta)
--- /dev/null
+#!/bin/bash
+
+FNAME="../res/system-recovery/images/tizen-anim.png"
+SRCIMG="./tizen-anim?src.png"
+
+./interlace-frames.py $SRCIMG "$FNAME"
+optipng -o 7 "$FNAME"
--- /dev/null
+#!/bin/bash
+
+FNAME="../res/system-recovery/images/menu-title.png"
+TEXT="Tizen system recovery"
+FONTSIZE=46
+FONT="./SamsungSans_Md.ttf"
+
+convert -background black -fill white -font "$FONT" -pointsize $FONTSIZE label:"$TEXT" "$FNAME"
+
+optipng -o 7 "$FNAME"
--- /dev/null
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdio.h>
+#include <stdbool.h>
+
+#include "input-events.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LOGD printf
+#define FILE_IO_BUF_SIZE 128
+
+#define SAFE_MODE_FILE "/opt/etc/.safeboot"
+#define ROOT_MOUNT_DIR "/system"
+#define INITRD_MOUNT_DIR "/system/mnt/initrd-recovery"
+#define FACTORY_RESET "/usr/bin/factory-reset"
+
+#define RUI_RECOVERY_IMAGES_DIR "/usr/lib/system-recovery/res/images"
+
+typedef enum {
+ RECOVERY_RUI_SCREEN_MAIN,
+ RECOVERY_RUI_SCREEN_REBOOT,
+ RECOVERY_RUI_SCREEN_SAFE,
+ RECOVERY_RUI_SCREEN_FACTORY,
+ RECOVERY_RUI_SCREEN_FACTORY_RUN,
+ RECOVERY_RUI_SCREEN_SD_RESTORE,
+ RECOVERY_RUI_SCREEN_SD_RESTORE_RUN
+} recovery_rui_screen_id;
+
+typedef enum {
+ RECOVERY_RUI_IMAGE_BACKGROUND_DEFAULT,
+ RECOVERY_RUI_IMAGE_MENU_TITLE
+} recovery_rui_image_id;
+
+typedef enum {
+ RECOVERY_RUI_ANIMATION_WORKING
+} recovery_rui_animation_id;
+
+int pivot_root(const char *new_root, const char *put_old);
+
+void sys_power_reboot(void);
+void boot_safe_mode(void);
+void run_factory_reset(void);
+void sd_restore(void);
+
+bool recovery_rui_init(void);
+void recovery_rui_exit(void);
+void recovery_rui_input_callback(user_action action,
+ user_action_type action_type);
+
+#ifdef __cplusplus
+}
+#endif