From: Jihoon Kim Date: Fri, 7 May 2021 02:28:30 +0000 (+0900) Subject: Change for supporting NUI backend X-Git-Tag: submit/tizen/20210803.031958~15 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=62b86a6ed05e9d238f350e91d519f9fc23563096;p=platform%2Fcore%2Fuifw%2Flibscl-ui-nui.git Change for supporting NUI backend Change-Id: I281f3634a68ca88f9be8a62c9f892b2e51178da0 Signed-off-by: Jihoon Kim --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 98b9ca2..295f780 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(libscl-ui CXX) +PROJECT(libscl-ui-nui CXX) SET(SRCS scl/sclres_manager.cpp @@ -36,10 +36,12 @@ SET(SRCS scl/sclcontroller.cpp scl/sclgwes.cpp scl/sclevents.cpp - scl/sclwindows-efl.cpp - scl/sclgraphics-efl.cpp - scl/sclanimator-efl.cpp - scl/sclevents-efl.cpp + + scl/sclwindows-nui.cpp + scl/sclgraphics-nui.cpp + scl/sclanimator-nui.cpp + scl/sclevents-nui.cpp + scl/sclfeedback.cpp scl/scluibuilder.cpp scl/scluiimpl.cpp @@ -115,7 +117,7 @@ ADD_DEFINITIONS("-DPACKAGE_NAME=\"${PKGNAME}\"") ADD_DEFINITIONS("-DLOG_TAG=\"LIBSCL_UI\"") ADD_DEFINITIONS("-DDEFAULT_THEME=\"default\"") ADD_DEFINITIONS("-DIMG_PATH_PREFIX=\"image\"") -ADD_DEFINITIONS("-D__EFL__") +ADD_DEFINITIONS("-D__NUI__") ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) @@ -124,12 +126,22 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS}) set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIBDIR}) -INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclui.h" DESTINATION include/libscl-ui) -INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclconfig.h" DESTINATION include/libscl-ui) -INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclstructs.h" DESTINATION include/libscl-ui) -INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/scleventcallback.h" DESTINATION include/libscl-ui) -INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclutils.h" DESTINATION include/libscl-ui) -INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclfeedback.h" DESTINATION include/libscl-ui) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclui.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclconfig.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclstructs.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/scleventcallback.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclgraphicsinfo.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclgraphicsbackendcallback.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclwindowbackendcallback.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclutils.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclfeedback.h" DESTINATION include/${name}) + +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclcontroller.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclgwes.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclwindows.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclgraphics.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclevents.h" DESTINATION include/${name}) +INSTALL(FILES "${CMAKE_SOURCE_DIR}/scl/sclcontext.h" DESTINATION include/${name}) CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) INSTALL(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIBDIR}/pkgconfig) diff --git a/libscl-ui-nui.manifest b/libscl-ui-nui.manifest new file mode 100644 index 0000000..017d22d --- /dev/null +++ b/libscl-ui-nui.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/libscl-ui-nui.pc.in b/libscl-ui-nui.pc.in new file mode 100644 index 0000000..5b347ac --- /dev/null +++ b/libscl-ui-nui.pc.in @@ -0,0 +1,14 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=${prefix} +libdir=@LIBDIR@ +includedir=${prefix}/include + +Name: libscl-ui-nui +Description: SCL UI NUI - A library for developing XML-based software keyboards +Version: 1.0 +Requires: libscl-common +Libs: -L${libdir} -lscl-ui-nui +Cflags: -I${includedir}/libscl-ui-nui + diff --git a/packaging/libscl-ui-nui.changes b/packaging/libscl-ui-nui.changes new file mode 100644 index 0000000..e69de29 diff --git a/packaging/libscl-ui-nui.spec b/packaging/libscl-ui-nui.spec new file mode 100644 index 0000000..ea9f996 --- /dev/null +++ b/packaging/libscl-ui-nui.spec @@ -0,0 +1,82 @@ +%bcond_with x +%bcond_with wayland + +Name: libscl-ui-nui +Summary: A library for developing XML-based software keyboards +Version: 0.6.88 +Release: 1 +Group: Graphics & UI Framework/Input +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(eldbus) +BuildRequires: pkgconfig(ecore-wl2) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(feedback) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: pkgconfig(tts) +BuildRequires: pkgconfig(libscl-common) + + +%description +A library that helps developing S/W Keyboard + +%package devel +Summary: SCL-UI-NUI header file +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +A devel package of libscl-ui-nui library that helps developing S/W Keyboard + +%prep +%setup -q + + +%build +export CFLAGS+=" -fvisibility=hidden -DTIZEN_DEBUG_ENABLE -Werror" +export CXXFLAGS+=" -fvisibility=hidden -fvisibility-inlines-hidden -DTIZEN_DEBUG_ENABLE -Werror" +export FFLAGS+=" -DTIZEN_DEBUG_ENABLE" + +# The -fvisibility=hidden option disables a generation of the rtti information for +# some classes with hidden visibility, this information is critically needed for +# ubsan VPTR check. Since this library needed to ise-default package, we should +# just disable visibility option with ubsan to avoid situation with undefined +# refernce to typeinfo. +%{?ubsan: +export CFLAGS=$(echo $CFLAGS | sed -e "s/-fvisibility=hidden//g") +export CXXFLAGS=$(echo $CXXFLAGS | sed -e "s/-fvisibility=hidden//g" -e "s/-fvisibility-inlines-hidden//g") +} + +rm -rf CMakeFiles +rm -rf CMakeCache.txt +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` + +%cmake . -Dwith_wayland=TRUE -DMAJORVER=${MAJORVER} -DFULLVER=%{version} + +make %{?_smp_mflags} + +%install +rm -rf %{buildroot} + +%make_install + + + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_libdir}/%{name}.so +%license LICENSE + +%files devel +%defattr(-,root,root,-) +%{_includedir}/* +%{_libdir}/pkgconfig/%{name}.pc diff --git a/packaging/libscl-ui.changes b/packaging/libscl-ui.changes deleted file mode 100644 index e69de29..0000000 diff --git a/packaging/libscl-ui.spec b/packaging/libscl-ui.spec deleted file mode 100644 index 4c15b59..0000000 --- a/packaging/libscl-ui.spec +++ /dev/null @@ -1,89 +0,0 @@ -%bcond_with x -%bcond_with wayland - -Name: libscl-ui -Summary: A library for developing XML-based software keyboards -Version: 0.6.88 -Release: 1 -Group: Graphics & UI Framework/Input -License: Apache-2.0 -Source0: %{name}-%{version}.tar.gz -BuildRequires: cmake -BuildRequires: pkgconfig(elementary) -BuildRequires: pkgconfig(eldbus) -%if %{with wayland} -BuildRequires: pkgconfig(ecore-wl2) -%else -BuildRequires: pkgconfig(ecore-x) -BuildRequires: pkgconfig(x11) -%endif -BuildRequires: pkgconfig(vconf) -BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pkgconfig(feedback) -BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(libxml-2.0) -BuildRequires: pkgconfig(tts) -BuildRequires: pkgconfig(libscl-common) - - -%description -A library that helps developing S/W Keyboard - -%package devel -Summary: SCL-UI header file -Group: Development/Libraries -Requires: %{name} = %{version}-%{release} - -%description devel -A devel package of libscl-ui library that helps developing S/W Keyboard - -%prep -%setup -q - - -%build -export CFLAGS+=" -fvisibility=hidden -DTIZEN_DEBUG_ENABLE -Werror" -export CXXFLAGS+=" -fvisibility=hidden -fvisibility-inlines-hidden -DTIZEN_DEBUG_ENABLE -Werror" -export FFLAGS+=" -DTIZEN_DEBUG_ENABLE" - -# The -fvisibility=hidden option disables a generation of the rtti information for -# some classes with hidden visibility, this information is critically needed for -# ubsan VPTR check. Since this library needed to ise-default package, we should -# just disable visibility option with ubsan to avoid situation with undefined -# refernce to typeinfo. -%{?ubsan: -export CFLAGS=$(echo $CFLAGS | sed -e "s/-fvisibility=hidden//g") -export CXXFLAGS=$(echo $CXXFLAGS | sed -e "s/-fvisibility=hidden//g" -e "s/-fvisibility-inlines-hidden//g") -} - -rm -rf CMakeFiles -rm -rf CMakeCache.txt - -%if %{with wayland} -%cmake . -Dwith_wayland=TRUE -%else -%cmake . -%endif -make %{?_smp_mflags} - -%install -rm -rf %{buildroot} - -%make_install - - - -%post -p /sbin/ldconfig - -%postun -p /sbin/ldconfig - -%files -%manifest %{name}.manifest -%defattr(-,root,root,-) -%{_libdir}/%{name}.so -%license LICENSE - -%files devel -%defattr(-,root,root,-) -%{_includedir}/* -%{_libdir}/pkgconfig/%{name}.pc diff --git a/scl/sclanimator-efl.cpp b/scl/sclanimator-efl.cpp deleted file mode 100644 index e969c85..0000000 --- a/scl/sclanimator-efl.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "sclanimator-efl.h" -#include "scldebug.h" - -#include -#include - -#include "sclutils.h" -#include "sclwindows.h" - -using namespace scl; - -/** - * Constructor - */ -CSCLAnimatorImplEfl::CSCLAnimatorImplEfl() -{ - SCL_DEBUG(); - - m_highlight_ui_object = NULL; - m_highlight_ui_object_alternate = NULL; -} - -/** - * De-constructor - */ -CSCLAnimatorImplEfl::~CSCLAnimatorImplEfl() -{ - SCL_DEBUG(); -} - -void CSCLAnimatorImplEfl::init() -{ -} - -void CSCLAnimatorImplEfl::fini() -{ - if (m_highlight_ui_object) { - evas_object_del(m_highlight_ui_object); - m_highlight_ui_object = NULL; - } - if (m_highlight_ui_object_alternate) { - evas_object_del(m_highlight_ui_object_alternate); - m_highlight_ui_object_alternate = NULL; - } -} - - -sclboolean -CSCLAnimatorImplEfl::check_animation_supported() -{ - /* EFL Backend finished implementing animation support */ - return TRUE; -} - -void -CSCLAnimatorImplEfl::animator_timer(SclAnimationState *state) -{ - CSCLUtils *utils = CSCLUtils::get_instance(); - CSCLWindows *windows = CSCLWindows::get_instance(); - - if (state && windows && utils) { - switch (state->desc.type) { - case ANIMATION_TYPE_HIGHLIGHT_UI: { - if (state->active) { - SclRectangle rect = state->rect_cur; - if (m_highlight_ui_object == NULL) { - Evas_Object *window_object = static_cast(windows->get_base_window()); - Evas *evas = evas_object_evas_get(window_object); - m_highlight_ui_object = evas_object_image_add(evas); - sclchar composed_path[_POSIX_PATH_MAX] = {0, }; - utils->get_composed_path(composed_path, IMG_PATH_PREFIX, SCL_HIGHLIGHT_UI_IMAGE); - evas_object_image_file_set(m_highlight_ui_object, composed_path, NULL); - } - evas_object_move(m_highlight_ui_object, rect.x, rect.y); - evas_object_image_fill_set(m_highlight_ui_object, 0, 0, rect.width, rect.height); - evas_object_resize(m_highlight_ui_object, rect.width, rect.height); - evas_object_raise(m_highlight_ui_object); - evas_object_show(m_highlight_ui_object); - - sclboolean circular = FALSE; - if (state->desc.circular) { - if (m_highlight_ui_object_alternate == NULL) { - Evas_Object *window_object = static_cast(windows->get_base_window()); - Evas *evas = evas_object_evas_get(window_object); - m_highlight_ui_object_alternate = evas_object_image_add(evas); - sclchar composed_path[_POSIX_PATH_MAX] = {0, }; - utils->get_composed_path(composed_path, IMG_PATH_PREFIX, SCL_HIGHLIGHT_UI_IMAGE); - evas_object_image_file_set(m_highlight_ui_object_alternate, composed_path, NULL); - } - SclWindowContext *window_context = windows->get_window_context(windows->get_base_window()); - if (window_context) { - if (rect.x < 0) { - evas_object_move(m_highlight_ui_object_alternate, - window_context->geometry.width + rect.x, rect.y); - evas_object_image_fill_set(m_highlight_ui_object_alternate, - 0, 0, rect.width, rect.height); - evas_object_resize(m_highlight_ui_object_alternate, - rect.width, rect.height); - evas_object_raise(m_highlight_ui_object_alternate); - evas_object_show(m_highlight_ui_object_alternate); - circular = TRUE; - } else if (rect.x + rect.width > window_context->geometry.width) { - evas_object_move(m_highlight_ui_object_alternate, - -(window_context->geometry.width - rect.x), rect.y); - evas_object_image_fill_set(m_highlight_ui_object_alternate, - 0, 0, rect.width, rect.height); - evas_object_resize(m_highlight_ui_object_alternate, - rect.width, rect.height); - evas_object_raise(m_highlight_ui_object_alternate); - evas_object_show(m_highlight_ui_object_alternate); - circular = TRUE; - } - } - } - if (!circular) { - if (m_highlight_ui_object_alternate) { - evas_object_hide(m_highlight_ui_object_alternate); - } - } else { - if (m_highlight_ui_object_alternate) { - sclint window_layer = 29000; - if (!windows->is_base_window(state->desc.window_from) || - !windows->is_base_window(state->desc.window_to)) { - window_layer = 29010; - } - evas_object_layer_set(m_highlight_ui_object_alternate, window_layer + 1); - } - } - - sclint window_layer = 29000; - if (!windows->is_base_window(state->desc.window_from) || - !windows->is_base_window(state->desc.window_to)) { - window_layer = 29010; - } - evas_object_layer_set(m_highlight_ui_object, window_layer + 1); - } else { - evas_object_hide(m_highlight_ui_object); - } - } - break; - default: - break; - } - } -} diff --git a/scl/sclanimator-efl.h b/scl/sclanimator-efl.h deleted file mode 100644 index 1325c83..0000000 --- a/scl/sclanimator-efl.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "sclanimator.h" - -#ifndef __SCL_ANIMATOR_EFL_H__ -#define __SCL_ANIMATOR_EFL_H__ - -#include - -namespace scl -{ -class CSCLAnimatorImplEfl : public CSCLAnimatorImpl -{ -public : - CSCLAnimatorImplEfl(); - ~CSCLAnimatorImplEfl(); - - void init(); - void fini(); - - sclboolean check_animation_supported(); - void animator_timer(SclAnimationState *state); - -private: - Evas_Object *m_highlight_ui_object; - Evas_Object *m_highlight_ui_object_alternate; -}; -} /* End of scl namespace */ -#endif //__SCL_ANIMATOR_EFL_H__ diff --git a/scl/sclanimator-nui.cpp b/scl/sclanimator-nui.cpp new file mode 100644 index 0000000..c2c8c9b --- /dev/null +++ b/scl/sclanimator-nui.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sclanimator-nui.h" +#include "scldebug.h" + +#include +#include + +#include "sclutils.h" +#include "sclwindows.h" + +using namespace scl; + +/** + * Constructor + */ +CSCLAnimatorImplNui::CSCLAnimatorImplNui() +{ + SCL_DEBUG(); + + m_highlight_ui_object = NULL; + m_highlight_ui_object_alternate = NULL; +} + +/** + * De-constructor + */ +CSCLAnimatorImplNui::~CSCLAnimatorImplNui() +{ + SCL_DEBUG(); +} + +void CSCLAnimatorImplNui::init() +{ +} + +void CSCLAnimatorImplNui::fini() +{ + if (m_highlight_ui_object) { + evas_object_del(m_highlight_ui_object); + m_highlight_ui_object = NULL; + } + if (m_highlight_ui_object_alternate) { + evas_object_del(m_highlight_ui_object_alternate); + m_highlight_ui_object_alternate = NULL; + } +} + + +sclboolean +CSCLAnimatorImplNui::check_animation_supported() +{ + /* EFL Backend finished implementing animation support */ + return TRUE; +} + +void +CSCLAnimatorImplNui::animator_timer(SclAnimationState *state) +{ + CSCLUtils *utils = CSCLUtils::get_instance(); + CSCLWindows *windows = CSCLWindows::get_instance(); + + if (state && windows && utils) { + switch (state->desc.type) { + case ANIMATION_TYPE_HIGHLIGHT_UI: { + if (state->active) { + SclRectangle rect = state->rect_cur; + if (m_highlight_ui_object == NULL) { + Evas_Object *window_object = static_cast(windows->get_base_window()); + Evas *evas = evas_object_evas_get(window_object); + m_highlight_ui_object = evas_object_image_add(evas); + sclchar composed_path[_POSIX_PATH_MAX] = {0, }; + utils->get_composed_path(composed_path, IMG_PATH_PREFIX, SCL_HIGHLIGHT_UI_IMAGE); + evas_object_image_file_set(m_highlight_ui_object, composed_path, NULL); + } + evas_object_move(m_highlight_ui_object, rect.x, rect.y); + evas_object_image_fill_set(m_highlight_ui_object, 0, 0, rect.width, rect.height); + evas_object_resize(m_highlight_ui_object, rect.width, rect.height); + evas_object_raise(m_highlight_ui_object); + evas_object_show(m_highlight_ui_object); + + sclboolean circular = FALSE; + if (state->desc.circular) { + if (m_highlight_ui_object_alternate == NULL) { + Evas_Object *window_object = static_cast(windows->get_base_window()); + Evas *evas = evas_object_evas_get(window_object); + m_highlight_ui_object_alternate = evas_object_image_add(evas); + sclchar composed_path[_POSIX_PATH_MAX] = {0, }; + utils->get_composed_path(composed_path, IMG_PATH_PREFIX, SCL_HIGHLIGHT_UI_IMAGE); + evas_object_image_file_set(m_highlight_ui_object_alternate, composed_path, NULL); + } + SclWindowContext *window_context = windows->get_window_context(windows->get_base_window()); + if (window_context) { + if (rect.x < 0) { + evas_object_move(m_highlight_ui_object_alternate, + window_context->geometry.width + rect.x, rect.y); + evas_object_image_fill_set(m_highlight_ui_object_alternate, + 0, 0, rect.width, rect.height); + evas_object_resize(m_highlight_ui_object_alternate, + rect.width, rect.height); + evas_object_raise(m_highlight_ui_object_alternate); + evas_object_show(m_highlight_ui_object_alternate); + circular = TRUE; + } else if (rect.x + rect.width > window_context->geometry.width) { + evas_object_move(m_highlight_ui_object_alternate, + -(window_context->geometry.width - rect.x), rect.y); + evas_object_image_fill_set(m_highlight_ui_object_alternate, + 0, 0, rect.width, rect.height); + evas_object_resize(m_highlight_ui_object_alternate, + rect.width, rect.height); + evas_object_raise(m_highlight_ui_object_alternate); + evas_object_show(m_highlight_ui_object_alternate); + circular = TRUE; + } + } + } + if (!circular) { + if (m_highlight_ui_object_alternate) { + evas_object_hide(m_highlight_ui_object_alternate); + } + } else { + if (m_highlight_ui_object_alternate) { + sclint window_layer = 29000; + if (!windows->is_base_window(state->desc.window_from) || + !windows->is_base_window(state->desc.window_to)) { + window_layer = 29010; + } + evas_object_layer_set(m_highlight_ui_object_alternate, window_layer + 1); + } + } + + sclint window_layer = 29000; + if (!windows->is_base_window(state->desc.window_from) || + !windows->is_base_window(state->desc.window_to)) { + window_layer = 29010; + } + evas_object_layer_set(m_highlight_ui_object, window_layer + 1); + } else { + evas_object_hide(m_highlight_ui_object); + } + } + break; + default: + break; + } + } +} diff --git a/scl/sclanimator-nui.h b/scl/sclanimator-nui.h new file mode 100644 index 0000000..d0411d6 --- /dev/null +++ b/scl/sclanimator-nui.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sclanimator.h" + +#ifndef __SCL_ANIMATOR_NUI_H__ +#define __SCL_ANIMATOR_NUI_H__ + +#include + +namespace scl +{ +class CSCLAnimatorImplNui : public CSCLAnimatorImpl +{ +public : + CSCLAnimatorImplNui(); + ~CSCLAnimatorImplNui(); + + void init(); + void fini(); + + sclboolean check_animation_supported(); + void animator_timer(SclAnimationState *state); + +private: + Evas_Object *m_highlight_ui_object; + Evas_Object *m_highlight_ui_object_alternate; +}; +} /* End of scl namespace */ +#endif //__SCL_ANIMATOR_NUI_H__ diff --git a/scl/sclanimator.cpp b/scl/sclanimator.cpp index 6bb04ce..180b043 100644 --- a/scl/sclanimator.cpp +++ b/scl/sclanimator.cpp @@ -20,6 +20,8 @@ #include "sclanimator-win32.h" #elif defined(__EFL__) #include "sclanimator-efl.h" +#elif defined(__NUI__) +#include "sclanimator-nui.h" #elif __GTK__ #include "sclanimator-gtk.h" #else @@ -83,6 +85,8 @@ CSCLAnimatorImpl* CSCLAnimator::get_scl_animator_impl() m_impl = new CSCLAnimatorImplWin32; #elif defined(__EFL__) m_impl = new CSCLAnimatorImplEfl; +#elif defined(__NUI__) + m_impl = new CSCLAnimatorImplNui; #elif __GTK__ m_impl = new CSCLAnimatorImplGtk; #else diff --git a/scl/sclbackendcallback.h b/scl/sclbackendcallback.h new file mode 100644 index 0000000..f8c4226 --- /dev/null +++ b/scl/sclbackendcallback.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __SCL_BACKENDCALLBACK_H__ +#define __SCL_BACKENDCALLBACK_H__ + +#include "sclgraphicsinfo.h" + +using namespace scl; + +//SCL_BEGIN_DECLS +/* FIXME : Need to check the dependency cause by the next include statement */ + +struct ISCLUIGraphicsBackendCallback { + virtual void on_draw_text(const SclFontInfo& font_info, const SclColor& color, const char *str, int pos_x, int pos_y, int w, int h, + SCLLabelAlignment align, int padding_x, int padding_y, int inner_width, int inner_height, void* user_data) { } + + virtual void on_draw_image(const char *image_path, int dest_x, int dest_y, int dest_weight, int dest_height, int src_x, int src_y, int src_width, int src_height, void* user_data) { } + + virtual void on_draw_rectangle(int pos_x, int pos_y, int width, int height, bool fill, int fill_color_r, int fill_color_g, int fill_color_b, int fill_color_a, void* user_data) { } + + virtual void update_window(int x, int w, int width, int height, void* user_data) { } +}; + +#endif //__SCL_BACKENDCALLBACK_H__ diff --git a/scl/sclcontroller.h b/scl/sclcontroller.h index 0a97612..cbb2eba 100644 --- a/scl/sclcontroller.h +++ b/scl/sclcontroller.h @@ -49,7 +49,7 @@ enum SclInternalSignal { * This class implements all functions for working as a soft-based keyboard * In side of ISE developer, they can modify it by their requirements. */ -class CSCLController +class EXAPI CSCLController { private: CSCLController(); diff --git a/scl/scldebug.cpp b/scl/scldebug.cpp index 3f947f6..8bc8499 100644 --- a/scl/scldebug.cpp +++ b/scl/scldebug.cpp @@ -22,11 +22,11 @@ #ifdef SCL_DEBUG_ON -/* Measure elapsed time */ +/* Measure elapased time */ static float _SCL_DEBUG_ELAPSED_TIME(const char* str, struct timeval t0, struct timeval t1); -/* Measure elapsed time */ +/* Measure elapased time */ float SCL_DEBUG_TIME(const char* fileStr, int line, const char* str) { float etime = 0.0; diff --git a/scl/sclevents-efl.cpp b/scl/sclevents-efl.cpp deleted file mode 100644 index 4492bc8..0000000 --- a/scl/sclevents-efl.cpp +++ /dev/null @@ -1,1249 +0,0 @@ -/* - * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "sclevents-efl.h" -#include "scldebug.h" -#include "sclcontroller.h" -#include "sclgraphics.h" -#include "scluibuilder.h" -#include "sclerroradjustment.h" -#include "sclresource.h" -#include "sclresourcecache.h" -#include "sclres_manager.h" - -#include -#include -#include -#ifdef WAYLAND -#define EFL_BETA_API_SUPPORT -#include -#else -#include -#endif - -#include "sclkeyfocushandler.h" - -using namespace scl; - -#ifdef USING_KEY_GRAB -#define HANDLE_KEY_EVENTS -#endif - -#define E_PROP_TOUCH_INPUT "X_TouchInput" - -#ifdef WAYLAND -#define E_KEYBOARD_SERVICE_BUS_NAME "org.tizen.keyboard" -#define E_KEYBOARD_SERVICE_NAVI_IFC_NAME "org.tizen.KBGestureNavigation" -#define E_KEYBOARD_SERVICE_NAVI_OBJ_PATH "/org/tizen/KBGestureNavigation" -static Eldbus_Connection *eldbus_conn = NULL; -static Eldbus_Object *eldbus_bus_obj = NULL; - -typedef enum _Gesture { - ONE_FINGER_HOVER = 0, - ONE_FINGER_SINGLE_TAP = 15, - ONE_FINGER_DOUBLE_TAP = 16 -} Gesture; - -typedef struct -{ - Gesture type; // Type of recognized gesture - int x; - int y; -} Gesture_Info; -#endif - -static sclboolean mouse_pressed = FALSE; /* Checks whether mouse is pressed or not */ -static sclwindow pressed_window = SCLWINDOW_INVALID; - -/* If the gap between two timestamps are bigger than 1 sec, do not compare */ -const unsigned int _touch_event_timestamp_compare_range = 1000; -/* If the gap between two timestamps are smaller than 50 msec, do not process */ -const unsigned int _touch_event_timestamp_valid_threshold = 50; -extern unsigned int g_timestamp_last_base_window_resized; - -#define MIN_XY_DIFF 14 - -static Eina_Bool mouse_press(void *data, int type, void *event_info); -static Eina_Bool mouse_move(void *data, int type, void *event_info); -static Eina_Bool mouse_release(void *data, int type, void *event_info); - -#ifndef WAYLAND -static Eina_Bool client_message_cb(void *data, int type, void *event); -#endif - -#ifdef HANDLE_KEY_EVENTS -static Eina_Bool key_pressed(void *data, int type, void *event_info); -#endif - -static sclboolean get_window_rect(const sclwindow window, SclRectangle *rect) -{ - SCL_DEBUG(); - sclboolean ret = FALSE; - CSCLUtils *utils = CSCLUtils::get_instance(); - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLContext *context = CSCLContext::get_instance(); - if (windows && context && utils && rect) { - SclWindowContext *window_context = windows->get_window_context(window); - sclint scr_w, scr_h; - /* get window size */ - if (window_context && utils->get_screen_resolution(&scr_w, &scr_h)) { - switch (context->get_rotation()) { - case ROTATION_90_CW: - { - rect->height = window_context->geometry.width; - rect->width = window_context->geometry.height; - rect->y = scr_w - rect->height - window_context->geometry.x; - rect->x = window_context->geometry.y; - } - break; - case ROTATION_180: - { - rect->width = window_context->geometry.width; - rect->height = window_context->geometry.height; - rect->x = scr_w - window_context->geometry.x - rect->width; - rect->y = scr_h - window_context->geometry.y - rect->height; - } - break; - case ROTATION_90_CCW: - { - rect->height = window_context->geometry.width; - rect->width = window_context->geometry.height; - rect->y = window_context->geometry.x; - rect->x = scr_h - window_context->geometry.y - rect->width; - } - break; - default: - { - rect->x = window_context->geometry.x; - rect->y = window_context->geometry.y; - rect->width = window_context->geometry.width; - rect->height = window_context->geometry.height; - } - break; - } - ret = TRUE; - } else { - rect->x = rect->y = rect->width = rect->height = 0; - } - } - return ret; -} - -#ifdef WAYLAND -/* In wayland, root.x / root.y is not available, so need to apply virtual offset - when event occurred on a virtual window */ -static void apply_virtual_offset(SclRectangle rect, int *adjustx, int *adjusty) -{ - int virtual_offset_x = 0; - int virtual_offset_y = 0; - SclRectangle base_rect = {0, 0, 0, 0}; - - CSCLWindows *windows = CSCLWindows::get_instance(); - if (windows) { - if (get_window_rect(windows->get_base_window(), &base_rect)) { - virtual_offset_x = rect.x - base_rect.x; - virtual_offset_y = rect.y - base_rect.y; - } - if (adjustx && adjusty) { - *adjustx -= virtual_offset_x; - *adjusty -= virtual_offset_y; - } - } -} -#endif - -/** - * Constructor - */ -CSCLEventsImplEfl::CSCLEventsImplEfl() -{ - SCL_DEBUG(); - - m_mouse_down_handler = NULL; - m_mouse_move_handler = NULL; - m_mouse_up_handler = NULL; - -#ifndef WAYLAND - m_xclient_msg_handler = NULL; -#endif - m_key_pressed_handler = NULL; -} - -#ifdef WAYLAND -static void gesture_cb(void *data, const Eldbus_Message *msg) -{ - LOGD("GestureDetected callback"); - int g_type; - static int last_pos_x = -1; - static int last_pos_y = -1; - - if (!msg) { - LOGD("Incoming message is empty"); - return; - } - CSCLController *controller = CSCLController::get_instance(); - CSCLWindows *windows = CSCLWindows::get_instance(); - - if (!windows || !controller) return; - - sclwindow base_window = windows->get_base_window(); - SclWindowContext *window_context = windows->get_window_context(base_window); - - if (!window_context) return; - if (window_context->hidden) return; - - LOGD("window_context->geometry.x=%d y=%d w=%d h=%d", - window_context->geometry.x, window_context->geometry.y, - window_context->geometry.width, window_context->geometry.height); - - Gesture_Info *info = (Gesture_Info *)calloc(sizeof(Gesture_Info), 1); - if (!info) { - LOGD("Memory alloc failed for Gesture_Info"); - return; - } - if (!eldbus_message_arguments_get(msg, "iii", &g_type, &info->x, - &info->y)) { - LOGD("Getting message arguments failed"); - free(info); - return; - } - - info->type = (Gesture)g_type; - LOGD("Incoming gesture name is %d : %d %d", info->type, info->x, info->y); - - if (info->type == ONE_FINGER_HOVER || info->type == ONE_FINGER_SINGLE_TAP) { - if (info->y >= window_context->geometry.y) { - last_pos_x = info->x; - last_pos_y = info->y - window_context->geometry.y; - LOGD("hover last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y); - controller->mouse_over(base_window, last_pos_x, last_pos_y); - } - } else if (info->type == ONE_FINGER_DOUBLE_TAP) { - if (info->y >= window_context->geometry.y) { - last_pos_x = info->x; - last_pos_y = info->y - window_context->geometry.y; - LOGD("double last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y); - controller->mouse_press(base_window, last_pos_x, last_pos_y); - controller->mouse_release(base_window, last_pos_x, last_pos_y); - } - } - free(info); -} - -static void gestures_tracker_register() -{ - Eldbus_Proxy *proxy = NULL; - - if (eldbus_conn) - return; - - eldbus_init(); - LOGD("Registering callback for GestureDetected signal"); - if (!(eldbus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION))) { - LOGW("Error: Unable to get session bus"); - return; - } - - eldbus_bus_obj = eldbus_object_get(eldbus_conn, E_KEYBOARD_SERVICE_BUS_NAME, E_KEYBOARD_SERVICE_NAVI_OBJ_PATH); - if (!eldbus_bus_obj) { - LOGW("Error: Getting object failed"); - goto obj_err; - } - - proxy = eldbus_proxy_get(eldbus_bus_obj, E_KEYBOARD_SERVICE_NAVI_IFC_NAME); - if (!proxy) { - LOGW("Error: Getting proxy failed"); - goto proxy_err; - } - - if (!eldbus_proxy_signal_handler_add(proxy, "KBGestureDetected", gesture_cb, NULL)) - LOGW("No signal handler returned"); - - LOGD("Callback registration successful"); - return; - -proxy_err: - eldbus_object_unref(eldbus_bus_obj); - eldbus_bus_obj = NULL; -obj_err: - eldbus_connection_unref(eldbus_conn); - eldbus_conn = NULL; -} - -static void gestures_tracker_unregister() -{ - if (eldbus_bus_obj) { - eldbus_object_unref(eldbus_bus_obj); - eldbus_bus_obj = NULL; - } - - if (eldbus_conn) { - eldbus_connection_unref(eldbus_conn); - eldbus_conn = NULL; - - eldbus_shutdown(); - } -} -#endif -/** - * De-constructor - */ -CSCLEventsImplEfl::~CSCLEventsImplEfl() -{ - SCL_DEBUG(); - - fini(); -} - -void CSCLEventsImplEfl::init() -{ - /* Initializes all window resources */ - m_mouse_down_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, mouse_press, NULL); - m_mouse_move_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, mouse_move, NULL); - m_mouse_up_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, mouse_release, NULL); - -#ifndef WAYLAND - m_xclient_msg_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, client_message_cb, NULL); -#else - gestures_tracker_register(); -#endif - -#ifdef HANDLE_KEY_EVENTS - m_key_pressed_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, key_pressed, NULL); -#endif -} - -void CSCLEventsImplEfl::fini() -{ - if (m_mouse_down_handler) ecore_event_handler_del(m_mouse_down_handler); - m_mouse_down_handler = NULL; - if (m_mouse_move_handler) ecore_event_handler_del(m_mouse_move_handler); - m_mouse_move_handler = NULL; - if (m_mouse_up_handler) ecore_event_handler_del(m_mouse_up_handler); - m_mouse_up_handler = NULL; -#ifdef HANDLE_KEY_EVENTS - if (m_key_pressed_handler) ecore_event_handler_del(m_key_pressed_handler); -#endif - m_key_pressed_handler = NULL; -#ifndef WAYLAND - if (m_xclient_msg_handler) ecore_event_handler_del(m_xclient_msg_handler); -#else - gestures_tracker_unregister(); -#endif -} - -/** Here x and y contains "actual" x and y position relative to portrait root window, - and window_context->width,height contains the window's orientation dependant width and height */ -SclPoint get_rotated_local_coords(sclint x, sclint y, SCLRotation rotation, SclRectangle *rect) { - SclPoint ret = {0, 0}; - - if (rect) { - switch (rotation) { - case ROTATION_90_CW: - { - ret.x = (rect->y + rect->width) - y; - ret.y = x - rect->x; - } - break; - case ROTATION_180: - { - ret.x = (rect->x + rect->width) - x; - ret.y = (rect->y + rect->height) - y; - } - break; - case ROTATION_90_CCW: - { - ret.x = y - rect->y; - ret.y = (rect->x + rect->height) - x; - } - break; - default: - { - ret.x = x - rect->x; - ret.y = y - rect->y; - } - break; - } - } - return ret; -} - -static Eina_Bool check_timestamp_outdated(unsigned int timestamp) -{ - /* Skip events that were generated nearly at the same time when our base window resized */ - timestamp -= _touch_event_timestamp_valid_threshold; - unsigned int gap = (g_timestamp_last_base_window_resized > timestamp) ? - (g_timestamp_last_base_window_resized - timestamp) : - (timestamp - g_timestamp_last_base_window_resized); - if (gap < _touch_event_timestamp_compare_range) { - if (g_timestamp_last_base_window_resized > timestamp) { - /* This event was generated before the base window resize event, ignore */ - LOGD("Skipping event since turned out to be outdated : %u, %u", - g_timestamp_last_base_window_resized, timestamp); - return EINA_TRUE; - } - } - return EINA_FALSE; -} - -//void mouse_press (void *data, Evas *e, Evas_Object *object, void *event_info) -static Eina_Bool mouse_press(void *data, int type, void *event_info) -{ - SCL_DEBUG(); -#ifdef WAYLAND - Ecore_Wl2_Window *wl_base_window; - Ecore_Wl2_Window *wl_magnifier_window; - Ecore_Wl2_Window *wl_window; -#endif - - CSCLController *controller = CSCLController::get_instance(); - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLContext *context = CSCLContext::get_instance(); - CSCLUtils *utils = CSCLUtils::get_instance(); - CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance(); - - Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info; - - if (ev && check_timestamp_outdated(ev->timestamp)) { - return TRUE; - } - - if (controller && windows && context && utils && adjustment && ev) { - LOGD("mouse_press : %d %d, %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y, - g_timestamp_last_base_window_resized, ev->timestamp); - - sclbyte index = 0; - sclboolean processed = FALSE; - sclwindow window = SCLWINDOW_INVALID; - -#ifndef WAYLAND - Ecore_X_Window inputWindow = 0; - Ecore_X_Atom inputAtom = ecore_x_atom_get("DeviceMgr Input Window"); - ecore_x_window_prop_xid_get(ecore_x_window_root_first_get(), - inputAtom, ECORE_X_ATOM_WINDOW, &inputWindow, 1); - if (inputWindow == 0) { - utils->log("Error : input window NULL!"); - } - - unsigned int touch_input = 0; - int res = ecore_x_window_prop_card32_get(inputWindow, - ecore_x_atom_get(E_PROP_TOUCH_INPUT), &touch_input, 1); - - utils->log("E_PROP_TOUCH_INPUT : %d %d\n", res, touch_input); - - if (1 == res) { - if (1 == touch_input) { - adjustment->enable_touch_offset(TRUE); - } else if (0 == touch_input) { - adjustment->enable_touch_offset(FALSE); - } - } -#endif - sclboolean is_scl_window = FALSE; -#ifdef WAYLAND - sclboolean is_magnifier_window = FALSE; - wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(windows->get_base_window())); - wl_magnifier_window = (Ecore_Wl2_Window*)(elm_win_wl_window_get(static_cast(windows->get_magnifier_window()))); - if (wl_base_window && (unsigned int)ecore_wl2_window_id_get(wl_base_window) == ev->window) { - is_scl_window = TRUE; - } else if (wl_magnifier_window && (unsigned int)ecore_wl2_window_id_get(wl_magnifier_window) == ev->window) { - is_scl_window = TRUE; - is_magnifier_window = TRUE; -#else - if (elm_win_xwindow_get(static_cast(windows->get_base_window())) == ev->window) { - is_scl_window = TRUE; - } else if (elm_win_xwindow_get(static_cast(windows->get_magnifier_window())) == ev->window) { - is_scl_window = TRUE; -#endif - } else { - do { - window = windows->get_nth_window_in_Z_order_list(index); - SclWindowContext *window_context = windows->get_window_context(window); - if (window_context) { - if (window_context->is_virtual) { - is_scl_window = TRUE; -#ifdef WAYLAND - } else if ((wl_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(window)))) { - if ((unsigned int)ecore_wl2_window_id_get(wl_window) == ev->window) - is_scl_window = TRUE; -#else - } else if (elm_win_xwindow_get(static_cast(window)) == ev->window) { - is_scl_window = TRUE; -#endif - } - } - index++; - } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID); - index = 0; - } - if (!is_scl_window) return TRUE; - - SclRectangle rect = {0, 0, 0, 0}; - do { - window = windows->get_nth_window_in_Z_order_list(index); - if (window) { - // Update the position of the target window - //windows->get_window_context(window, TRUE); - SclWindowContext *window_context = windows->get_window_context(window); - if (window_context) { - windows->get_window_rect(window, &(window_context->geometry)); - if (get_window_rect(window, &rect)) { -#ifdef WAYLAND - int root_x = 0; - int root_y = 0; - if (is_magnifier_window) { - SclRectangle magnifier_rect = { 0, 0, 0, 0 }; - if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) { - root_x = ev->x + magnifier_rect.x; - root_y = ev->y + magnifier_rect.y; - } - } else { - root_x = ev->x + rect.x; - root_y = ev->y + rect.y; - } - if (window_context->is_virtual) { - apply_virtual_offset(rect, &root_x, &root_y); - } -#else - int root_x = ev->root.x; - int root_y = ev->root.y; -#endif - int adjust_x = root_x; - int adjust_y = root_y; - - SclResParserManager *sclres_manager = SclResParserManager::get_instance(); - PSclDefaultConfigure default_configure = NULL; - if (sclres_manager) { - default_configure = sclres_manager->get_default_configure(); - } - - if (default_configure) { - SCLDisplayMode display_mode = context->get_display_mode(); - if (scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) { - adjustment->apply_touch_offset( - default_configure->touch_offset_level[display_mode], - &adjust_x, &adjust_y); - } - } - - sclint win_width = rect.width; - sclint win_height = rect.height; - if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) { - rect.height = win_width; - rect.width = win_height; - } - - /* Check whether will-be-adjusted coordinate is within the window area */ - sclboolean process_event = FALSE; - if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) && - (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) { - process_event = TRUE; - } - if (process_event) { - /* Now convert the global coordinate to appropriate local coordinate */ - SclPoint coords = get_rotated_local_coords( - root_x, root_y, context->get_rotation(), &rect); - controller->mouse_press(window, coords.x, coords.y, ev->multi.device); - mouse_pressed = TRUE; - processed = TRUE; - pressed_window = window; - } - } - } - } - index++; - } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed); - - if (!processed) { - window = pressed_window; - SclWindowContext *window_context = windows->get_window_context(window); - if (window_context && get_window_rect(window, &rect)) { - if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) { - sclint temp = rect.width; - rect.width = rect.height; - rect.height = temp; - } - - // Now convert the global coordinate to appropriate local coordinate -#ifdef WAYLAND - int root_x = ev->x + rect.x; - int root_y = ev->y + rect.y; - if (window_context->is_virtual) { - apply_virtual_offset(rect, &root_x, &root_y); - } -#else - int root_x = ev->root.x; - int root_y = ev->root.y; -#endif - - SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect); - controller->mouse_press(window, coords.x, coords.y, ev->multi.device); - mouse_pressed = TRUE; - processed = TRUE; - } - } - } - - return TRUE; - - /*CSCLContext *context = CSCLContext::get_instance(); - controller->mouse_press((sclwindow)data, ev->output.x, ev->output.y); - mouse_pressed = TRUE;*/ - - //LOGD("=-=-=-=- mouse_press : %p %d %d\n", data, ev->output.x, ev->output.y); -} - -//void mouse_release (void *data, Evas *e, Evas_Object *object, void *event_info) -static Eina_Bool mouse_release(void *data, int type, void *event_info) -{ - SCL_DEBUG(); - - CSCLController *controller = CSCLController::get_instance(); - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLContext *context = CSCLContext::get_instance(); - - //Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up*)event_info; - Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info; - - //if (!mouse_pressed) return FALSE; - if (ev && check_timestamp_outdated(ev->timestamp)) { - return TRUE; - } - - if (controller && windows && context && ev) { - LOGD("mouse_release : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y); - - sclbyte index = 0; - sclboolean processed = FALSE; - sclwindow window = SCLWINDOW_INVALID; - SclRectangle rect; - sclboolean dimwinevent = FALSE; - SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window()); - if (dim_window_context) { - if (!(dim_window_context->is_virtual)) { - if (elm_win_xwindow_get(static_cast(windows->get_dim_window())) == ev->window) { - dimwinevent = TRUE; - } - } - } - if (dimwinevent) { - controller->mouse_press(windows->get_dim_window(), ev->root.x, ev->root.y, ev->multi.device); - } else { - do { - window = windows->get_nth_window_in_Z_order_list(index); - if (window) { - SclWindowContext *window_context = windows->get_window_context(window); - if (window_context) { - windows->get_window_rect(window, &(window_context->geometry)); - if (get_window_rect(window, &rect)) { -#ifdef WAYLAND - int root_x = 0; - int root_y = 0; - Ecore_Wl2_Window *wl_magnifier_window = - (Ecore_Wl2_Window*)(elm_win_wl_window_get(static_cast(windows->get_magnifier_window()))); - if (wl_magnifier_window && - (unsigned int)ecore_wl2_window_id_get(wl_magnifier_window) == ev->window) { - SclRectangle magnifier_rect = { 0, 0, 0, 0 }; - if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) { - root_x = ev->x + magnifier_rect.x; - root_y = ev->y + magnifier_rect.y; - } - } else { - root_x = ev->x + rect.x; - root_y = ev->y + rect.y; - } - if (window_context->is_virtual) { - apply_virtual_offset(rect, &root_x, &root_y); - } -#else - int root_x = ev->root.x; - int root_y = ev->root.y; -#endif - int adjust_x = root_x; - int adjust_y = root_y; - - SclResParserManager *sclres_manager = SclResParserManager::get_instance(); - PSclDefaultConfigure default_configure = NULL; - if (sclres_manager) { - default_configure = sclres_manager->get_default_configure(); - } - - if (default_configure) { - SCLDisplayMode display_mode = context->get_display_mode(); - CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance(); - if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) { - adjustment->apply_touch_offset( - default_configure->touch_offset_level[display_mode], - &adjust_x, &adjust_y); - } - } - - sclint win_width = rect.width; - sclint win_height = rect.height; - if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) { - rect.height = win_width; - rect.width = win_height; - } - - /* Check whether will-be-adjusted coordinate is within the window area */ - sclboolean process_event = FALSE; - if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) && - (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) { - process_event = TRUE; - } - if (process_event) { - /* Now convert the global coordinate to appropriate local coordinate */ - SclPoint coords = get_rotated_local_coords( - root_x, root_y, context->get_rotation(), &rect); - controller->mouse_release(window, coords.x, coords.y, ev->multi.device); - processed = TRUE; - } - } - } - } - index++; - } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed); - } - - if (!processed) { - window = pressed_window; - SclWindowContext *window_context = windows->get_window_context(window); - if (window_context && get_window_rect(window, &rect)) { - if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) { - sclint temp = rect.width; - rect.width = rect.height; - rect.height = temp; - } - - /* Now convert the global coordinate to appropriate local coordinate */ -#ifdef WAYLAND - int root_x = ev->x + rect.x; - int root_y = ev->y + rect.y; - if (window_context->is_virtual) { - apply_virtual_offset(rect, &root_x, &root_y); - } -#else - int root_x = ev->root.x; - int root_y = ev->root.y; -#endif - - SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect); - controller->mouse_release(window, coords.x, coords.y, ev->multi.device); - processed = TRUE; - } - } - - mouse_pressed = FALSE; - } - - return TRUE; - //CSCLController *controller = CSCLController::get_instance(); - //CSCLWindows *windows = CSCLWindows::get_instance(); - //controller->mouse_release((sclwindow)data, (int)ev->output.x, (int)ev->output.y); - //controller->mouse_release((sclwindow)data, (int)ev->x, (int)ev->y); -} - -#ifdef HANDLE_KEY_EVENTS -static Eina_Bool key_pressed(void *data, int type, void *event_info) -{ - LOGD("=-=-=-=- key_pressed \n"); - CSCLController *controller = CSCLController::get_instance(); - Ecore_Event_Key *ev = (Ecore_Event_Key *)event_info; - const char *ckey_val = ev->key; - LOGD("=-=-=-=- ev->key(char) = %c \n", ev->key); - LOGD("=-=-=-=- ev->key(string) = %s \n", ev->key); - LOGD("=-=-=-=- ev->keyname(char) = %c \n", ev->keyname); - LOGD("=-=-=-=- ev->keyname(string) = %s \n", ev->keyname); - LOGD("=-=-=-=- ev->string(char) = %c \n", ev->string); - LOGD("=-=-=-=- ev->string(string) = %s \n", ev->string); - - CSCLResourceCache *cache = CSCLResourceCache::get_instance(); - SclButtonContext *prev_button_context = NULL; - const SclLayoutKeyCoordinate *prevcoordinate = NULL; - SclButtonContext *button_context = NULL; - const SclLayoutKeyCoordinate *coordinate = NULL; - - CSCLWindows *windows = CSCLWindows::get_instance(); - sclwindow window = windows->get_base_window(); - CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance(); - - sclbyte current_key_index = focus_handler->get_current_key_index(); - sclbyte key_index = current_key_index; - - if (strcmp(ev->keyname, "Right") == 0) { - key_index = focus_handler->get_next_key_index(NAVIGATE_RIGHT); - } else if (strcmp(ev->keyname, "Left") == 0) { - key_index = focus_handler->get_next_key_index(NAVIGATE_LEFT); - } else if (strcmp(ev->keyname, "Up") == 0) { - key_index = focus_handler->get_next_key_index(NAVIGATE_UP); - } else if (strcmp(ev->keyname, "Down") == 0) { - key_index = focus_handler->get_next_key_index(NAVIGATE_DOWN); - } else if ((strcmp(ev->keyname, "Return") == 0) || (strcmp(ev->keyname, "Enter") == 0)) { - button_context = cache->get_cur_button_context(window, current_key_index); - coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index); - button_context->state = BUTTON_STATE_NORMAL; - controller->mouse_press(window, coordinate->x, coordinate->y, TRUE); - controller->mouse_release(window, coordinate->x, coordinate->y, TRUE); - if (KEY_TYPE_MODECHANGE != coordinate->key_type) { - button_context->state = BUTTON_STATE_PRESSED; - windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height); - } else { - focus_handler->init_key_index(); - } - return TRUE; - } - - if (current_key_index != key_index) { - button_context = cache->get_cur_button_context(window, key_index); - prev_button_context = cache->get_cur_button_context(window, current_key_index); - prevcoordinate = cache->get_cur_layout_key_coordinate(window, current_key_index); - coordinate = cache->get_cur_layout_key_coordinate(window, key_index); - prev_button_context->state = BUTTON_STATE_NORMAL; - button_context->state = BUTTON_STATE_PRESSED; - sclshort x, y, width, height; - if (prevcoordinate->x < coordinate->x) { - x = prevcoordinate->x; - } else { - x = coordinate->x; - } - - if (prevcoordinate->y < coordinate->y) { - y = prevcoordinate->y; - } else { - y = coordinate->y; - } - - if (prevcoordinate->x + prevcoordinate->width > coordinate->x + coordinate->width) { - width = prevcoordinate->x + prevcoordinate->width - x; - } else { - width = coordinate->x + coordinate->width - x; - } - - if (prevcoordinate->y + prevcoordinate->height > coordinate->y + coordinate->height) { - height = prevcoordinate->y + prevcoordinate->height - y; - } else { - height = coordinate->y + coordinate->height - y; - } - windows->update_window(window, x, y, width, height); - - } else { - } - - return TRUE; -} -#endif /*HANDLE_KEY_EVENTS*/ - -//int mouse_move (void *data, Evas *e, Evas_Object *object, void *event_info) -static Eina_Bool mouse_move(void *data, int type, void *event_info) -{ - SCL_DEBUG(); - - CSCLController *controller = CSCLController::get_instance(); - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLContext *context = CSCLContext::get_instance(); - CSCLResourceCache *cache = CSCLResourceCache::get_instance(); - - //Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move*)event_info; - Ecore_Event_Mouse_Move *ev = (Ecore_Event_Mouse_Move*)event_info; - - //if (!mouse_pressed) return FALSE; - if (ev && check_timestamp_outdated(ev->timestamp)) { - return TRUE; - } - - if (controller && windows && context && cache && ev) { - sclbyte index = 0; - sclboolean processed = FALSE; - sclwindow window = SCLWINDOW_INVALID; - SclRectangle rect; - - LOGD("mouse_move : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y); - - if (context->get_cur_pressed_window(ev->multi.device) != SCLWINDOW_INVALID && - get_window_rect(context->get_cur_pressed_window(ev->multi.device), &rect)) { - sclint winwidth = rect.width; - sclint winheight = rect.height; - if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) { - rect.height = winwidth; - rect.width = winheight; - } -#ifdef WAYLAND - int root_x = 0; - int root_y = 0; - - Ecore_Wl2_Window *wl_base_window = - (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(windows->get_base_window())); - Ecore_Wl2_Window *wl_magnifier_window = - (Ecore_Wl2_Window*)(elm_win_wl_window_get(static_cast(windows->get_magnifier_window()))); - if (wl_base_window && (unsigned int)ecore_wl2_window_id_get(wl_base_window) == ev->window) { - SclRectangle base_rect; - if (get_window_rect(windows->get_base_window(), &base_rect)) { - root_x = ev->x + base_rect.x; - root_y = ev->y + base_rect.y; - } - } else if (wl_magnifier_window && (unsigned int)ecore_wl2_window_id_get(wl_magnifier_window) == ev->window) { - SclRectangle magnifier_rect = { 0, 0, 0, 0 }; - if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) { - root_x = ev->x + magnifier_rect.x; - root_y = ev->y + magnifier_rect.y; - } - } else { - root_x = ev->x + rect.x; - root_y = ev->y + rect.y; - } -#else - int root_x = ev->root.x; - int root_y = ev->root.y; -#endif - - SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect); - - controller->mouse_move(context->get_cur_pressed_window(ev->multi.device), coords.x, coords.y, ev->multi.device); - processed = TRUE; - } else { - do { - window = windows->get_nth_window_in_Z_order_list(index); - if (window) { - SclWindowContext *window_context = windows->get_window_context(window); - if (window_context) { - windows->get_window_rect(window, &(window_context->geometry)); - if (get_window_rect(window, &rect)) { -#ifdef WAYLAND - int root_x = ev->x + rect.x; - int root_y = ev->y + rect.y; - if (window_context->is_virtual) { - apply_virtual_offset(rect, &root_x, &root_y); - } -#else - int root_x = ev->root.x; - int root_y = ev->root.y; -#endif - int adjust_x = root_x; - int adjust_y = root_y; - - SclResParserManager *sclres_manager = SclResParserManager::get_instance(); - PSclDefaultConfigure default_configure = NULL; - if (sclres_manager) { - default_configure = sclres_manager->get_default_configure(); - } - if (default_configure) { - SCLDisplayMode display_mode = context->get_display_mode(); - CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance(); - if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) { - adjustment->apply_touch_offset( - default_configure->touch_offset_level[display_mode], - &adjust_x, &adjust_y); - } - } - - sclint win_width = rect.width; - sclint win_height = rect.height; - if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) { - rect.height = win_width; - rect.width = win_height; - } - - sclboolean process_event = FALSE; - if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) && - (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) { - process_event = TRUE; - } - /* Process this event regardless of the coordinate if the top window has the POPUP_GRAB layout style */ - if (index == SCL_WINDOW_Z_TOP) { - const SclLayout *layout = cache->get_cur_layout(window); - if (layout) { - if (layout->style == LAYOUT_STYLE_POPUP_GRAB) { - process_event = TRUE; - } - } - } - if (process_event) { - /* Now convert the global coordinate to appropriate local coordinate */ - SclPoint coords = get_rotated_local_coords( - root_x, root_y, context->get_rotation(), &rect); - controller->mouse_move(window, coords.x, coords.y, ev->multi.device); - processed = TRUE; - } - } - } - } - index++; - } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed); - } - - if (!processed) { - window = pressed_window; - SclWindowContext *window_context = windows->get_window_context(window); - if (window_context && get_window_rect(window, &rect)) { - /* Now convert the global coordinate to appropriate local coordinate */ -#ifdef WAYLAND - int root_x = ev->x + rect.x; - int root_y = ev->y + rect.y; - if (window_context->is_virtual) { - apply_virtual_offset(rect, &root_x, &root_y); - } -#else - int root_x = ev->root.x; - int root_y = ev->root.y; -#endif - - SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect); - controller->mouse_move(window, coords.x, coords.y, ev->multi.device); - processed = TRUE; - } - } - } - //CSCLController *controller = CSCLController::get_instance(); - //CSCLWindows *windows = CSCLWindows::get_instance(); - //controller->mouse_move((sclwindow)data, (int)ev->cur.output.x, (int)ev->cur.output.y); - //controller->mouse_move((sclwindow)data, (int)ev->x, (int)ev->y); - - return TRUE; -} - -/** - * Registers a event callback func to given window. - * In this function, it should call several event functions of CSCLController class whenever an event has occurred - * The below list shows what event function should be called. - * - mouse_press (when the user presses mouse button) - * - mouse_release (when the user releases mouse button) - * - mouse_move (when the user drags mouse button) - * - show_base_layout (when the expost event has occurred) - */ -void -CSCLEventsImplEfl::connect_window_events(const sclwindow wnd, const sclint evt) -{ - SCL_DEBUG(); - - //evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, NULL); - /*evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_UP, mouse_release, NULL); - evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, NULL);*/ -} - -#ifndef WAYLAND -static Eina_Bool -client_message_cb(void *data, int type, void *event) -{ - Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *)event; - if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL) { - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLController *controller = CSCLController::get_instance(); - - static int last_pos_x = -10000; - static int last_pos_y = -10000; - - if (windows && controller) { - Evas_Object *base_win = (Evas_Object *)windows->get_base_window(); - if (base_win == NULL) return FALSE; - - if ((unsigned int)ev->data.l[0] == elm_win_xwindow_get(base_win)) { - if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE) { - // 1 finger double tap - controller->mouse_press(base_win, last_pos_x, last_pos_y); - controller->mouse_release(base_win, last_pos_x, last_pos_y); - } else if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ) { - // 1 finger tap - // 1 finger touch & move - last_pos_x = ev->data.l[2]; - last_pos_y = ev->data.l[3]; - controller->mouse_over(base_win, last_pos_x, last_pos_y); - } - } - } - } - return ECORE_CALLBACK_PASS_ON; -} -#endif - -Eina_Bool timer_event(void *data) -{ - SCL_DEBUG(); - CSCLUtils *utils = CSCLUtils::get_instance(); - CSCLController *controller = CSCLController::get_instance(); - - scl32 sendData = static_cast(reinterpret_cast(data) & 0xffffffff); - - if (controller && utils) { - scl16 id = SCL_LOWORD(sendData); /* Timer ID */ - Eina_Bool ret = controller->timer_event(sendData); - if (!ret) { - utils->log("Returning Timer : %d %d\n", id, ret); - } - return ret; - } - return TRUE; -} - -/** - * Creates a timer - * In this function, it should call timer_event of CSCLController class - */ -void -CSCLEventsImplEfl::create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap) -{ - SCL_DEBUG(); - sclint data = SCL_MAKELONG(id, value); - Ecore_Timer *pTimer = ecore_timer_add((double)interval / 1000.0, timer_event, (void*)(uintptr_t)data); - if (pTimer) { - CSCLUtils *utils = CSCLUtils::get_instance(); - if (utils) { - utils->log("Created Timer : %d %p\n", id, pTimer); - } - if (addToMap) { - idMap[id] = pTimer; - } - } -} - -/** - * Destroys the given ID's timer - */ -void -CSCLEventsImplEfl::destroy_timer(const scl32 id) -{ - SCL_DEBUG(); - //for ( std::map::iterator idx = idMap.begin(); idx != idMap.end(); ++idx) { - std::map::iterator idx = idMap.find(id); - //if ((*idx).first == id) { - if (idx != idMap.end()) { - CSCLUtils *utils = CSCLUtils::get_instance(); - if (utils) { - utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second); - } - ecore_timer_del((*idx).second); - idMap.erase((*idx).first); - //break; - } - //} -} - -/** - * Destroys all of created timer - */ -void -CSCLEventsImplEfl::destroy_all_timer() -{ - SCL_DEBUG(); - for ( std::map::iterator idx = idMap.begin(); idx != idMap.end(); ++idx ) { - ecore_timer_del((*idx).second); - - CSCLUtils *utils = CSCLUtils::get_instance(); - if (utils) { - utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second); - } - } - idMap.clear(); -} - -void -CSCLEventsImplEfl::generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y) -{ - CSCLWindows *windows = CSCLWindows::get_instance(); - SclWindowContext *window_context = NULL; - - static const sclint MAX_DEVICES = 100; - static sclboolean pressed[MAX_DEVICES] = { FALSE }; - if (windows) { - switch (type) { - case SCL_MOUSE_EVENT_PRESS: - { - sclboolean generated = FALSE; - for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) { - if (pressed[loop] != TRUE) { - pressed[loop] = TRUE; - Ecore_Event_Mouse_Button evt; -#ifdef WAYLAND - Ecore_Wl2_Window *wl_base_window; - wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(windows->get_base_window())); - if (wl_base_window) - evt.window = (unsigned int)ecore_wl2_window_id_get(wl_base_window); -#else - evt.window = elm_win_xwindow_get(static_cast(windows->get_base_window())); -#endif - //window_context = windows->get_window_context(windows->get_base_window(), FALSE); - window_context = windows->get_window_context(windows->get_base_window()); - if (window_context) { - evt.x = evt.root.x = x + window_context->geometry.x; - evt.y = evt.root.y = y + window_context->geometry.y; - evt.multi.device = loop; - mouse_press(NULL, 0, &evt); - } - generated = TRUE; - } - } - } - break; - case SCL_MOUSE_EVENT_RELEASE: - { - sclboolean generated = FALSE; - for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) { - if (pressed[loop] == TRUE) { - pressed[loop] = FALSE; - Ecore_Event_Mouse_Button evt; -#ifdef WAYLAND - Ecore_Wl2_Window *wl_base_window; - wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(windows->get_base_window())); - if (wl_base_window) - evt.window = (unsigned int)ecore_wl2_window_id_get(wl_base_window); -#else - evt.window = elm_win_xwindow_get(static_cast(windows->get_base_window())); -#endif - //window_context = windows->get_window_context(windows->get_base_window(), FALSE); - window_context = windows->get_window_context(windows->get_base_window()); - if (window_context) { - evt.x = evt.root.x = x + window_context->geometry.x; - evt.y = evt.root.y = y + window_context->geometry.y; - evt.multi.device = loop; - mouse_release(NULL, 0, &evt); - } - generated = TRUE; - } - } - } - break; - case SCL_MOUSE_EVENT_MOVE: - { - sclboolean generated = FALSE; - for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) { - if (pressed[loop] == TRUE) { - Ecore_Event_Mouse_Move evt; -#ifdef WAYLAND - Ecore_Wl2_Window *wl_base_window; - wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(windows->get_base_window())); - if (wl_base_window) - evt.window = (unsigned int)ecore_wl2_window_id_get(wl_base_window); -#else - evt.window = elm_win_xwindow_get(static_cast(windows->get_base_window())); -#endif - //window_context = windows->get_window_context(windows->get_base_window(), FALSE); - window_context = windows->get_window_context(windows->get_base_window()); - if (window_context) { - evt.x = evt.root.x = x + window_context->geometry.x; - evt.y = evt.root.y = y + window_context->geometry.y; - evt.multi.device = loop; - mouse_move(NULL, 0, &evt); - } - generated = TRUE; - } - } - } - break; - default: - break; - } - } -} diff --git a/scl/sclevents-efl.h b/scl/sclevents-efl.h deleted file mode 100644 index 4bd7a2d..0000000 --- a/scl/sclevents-efl.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "sclevents.h" -#include -#include -#include - - -#ifndef __SCL_EVENTS_EFL_H__ -#define __SCL_EVENTS_EFL_H__ - -namespace scl -{ -class CSCLEventsImplEfl : public CSCLEventsImpl -{ -public : - CSCLEventsImplEfl(); - ~CSCLEventsImplEfl(); - - void init(); - void fini(); - - /* Implementation about interface functions */ - void connect_window_events(const sclwindow wnd, const sclint evt); - void create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap); - void destroy_timer(const scl32 id); - void destroy_all_timer(); - - void generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y); - -private: - std::map idMap; - - Ecore_Event_Handler *m_mouse_down_handler; - Ecore_Event_Handler *m_mouse_move_handler; - Ecore_Event_Handler *m_mouse_up_handler; - Ecore_Event_Handler *m_key_pressed_handler; - -#ifndef WAYLAND - Ecore_Event_Handler *m_xclient_msg_handler; -#endif -}; -} /* End of scl namespace */ -#endif diff --git a/scl/sclevents-nui.cpp b/scl/sclevents-nui.cpp new file mode 100644 index 0000000..5b4427e --- /dev/null +++ b/scl/sclevents-nui.cpp @@ -0,0 +1,1249 @@ +/* + * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sclevents-nui.h" +#include "scldebug.h" +#include "sclcontroller.h" +#include "sclgraphics.h" +#include "scluibuilder.h" +#include "sclerroradjustment.h" +#include "sclresource.h" +#include "sclresourcecache.h" +#include "sclres_manager.h" + +#include +#include +#include +#ifdef WAYLAND +#define EFL_BETA_API_SUPPORT +#include +#else +#include +#endif + +#include "sclkeyfocushandler.h" + +using namespace scl; + +#ifdef USING_KEY_GRAB +#define HANDLE_KEY_EVENTS +#endif + +#define E_PROP_TOUCH_INPUT "X_TouchInput" + +#ifdef WAYLAND +#define E_KEYBOARD_SERVICE_BUS_NAME "org.tizen.keyboard" +#define E_KEYBOARD_SERVICE_NAVI_IFC_NAME "org.tizen.KBGestureNavigation" +#define E_KEYBOARD_SERVICE_NAVI_OBJ_PATH "/org/tizen/KBGestureNavigation" +static Eldbus_Connection *eldbus_conn = NULL; +static Eldbus_Object *eldbus_bus_obj = NULL; + +typedef enum _Gesture { + ONE_FINGER_HOVER = 0, + ONE_FINGER_SINGLE_TAP = 15, + ONE_FINGER_DOUBLE_TAP = 16 +} Gesture; + +typedef struct +{ + Gesture type; // Type of recognized gesture + int x; + int y; +} Gesture_Info; +#endif + +static sclboolean mouse_pressed = FALSE; /* Checks whether mouse is pressed or not */ +static sclwindow pressed_window = SCLWINDOW_INVALID; + +/* If the gap between two timestamps are bigger than 1 sec, do not compare */ +const unsigned int _touch_event_timestamp_compare_range = 1000; +/* If the gap between two timestamps are smaller than 50 msec, do not process */ +const unsigned int _touch_event_timestamp_valid_threshold = 50; +extern unsigned int g_timestamp_last_base_window_resized; + +#define MIN_XY_DIFF 14 + +static Eina_Bool mouse_press(void *data, int type, void *event_info); +static Eina_Bool mouse_move(void *data, int type, void *event_info); +static Eina_Bool mouse_release(void *data, int type, void *event_info); + +#ifndef WAYLAND +static Eina_Bool client_message_cb(void *data, int type, void *event); +#endif + +#ifdef HANDLE_KEY_EVENTS +static Eina_Bool key_pressed(void *data, int type, void *event_info); +#endif + +static sclboolean get_window_rect(const sclwindow window, SclRectangle *rect) +{ + SCL_DEBUG(); + sclboolean ret = FALSE; + CSCLUtils *utils = CSCLUtils::get_instance(); + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLContext *context = CSCLContext::get_instance(); + if (windows && context && utils && rect) { + SclWindowContext *window_context = windows->get_window_context(window); + sclint scr_w, scr_h; + /* get window size */ + if (window_context && utils->get_screen_resolution(&scr_w, &scr_h)) { + switch (context->get_rotation()) { + case ROTATION_90_CW: + { + rect->height = window_context->geometry.width; + rect->width = window_context->geometry.height; + rect->y = scr_w - rect->height - window_context->geometry.x; + rect->x = window_context->geometry.y; + } + break; + case ROTATION_180: + { + rect->width = window_context->geometry.width; + rect->height = window_context->geometry.height; + rect->x = scr_w - window_context->geometry.x - rect->width; + rect->y = scr_h - window_context->geometry.y - rect->height; + } + break; + case ROTATION_90_CCW: + { + rect->height = window_context->geometry.width; + rect->width = window_context->geometry.height; + rect->y = window_context->geometry.x; + rect->x = scr_h - window_context->geometry.y - rect->width; + } + break; + default: + { + rect->x = window_context->geometry.x; + rect->y = window_context->geometry.y; + rect->width = window_context->geometry.width; + rect->height = window_context->geometry.height; + } + break; + } + ret = TRUE; + } else { + rect->x = rect->y = rect->width = rect->height = 0; + } + } + return ret; +} + +#ifdef WAYLAND +/* In wayland, root.x / root.y is not available, so need to apply virtual offset + when event occurred on a virtual window */ +static void apply_virtual_offset(SclRectangle rect, int *adjustx, int *adjusty) +{ + int virtual_offset_x = 0; + int virtual_offset_y = 0; + SclRectangle base_rect = {0, 0, 0, 0}; + + CSCLWindows *windows = CSCLWindows::get_instance(); + if (windows) { + if (get_window_rect(windows->get_base_window(), &base_rect)) { + virtual_offset_x = rect.x - base_rect.x; + virtual_offset_y = rect.y - base_rect.y; + } + if (adjustx && adjusty) { + *adjustx -= virtual_offset_x; + *adjusty -= virtual_offset_y; + } + } +} +#endif + +/** + * Constructor + */ +CSCLEventsImplNui::CSCLEventsImplNui() +{ + SCL_DEBUG(); + + m_mouse_down_handler = NULL; + m_mouse_move_handler = NULL; + m_mouse_up_handler = NULL; + +#ifndef WAYLAND + m_xclient_msg_handler = NULL; +#endif + m_key_pressed_handler = NULL; +} + +#ifdef WAYLAND +static void gesture_cb(void *data, const Eldbus_Message *msg) +{ + LOGD("GestureDetected callback"); + int g_type; + static int last_pos_x = -1; + static int last_pos_y = -1; + + if (!msg) { + LOGD("Incoming message is empty"); + return; + } + CSCLController *controller = CSCLController::get_instance(); + CSCLWindows *windows = CSCLWindows::get_instance(); + + if (!windows || !controller) return; + + sclwindow base_window = windows->get_base_window(); + SclWindowContext *window_context = windows->get_window_context(base_window); + + if (!window_context) return; + if (window_context->hidden) return; + + LOGD("window_context->geometry.x=%d y=%d w=%d h=%d", + window_context->geometry.x, window_context->geometry.y, + window_context->geometry.width, window_context->geometry.height); + + Gesture_Info *info = (Gesture_Info *)calloc(sizeof(Gesture_Info), 1); + if (!info) { + LOGD("Memory alloc failed for Gesture_Info"); + return; + } + if (!eldbus_message_arguments_get(msg, "iii", &g_type, &info->x, + &info->y)) { + LOGD("Getting message arguments failed"); + free(info); + return; + } + + info->type = (Gesture)g_type; + LOGD("Incoming gesture name is %d : %d %d", info->type, info->x, info->y); + + if (info->type == ONE_FINGER_HOVER || info->type == ONE_FINGER_SINGLE_TAP) { + if (info->y >= window_context->geometry.y) { + last_pos_x = info->x; + last_pos_y = info->y - window_context->geometry.y; + LOGD("hover last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y); + controller->mouse_over(base_window, last_pos_x, last_pos_y); + } + } else if (info->type == ONE_FINGER_DOUBLE_TAP) { + if (info->y >= window_context->geometry.y) { + last_pos_x = info->x; + last_pos_y = info->y - window_context->geometry.y; + LOGD("double last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y); + controller->mouse_press(base_window, last_pos_x, last_pos_y); + controller->mouse_release(base_window, last_pos_x, last_pos_y); + } + } + free(info); +} + +static void gestures_tracker_register() +{ + Eldbus_Proxy *proxy = NULL; + + if (eldbus_conn) + return; + + eldbus_init(); + LOGD("Registering callback for GestureDetected signal"); + if (!(eldbus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION))) { + LOGW("Error: Unable to get session bus"); + return; + } + + eldbus_bus_obj = eldbus_object_get(eldbus_conn, E_KEYBOARD_SERVICE_BUS_NAME, E_KEYBOARD_SERVICE_NAVI_OBJ_PATH); + if (!eldbus_bus_obj) { + LOGW("Error: Getting object failed"); + goto obj_err; + } + + proxy = eldbus_proxy_get(eldbus_bus_obj, E_KEYBOARD_SERVICE_NAVI_IFC_NAME); + if (!proxy) { + LOGW("Error: Getting proxy failed"); + goto proxy_err; + } + + if (!eldbus_proxy_signal_handler_add(proxy, "KBGestureDetected", gesture_cb, NULL)) + LOGW("No signal handler returned"); + + LOGD("Callback registration successful"); + return; + +proxy_err: + eldbus_object_unref(eldbus_bus_obj); + eldbus_bus_obj = NULL; +obj_err: + eldbus_connection_unref(eldbus_conn); + eldbus_conn = NULL; +} + +static void gestures_tracker_unregister() +{ + if (eldbus_bus_obj) { + eldbus_object_unref(eldbus_bus_obj); + eldbus_bus_obj = NULL; + } + + if (eldbus_conn) { + eldbus_connection_unref(eldbus_conn); + eldbus_conn = NULL; + + eldbus_shutdown(); + } +} +#endif +/** + * De-constructor + */ +CSCLEventsImplNui::~CSCLEventsImplNui() +{ + SCL_DEBUG(); + + fini(); +} + +void CSCLEventsImplNui::init() +{ + /* Initializes all window resources */ + m_mouse_down_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, mouse_press, NULL); + m_mouse_move_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, mouse_move, NULL); + m_mouse_up_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, mouse_release, NULL); + +#ifndef WAYLAND + m_xclient_msg_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, client_message_cb, NULL); +#else + gestures_tracker_register(); +#endif + +#ifdef HANDLE_KEY_EVENTS + m_key_pressed_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, key_pressed, NULL); +#endif +} + +void CSCLEventsImplNui::fini() +{ + if (m_mouse_down_handler) ecore_event_handler_del(m_mouse_down_handler); + m_mouse_down_handler = NULL; + if (m_mouse_move_handler) ecore_event_handler_del(m_mouse_move_handler); + m_mouse_move_handler = NULL; + if (m_mouse_up_handler) ecore_event_handler_del(m_mouse_up_handler); + m_mouse_up_handler = NULL; +#ifdef HANDLE_KEY_EVENTS + if (m_key_pressed_handler) ecore_event_handler_del(m_key_pressed_handler); +#endif + m_key_pressed_handler = NULL; +#ifndef WAYLAND + if (m_xclient_msg_handler) ecore_event_handler_del(m_xclient_msg_handler); +#else + gestures_tracker_unregister(); +#endif +} + +/** Here x and y contains "actual" x and y position relative to portrait root window, + and window_context->width,height contains the window's orientation dependant width and height */ +SclPoint get_rotated_local_coords(sclint x, sclint y, SCLRotation rotation, SclRectangle *rect) { + SclPoint ret = {0, 0}; + + if (rect) { + switch (rotation) { + case ROTATION_90_CW: + { + ret.x = (rect->y + rect->width) - y; + ret.y = x - rect->x; + } + break; + case ROTATION_180: + { + ret.x = (rect->x + rect->width) - x; + ret.y = (rect->y + rect->height) - y; + } + break; + case ROTATION_90_CCW: + { + ret.x = y - rect->y; + ret.y = (rect->x + rect->height) - x; + } + break; + default: + { + ret.x = x - rect->x; + ret.y = y - rect->y; + } + break; + } + } + return ret; +} + +static Eina_Bool check_timestamp_outdated(unsigned int timestamp) +{ + /* Skip events that were generated nearly at the same time when our base window resized */ + timestamp -= _touch_event_timestamp_valid_threshold; + unsigned int gap = (g_timestamp_last_base_window_resized > timestamp) ? + (g_timestamp_last_base_window_resized - timestamp) : + (timestamp - g_timestamp_last_base_window_resized); + if (gap < _touch_event_timestamp_compare_range) { + if (g_timestamp_last_base_window_resized > timestamp) { + /* This event was generated before the base window resize event, ignore */ + LOGD("Skipping event since turned out to be outdated : %u, %u", + g_timestamp_last_base_window_resized, timestamp); + return EINA_TRUE; + } + } + return EINA_FALSE; +} + +//void mouse_press (void *data, Evas *e, Evas_Object *object, void *event_info) +static Eina_Bool mouse_press(void *data, int type, void *event_info) +{ + SCL_DEBUG(); +#ifdef WAYLAND + Ecore_Wl2_Window *wl_base_window; + Ecore_Wl2_Window *wl_magnifier_window; + Ecore_Wl2_Window *wl_window; +#endif + + CSCLController *controller = CSCLController::get_instance(); + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLContext *context = CSCLContext::get_instance(); + CSCLUtils *utils = CSCLUtils::get_instance(); + CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance(); + + Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info; + + if (ev && check_timestamp_outdated(ev->timestamp)) { + return TRUE; + } + + if (controller && windows && context && utils && adjustment && ev) { + LOGD("mouse_press : %d %d, %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y, + g_timestamp_last_base_window_resized, ev->timestamp); + + sclbyte index = 0; + sclboolean processed = FALSE; + sclwindow window = SCLWINDOW_INVALID; + +#ifndef WAYLAND + Ecore_X_Window inputWindow = 0; + Ecore_X_Atom inputAtom = ecore_x_atom_get("DeviceMgr Input Window"); + ecore_x_window_prop_xid_get(ecore_x_window_root_first_get(), + inputAtom, ECORE_X_ATOM_WINDOW, &inputWindow, 1); + if (inputWindow == 0) { + utils->log("Error : input window NULL!"); + } + + unsigned int touch_input = 0; + int res = ecore_x_window_prop_card32_get(inputWindow, + ecore_x_atom_get(E_PROP_TOUCH_INPUT), &touch_input, 1); + + utils->log("E_PROP_TOUCH_INPUT : %d %d\n", res, touch_input); + + if (1 == res) { + if (1 == touch_input) { + adjustment->enable_touch_offset(TRUE); + } else if (0 == touch_input) { + adjustment->enable_touch_offset(FALSE); + } + } +#endif + sclboolean is_scl_window = FALSE; +#ifdef WAYLAND + sclboolean is_magnifier_window = FALSE; + wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(windows->get_base_window())); + wl_magnifier_window = (Ecore_Wl2_Window*)(elm_win_wl_window_get(static_cast(windows->get_magnifier_window()))); + if (wl_base_window && (unsigned int)ecore_wl2_window_id_get(wl_base_window) == ev->window) { + is_scl_window = TRUE; + } else if (wl_magnifier_window && (unsigned int)ecore_wl2_window_id_get(wl_magnifier_window) == ev->window) { + is_scl_window = TRUE; + is_magnifier_window = TRUE; +#else + if (elm_win_xwindow_get(static_cast(windows->get_base_window())) == ev->window) { + is_scl_window = TRUE; + } else if (elm_win_xwindow_get(static_cast(windows->get_magnifier_window())) == ev->window) { + is_scl_window = TRUE; +#endif + } else { + do { + window = windows->get_nth_window_in_Z_order_list(index); + SclWindowContext *window_context = windows->get_window_context(window); + if (window_context) { + if (window_context->is_virtual) { + is_scl_window = TRUE; +#ifdef WAYLAND + } else if ((wl_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(window)))) { + if ((unsigned int)ecore_wl2_window_id_get(wl_window) == ev->window) + is_scl_window = TRUE; +#else + } else if (elm_win_xwindow_get(static_cast(window)) == ev->window) { + is_scl_window = TRUE; +#endif + } + } + index++; + } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID); + index = 0; + } + if (!is_scl_window) return TRUE; + + SclRectangle rect = {0, 0, 0, 0}; + do { + window = windows->get_nth_window_in_Z_order_list(index); + if (window) { + // Update the position of the target window + //windows->get_window_context(window, TRUE); + SclWindowContext *window_context = windows->get_window_context(window); + if (window_context) { + windows->get_window_rect(window, &(window_context->geometry)); + if (get_window_rect(window, &rect)) { +#ifdef WAYLAND + int root_x = 0; + int root_y = 0; + if (is_magnifier_window) { + SclRectangle magnifier_rect = { 0, 0, 0, 0 }; + if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) { + root_x = ev->x + magnifier_rect.x; + root_y = ev->y + magnifier_rect.y; + } + } else { + root_x = ev->x + rect.x; + root_y = ev->y + rect.y; + } + if (window_context->is_virtual) { + apply_virtual_offset(rect, &root_x, &root_y); + } +#else + int root_x = ev->root.x; + int root_y = ev->root.y; +#endif + int adjust_x = root_x; + int adjust_y = root_y; + + SclResParserManager *sclres_manager = SclResParserManager::get_instance(); + PSclDefaultConfigure default_configure = NULL; + if (sclres_manager) { + default_configure = sclres_manager->get_default_configure(); + } + + if (default_configure) { + SCLDisplayMode display_mode = context->get_display_mode(); + if (scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) { + adjustment->apply_touch_offset( + default_configure->touch_offset_level[display_mode], + &adjust_x, &adjust_y); + } + } + + sclint win_width = rect.width; + sclint win_height = rect.height; + if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) { + rect.height = win_width; + rect.width = win_height; + } + + /* Check whether will-be-adjusted coordinate is within the window area */ + sclboolean process_event = FALSE; + if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) && + (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) { + process_event = TRUE; + } + if (process_event) { + /* Now convert the global coordinate to appropriate local coordinate */ + SclPoint coords = get_rotated_local_coords( + root_x, root_y, context->get_rotation(), &rect); + controller->mouse_press(window, coords.x, coords.y, ev->multi.device); + mouse_pressed = TRUE; + processed = TRUE; + pressed_window = window; + } + } + } + } + index++; + } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed); + + if (!processed) { + window = pressed_window; + SclWindowContext *window_context = windows->get_window_context(window); + if (window_context && get_window_rect(window, &rect)) { + if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) { + sclint temp = rect.width; + rect.width = rect.height; + rect.height = temp; + } + + // Now convert the global coordinate to appropriate local coordinate +#ifdef WAYLAND + int root_x = ev->x + rect.x; + int root_y = ev->y + rect.y; + if (window_context->is_virtual) { + apply_virtual_offset(rect, &root_x, &root_y); + } +#else + int root_x = ev->root.x; + int root_y = ev->root.y; +#endif + + SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect); + controller->mouse_press(window, coords.x, coords.y, ev->multi.device); + mouse_pressed = TRUE; + processed = TRUE; + } + } + } + + return TRUE; + + /*CSCLContext *context = CSCLContext::get_instance(); + controller->mouse_press((sclwindow)data, ev->output.x, ev->output.y); + mouse_pressed = TRUE;*/ + + //LOGD("=-=-=-=- mouse_press : %p %d %d\n", data, ev->output.x, ev->output.y); +} + +//void mouse_release (void *data, Evas *e, Evas_Object *object, void *event_info) +static Eina_Bool mouse_release(void *data, int type, void *event_info) +{ + SCL_DEBUG(); + + CSCLController *controller = CSCLController::get_instance(); + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLContext *context = CSCLContext::get_instance(); + + //Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up*)event_info; + Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button*)event_info; + + //if (!mouse_pressed) return FALSE; + if (ev && check_timestamp_outdated(ev->timestamp)) { + return TRUE; + } + + if (controller && windows && context && ev) { + LOGD("mouse_release : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y); + + sclbyte index = 0; + sclboolean processed = FALSE; + sclwindow window = SCLWINDOW_INVALID; + SclRectangle rect; + sclboolean dimwinevent = FALSE; + SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window()); + if (dim_window_context) { + if (!(dim_window_context->is_virtual)) { + if (elm_win_xwindow_get(static_cast(windows->get_dim_window())) == ev->window) { + dimwinevent = TRUE; + } + } + } + if (dimwinevent) { + controller->mouse_press(windows->get_dim_window(), ev->root.x, ev->root.y, ev->multi.device); + } else { + do { + window = windows->get_nth_window_in_Z_order_list(index); + if (window) { + SclWindowContext *window_context = windows->get_window_context(window); + if (window_context) { + windows->get_window_rect(window, &(window_context->geometry)); + if (get_window_rect(window, &rect)) { +#ifdef WAYLAND + int root_x = 0; + int root_y = 0; + Ecore_Wl2_Window *wl_magnifier_window = + (Ecore_Wl2_Window*)(elm_win_wl_window_get(static_cast(windows->get_magnifier_window()))); + if (wl_magnifier_window && + (unsigned int)ecore_wl2_window_id_get(wl_magnifier_window) == ev->window) { + SclRectangle magnifier_rect = { 0, 0, 0, 0 }; + if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) { + root_x = ev->x + magnifier_rect.x; + root_y = ev->y + magnifier_rect.y; + } + } else { + root_x = ev->x + rect.x; + root_y = ev->y + rect.y; + } + if (window_context->is_virtual) { + apply_virtual_offset(rect, &root_x, &root_y); + } +#else + int root_x = ev->root.x; + int root_y = ev->root.y; +#endif + int adjust_x = root_x; + int adjust_y = root_y; + + SclResParserManager *sclres_manager = SclResParserManager::get_instance(); + PSclDefaultConfigure default_configure = NULL; + if (sclres_manager) { + default_configure = sclres_manager->get_default_configure(); + } + + if (default_configure) { + SCLDisplayMode display_mode = context->get_display_mode(); + CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance(); + if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) { + adjustment->apply_touch_offset( + default_configure->touch_offset_level[display_mode], + &adjust_x, &adjust_y); + } + } + + sclint win_width = rect.width; + sclint win_height = rect.height; + if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) { + rect.height = win_width; + rect.width = win_height; + } + + /* Check whether will-be-adjusted coordinate is within the window area */ + sclboolean process_event = FALSE; + if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) && + (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) { + process_event = TRUE; + } + if (process_event) { + /* Now convert the global coordinate to appropriate local coordinate */ + SclPoint coords = get_rotated_local_coords( + root_x, root_y, context->get_rotation(), &rect); + controller->mouse_release(window, coords.x, coords.y, ev->multi.device); + processed = TRUE; + } + } + } + } + index++; + } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed); + } + + if (!processed) { + window = pressed_window; + SclWindowContext *window_context = windows->get_window_context(window); + if (window_context && get_window_rect(window, &rect)) { + if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) { + sclint temp = rect.width; + rect.width = rect.height; + rect.height = temp; + } + + /* Now convert the global coordinate to appropriate local coordinate */ +#ifdef WAYLAND + int root_x = ev->x + rect.x; + int root_y = ev->y + rect.y; + if (window_context->is_virtual) { + apply_virtual_offset(rect, &root_x, &root_y); + } +#else + int root_x = ev->root.x; + int root_y = ev->root.y; +#endif + + SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect); + controller->mouse_release(window, coords.x, coords.y, ev->multi.device); + processed = TRUE; + } + } + + mouse_pressed = FALSE; + } + + return TRUE; + //CSCLController *controller = CSCLController::get_instance(); + //CSCLWindows *windows = CSCLWindows::get_instance(); + //controller->mouse_release((sclwindow)data, (int)ev->output.x, (int)ev->output.y); + //controller->mouse_release((sclwindow)data, (int)ev->x, (int)ev->y); +} + +#ifdef HANDLE_KEY_EVENTS +static Eina_Bool key_pressed(void *data, int type, void *event_info) +{ + LOGD("=-=-=-=- key_pressed \n"); + CSCLController *controller = CSCLController::get_instance(); + Ecore_Event_Key *ev = (Ecore_Event_Key *)event_info; + const char *ckey_val = ev->key; + LOGD("=-=-=-=- ev->key(char) = %c \n", ev->key); + LOGD("=-=-=-=- ev->key(string) = %s \n", ev->key); + LOGD("=-=-=-=- ev->keyname(char) = %c \n", ev->keyname); + LOGD("=-=-=-=- ev->keyname(string) = %s \n", ev->keyname); + LOGD("=-=-=-=- ev->string(char) = %c \n", ev->string); + LOGD("=-=-=-=- ev->string(string) = %s \n", ev->string); + + CSCLResourceCache *cache = CSCLResourceCache::get_instance(); + SclButtonContext *prev_button_context = NULL; + const SclLayoutKeyCoordinate *prevcoordinate = NULL; + SclButtonContext *button_context = NULL; + const SclLayoutKeyCoordinate *coordinate = NULL; + + CSCLWindows *windows = CSCLWindows::get_instance(); + sclwindow window = windows->get_base_window(); + CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance(); + + sclbyte current_key_index = focus_handler->get_current_key_index(); + sclbyte key_index = current_key_index; + + if (strcmp(ev->keyname, "Right") == 0) { + key_index = focus_handler->get_next_key_index(NAVIGATE_RIGHT); + } else if (strcmp(ev->keyname, "Left") == 0) { + key_index = focus_handler->get_next_key_index(NAVIGATE_LEFT); + } else if (strcmp(ev->keyname, "Up") == 0) { + key_index = focus_handler->get_next_key_index(NAVIGATE_UP); + } else if (strcmp(ev->keyname, "Down") == 0) { + key_index = focus_handler->get_next_key_index(NAVIGATE_DOWN); + } else if ((strcmp(ev->keyname, "Return") == 0) || (strcmp(ev->keyname, "Enter") == 0)) { + button_context = cache->get_cur_button_context(window, current_key_index); + coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index); + button_context->state = BUTTON_STATE_NORMAL; + controller->mouse_press(window, coordinate->x, coordinate->y, TRUE); + controller->mouse_release(window, coordinate->x, coordinate->y, TRUE); + if (KEY_TYPE_MODECHANGE != coordinate->key_type) { + button_context->state = BUTTON_STATE_PRESSED; + windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height); + } else { + focus_handler->init_key_index(); + } + return TRUE; + } + + if (current_key_index != key_index) { + button_context = cache->get_cur_button_context(window, key_index); + prev_button_context = cache->get_cur_button_context(window, current_key_index); + prevcoordinate = cache->get_cur_layout_key_coordinate(window, current_key_index); + coordinate = cache->get_cur_layout_key_coordinate(window, key_index); + prev_button_context->state = BUTTON_STATE_NORMAL; + button_context->state = BUTTON_STATE_PRESSED; + sclshort x, y, width, height; + if (prevcoordinate->x < coordinate->x) { + x = prevcoordinate->x; + } else { + x = coordinate->x; + } + + if (prevcoordinate->y < coordinate->y) { + y = prevcoordinate->y; + } else { + y = coordinate->y; + } + + if (prevcoordinate->x + prevcoordinate->width > coordinate->x + coordinate->width) { + width = prevcoordinate->x + prevcoordinate->width - x; + } else { + width = coordinate->x + coordinate->width - x; + } + + if (prevcoordinate->y + prevcoordinate->height > coordinate->y + coordinate->height) { + height = prevcoordinate->y + prevcoordinate->height - y; + } else { + height = coordinate->y + coordinate->height - y; + } + windows->update_window(window, x, y, width, height); + + } else { + } + + return TRUE; +} +#endif /*HANDLE_KEY_EVENTS*/ + +//int mouse_move (void *data, Evas *e, Evas_Object *object, void *event_info) +static Eina_Bool mouse_move(void *data, int type, void *event_info) +{ + SCL_DEBUG(); + + CSCLController *controller = CSCLController::get_instance(); + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLContext *context = CSCLContext::get_instance(); + CSCLResourceCache *cache = CSCLResourceCache::get_instance(); + + //Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move*)event_info; + Ecore_Event_Mouse_Move *ev = (Ecore_Event_Mouse_Move*)event_info; + + //if (!mouse_pressed) return FALSE; + if (ev && check_timestamp_outdated(ev->timestamp)) { + return TRUE; + } + + if (controller && windows && context && cache && ev) { + sclbyte index = 0; + sclboolean processed = FALSE; + sclwindow window = SCLWINDOW_INVALID; + SclRectangle rect; + + LOGD("mouse_move : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y); + + if (context->get_cur_pressed_window(ev->multi.device) != SCLWINDOW_INVALID && + get_window_rect(context->get_cur_pressed_window(ev->multi.device), &rect)) { + sclint winwidth = rect.width; + sclint winheight = rect.height; + if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) { + rect.height = winwidth; + rect.width = winheight; + } +#ifdef WAYLAND + int root_x = 0; + int root_y = 0; + + Ecore_Wl2_Window *wl_base_window = + (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(windows->get_base_window())); + Ecore_Wl2_Window *wl_magnifier_window = + (Ecore_Wl2_Window*)(elm_win_wl_window_get(static_cast(windows->get_magnifier_window()))); + if (wl_base_window && (unsigned int)ecore_wl2_window_id_get(wl_base_window) == ev->window) { + SclRectangle base_rect; + if (get_window_rect(windows->get_base_window(), &base_rect)) { + root_x = ev->x + base_rect.x; + root_y = ev->y + base_rect.y; + } + } else if (wl_magnifier_window && (unsigned int)ecore_wl2_window_id_get(wl_magnifier_window) == ev->window) { + SclRectangle magnifier_rect = { 0, 0, 0, 0 }; + if (get_window_rect(windows->get_magnifier_window(), &magnifier_rect)) { + root_x = ev->x + magnifier_rect.x; + root_y = ev->y + magnifier_rect.y; + } + } else { + root_x = ev->x + rect.x; + root_y = ev->y + rect.y; + } +#else + int root_x = ev->root.x; + int root_y = ev->root.y; +#endif + + SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect); + + controller->mouse_move(context->get_cur_pressed_window(ev->multi.device), coords.x, coords.y, ev->multi.device); + processed = TRUE; + } else { + do { + window = windows->get_nth_window_in_Z_order_list(index); + if (window) { + SclWindowContext *window_context = windows->get_window_context(window); + if (window_context) { + windows->get_window_rect(window, &(window_context->geometry)); + if (get_window_rect(window, &rect)) { +#ifdef WAYLAND + int root_x = ev->x + rect.x; + int root_y = ev->y + rect.y; + if (window_context->is_virtual) { + apply_virtual_offset(rect, &root_x, &root_y); + } +#else + int root_x = ev->root.x; + int root_y = ev->root.y; +#endif + int adjust_x = root_x; + int adjust_y = root_y; + + SclResParserManager *sclres_manager = SclResParserManager::get_instance(); + PSclDefaultConfigure default_configure = NULL; + if (sclres_manager) { + default_configure = sclres_manager->get_default_configure(); + } + if (default_configure) { + SCLDisplayMode display_mode = context->get_display_mode(); + CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance(); + if (adjustment && scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) { + adjustment->apply_touch_offset( + default_configure->touch_offset_level[display_mode], + &adjust_x, &adjust_y); + } + } + + sclint win_width = rect.width; + sclint win_height = rect.height; + if (context->get_display_mode() != DISPLAYMODE_PORTRAIT) { + rect.height = win_width; + rect.width = win_height; + } + + sclboolean process_event = FALSE; + if ((adjust_x >= rect.x && adjust_x <= (rect.x + win_width)) && + (adjust_y >= rect.y && adjust_y <= (rect.y + win_height))) { + process_event = TRUE; + } + /* Process this event regardless of the coordinate if the top window has the POPUP_GRAB layout style */ + if (index == SCL_WINDOW_Z_TOP) { + const SclLayout *layout = cache->get_cur_layout(window); + if (layout) { + if (layout->style == LAYOUT_STYLE_POPUP_GRAB) { + process_event = TRUE; + } + } + } + if (process_event) { + /* Now convert the global coordinate to appropriate local coordinate */ + SclPoint coords = get_rotated_local_coords( + root_x, root_y, context->get_rotation(), &rect); + controller->mouse_move(window, coords.x, coords.y, ev->multi.device); + processed = TRUE; + } + } + } + } + index++; + } while (index < MAX_ZORDER_NUM && window != SCLWINDOW_INVALID && !processed); + } + + if (!processed) { + window = pressed_window; + SclWindowContext *window_context = windows->get_window_context(window); + if (window_context && get_window_rect(window, &rect)) { + /* Now convert the global coordinate to appropriate local coordinate */ +#ifdef WAYLAND + int root_x = ev->x + rect.x; + int root_y = ev->y + rect.y; + if (window_context->is_virtual) { + apply_virtual_offset(rect, &root_x, &root_y); + } +#else + int root_x = ev->root.x; + int root_y = ev->root.y; +#endif + + SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect); + controller->mouse_move(window, coords.x, coords.y, ev->multi.device); + processed = TRUE; + } + } + } + //CSCLController *controller = CSCLController::get_instance(); + //CSCLWindows *windows = CSCLWindows::get_instance(); + //controller->mouse_move((sclwindow)data, (int)ev->cur.output.x, (int)ev->cur.output.y); + //controller->mouse_move((sclwindow)data, (int)ev->x, (int)ev->y); + + return TRUE; +} + +/** + * Regists a event callback func to given window. + * In this function, it should call several event functions of CSCLController class whenever an event has occurred + * The below list shows what event function should be called. + * - mouse_press (when the user presses mouse button) + * - mouse_release (when the user releases mouse button) + * - mouse_move (when the user drags mouse button) + * - show_base_layout (when the expost event has occurred) + */ +void +CSCLEventsImplNui::connect_window_events(const sclwindow wnd, const sclint evt) +{ + SCL_DEBUG(); + + //evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, NULL); + /*evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_UP, mouse_release, NULL); + evas_object_event_callback_add((Evas_Object*)wnd, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, NULL);*/ +} + +#ifndef WAYLAND +static Eina_Bool +client_message_cb(void *data, int type, void *event) +{ + Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *)event; + if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL) { + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLController *controller = CSCLController::get_instance(); + + static int last_pos_x = -10000; + static int last_pos_y = -10000; + + if (windows && controller) { + Evas_Object *base_win = (Evas_Object *)windows->get_base_window(); + if (base_win == NULL) return FALSE; + + if ((unsigned int)ev->data.l[0] == elm_win_xwindow_get(base_win)) { + if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE) { + // 1 finger double tap + controller->mouse_press(base_win, last_pos_x, last_pos_y); + controller->mouse_release(base_win, last_pos_x, last_pos_y); + } else if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ) { + // 1 finger tap + // 1 finger touch & move + last_pos_x = ev->data.l[2]; + last_pos_y = ev->data.l[3]; + controller->mouse_over(base_win, last_pos_x, last_pos_y); + } + } + } + } + return ECORE_CALLBACK_PASS_ON; +} +#endif + +Eina_Bool timer_event(void *data) +{ + SCL_DEBUG(); + CSCLUtils *utils = CSCLUtils::get_instance(); + CSCLController *controller = CSCLController::get_instance(); + + scl32 sendData = static_cast(reinterpret_cast(data) & 0xffffffff); + + if (controller && utils) { + scl16 id = SCL_LOWORD(sendData); /* Timer ID */ + Eina_Bool ret = controller->timer_event(sendData); + if (!ret) { + utils->log("Returning Timer : %d %d\n", id, ret); + } + return ret; + } + return TRUE; +} + +/** + * Creates a timer + * In this function, it should call timer_event of CSCLController class + */ +void +CSCLEventsImplNui::create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap) +{ + SCL_DEBUG(); + sclint data = SCL_MAKELONG(id, value); + Ecore_Timer *pTimer = ecore_timer_add((double)interval / 1000.0, timer_event, (void*)(uintptr_t)data); + if (pTimer) { + CSCLUtils *utils = CSCLUtils::get_instance(); + if (utils) { + utils->log("Created Timer : %d %p\n", id, pTimer); + } + if (addToMap) { + idMap[id] = pTimer; + } + } +} + +/** + * Destroys the given ID's timer + */ +void +CSCLEventsImplNui::destroy_timer(const scl32 id) +{ + SCL_DEBUG(); + //for ( std::map::iterator idx = idMap.begin(); idx != idMap.end(); ++idx) { + std::map::iterator idx = idMap.find(id); + //if ((*idx).first == id) { + if (idx != idMap.end()) { + CSCLUtils *utils = CSCLUtils::get_instance(); + if (utils) { + utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second); + } + ecore_timer_del((*idx).second); + idMap.erase((*idx).first); + //break; + } + //} +} + +/** + * Destroys all of created timer + */ +void +CSCLEventsImplNui::destroy_all_timer() +{ + SCL_DEBUG(); + for ( std::map::iterator idx = idMap.begin(); idx != idMap.end(); ++idx ) { + ecore_timer_del((*idx).second); + + CSCLUtils *utils = CSCLUtils::get_instance(); + if (utils) { + utils->log("Destroyed Timer : %d %p\n", (*idx).first, (*idx).second); + } + } + idMap.clear(); +} + +void +CSCLEventsImplNui::generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y) +{ + CSCLWindows *windows = CSCLWindows::get_instance(); + SclWindowContext *window_context = NULL; + + static const sclint MAX_DEVICES = 100; + static sclboolean pressed[MAX_DEVICES] = { FALSE }; + if (windows) { + switch (type) { + case SCL_MOUSE_EVENT_PRESS: + { + sclboolean generated = FALSE; + for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) { + if (pressed[loop] != TRUE) { + pressed[loop] = TRUE; + Ecore_Event_Mouse_Button evt; +#ifdef WAYLAND + Ecore_Wl2_Window *wl_base_window; + wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(windows->get_base_window())); + if (wl_base_window) + evt.window = (unsigned int)ecore_wl2_window_id_get(wl_base_window); +#else + evt.window = elm_win_xwindow_get(static_cast(windows->get_base_window())); +#endif + //window_context = windows->get_window_context(windows->get_base_window(), FALSE); + window_context = windows->get_window_context(windows->get_base_window()); + if (window_context) { + evt.x = evt.root.x = x + window_context->geometry.x; + evt.y = evt.root.y = y + window_context->geometry.y; + evt.multi.device = loop; + mouse_press(NULL, 0, &evt); + } + generated = TRUE; + } + } + } + break; + case SCL_MOUSE_EVENT_RELEASE: + { + sclboolean generated = FALSE; + for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) { + if (pressed[loop] == TRUE) { + pressed[loop] = FALSE; + Ecore_Event_Mouse_Button evt; +#ifdef WAYLAND + Ecore_Wl2_Window *wl_base_window; + wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(windows->get_base_window())); + if (wl_base_window) + evt.window = (unsigned int)ecore_wl2_window_id_get(wl_base_window); +#else + evt.window = elm_win_xwindow_get(static_cast(windows->get_base_window())); +#endif + //window_context = windows->get_window_context(windows->get_base_window(), FALSE); + window_context = windows->get_window_context(windows->get_base_window()); + if (window_context) { + evt.x = evt.root.x = x + window_context->geometry.x; + evt.y = evt.root.y = y + window_context->geometry.y; + evt.multi.device = loop; + mouse_release(NULL, 0, &evt); + } + generated = TRUE; + } + } + } + break; + case SCL_MOUSE_EVENT_MOVE: + { + sclboolean generated = FALSE; + for (sclint loop = 0; !generated && loop < MAX_DEVICES; loop++) { + if (pressed[loop] == TRUE) { + Ecore_Event_Mouse_Move evt; +#ifdef WAYLAND + Ecore_Wl2_Window *wl_base_window; + wl_base_window = (Ecore_Wl2_Window*)elm_win_wl_window_get(static_cast(windows->get_base_window())); + if (wl_base_window) + evt.window = (unsigned int)ecore_wl2_window_id_get(wl_base_window); +#else + evt.window = elm_win_xwindow_get(static_cast(windows->get_base_window())); +#endif + //window_context = windows->get_window_context(windows->get_base_window(), FALSE); + window_context = windows->get_window_context(windows->get_base_window()); + if (window_context) { + evt.x = evt.root.x = x + window_context->geometry.x; + evt.y = evt.root.y = y + window_context->geometry.y; + evt.multi.device = loop; + mouse_move(NULL, 0, &evt); + } + generated = TRUE; + } + } + } + break; + default: + break; + } + } +} diff --git a/scl/sclevents-nui.h b/scl/sclevents-nui.h new file mode 100644 index 0000000..663b2dd --- /dev/null +++ b/scl/sclevents-nui.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sclevents.h" +#include +#include +#include + + +#ifndef __SCL_EVENTS_NUI_H__ +#define __SCL_EVENTS_NUI_H__ + +namespace scl +{ +class CSCLEventsImplNui : public CSCLEventsImpl +{ +public : + CSCLEventsImplNui(); + ~CSCLEventsImplNui(); + + void init(); + void fini(); + + /* Implementation about interface functions */ + void connect_window_events(const sclwindow wnd, const sclint evt); + void create_timer(const scl16 id, const scl32 interval, scl16 value, sclboolean addToMap); + void destroy_timer(const scl32 id); + void destroy_all_timer(); + + void generate_mouse_event(SCLMouseEvent type, scl16 x, scl16 y); + +private: + std::map idMap; + + Ecore_Event_Handler *m_mouse_down_handler; + Ecore_Event_Handler *m_mouse_move_handler; + Ecore_Event_Handler *m_mouse_up_handler; + Ecore_Event_Handler *m_key_pressed_handler; +}; +} /* End of scl namespace */ +#endif diff --git a/scl/sclevents.cpp b/scl/sclevents.cpp index 2183f2b..aea5d23 100644 --- a/scl/sclevents.cpp +++ b/scl/sclevents.cpp @@ -20,6 +20,8 @@ #include "sclevents-win32.h" #elif defined(__EFL__) #include "sclevents-efl.h" +#elif defined(__NUI__) +#include "sclevents-nui.h" #else #include "sclevents-gtk.h" #endif @@ -74,6 +76,8 @@ CSCLEventsImpl* CSCLEvents::get_scl_events_impl() m_impl = new CSCLEventsImplWin32; #elif defined(__EFL__) m_impl = new CSCLEventsImplEfl; +#elif defined(__NUI__) + m_impl = new CSCLEventsImplNui; #else m_impl = new CSCLEventsImplGtk; #endif diff --git a/scl/sclgraphics-efl.cpp b/scl/sclgraphics-efl.cpp deleted file mode 100644 index da54147..0000000 --- a/scl/sclgraphics-efl.cpp +++ /dev/null @@ -1,1076 +0,0 @@ -/* - * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "sclgraphics-efl.h" -#include "sclimageproxy.h" -#include "sclfontproxy.h" -#include "scldebug.h" -#include "sclwindows.h" -#include "sclresourcecache.h" -#include "sclwindows-efl.h" -#include "sclutils.h" - -#include -#include -#include -//#include -#include -#include - -//#define EXTRACT_PARTIMAGE - -#ifdef TEST_NEWBACKEND -std::vector g_ImageCache; -std::vector g_TextCache; -sclint hash_string(const sclchar* str) { - sclint ret = 0; - sclint len = strlen(str); - for (sclint loop = 0;loop < len && str[loop];loop++) { - ret = ((loop + 1) * str[loop]); - } - - return ret; -} -#else -#endif -using namespace scl; - -extern void mouse_press(void *data, Evas *e, Evas_Object *object, void *event_info); -extern void mouse_release(void *data, Evas *e, Evas_Object *object, void *event_info); -extern void mouse_move(void *data, Evas *e, Evas_Object *object, void *event_info); - -static std::map _nine_patch_map; - -/** - * Constructor - */ -CSCLGraphicsImplEfl::CSCLGraphicsImplEfl() -{ - SCL_DEBUG(); - /* Initializes all window resources */ - m_highlight_ui_object = NULL; -} - -/** - * De-constructor - */ -CSCLGraphicsImplEfl::~CSCLGraphicsImplEfl() -{ - SCL_DEBUG(); - - fini(); -} - -void CSCLGraphicsImplEfl::init() -{ - m_highlight_ui_object = NULL; -} - -void CSCLGraphicsImplEfl::fini() -{ - if (m_highlight_ui_object) { - evas_object_del(m_highlight_ui_object); - m_highlight_ui_object = NULL; - } -} - -Evas_Object* extract_partimage_from_fullimage( - Evas_Object* fullimage, - int img_x, int img_y, - int cell_x, int cell_y, - int cell_cx, int cell_cy) -{ - unsigned int *data; - unsigned int *t_data; - int i, j; - int w, h; - Evas_Object *image_ob; - - if (fullimage == NULL) { - return NULL; - } - evas_object_image_size_get(fullimage, &w, &h); - - data = (unsigned int*)evas_object_image_data_get(fullimage, 0); - if (data == NULL) { - return NULL; - } - - t_data = (unsigned int*)malloc(sizeof(unsigned int)*cell_cx*cell_cy); - if (t_data == NULL) { - return NULL; - } - - for (i=img_y; i < img_y+cell_cy; i++) { - for (j=img_x; j < img_x+cell_cx; j++) { - t_data[(i-img_y)*cell_cx+(j-img_x)] = data[i*w+j]; - } - } - - image_ob = evas_object_image_add(evas_object_evas_get(fullimage)); - if (image_ob == NULL) { - free(t_data); - return NULL; - } - evas_object_image_size_set(image_ob, cell_cx, cell_cy); - evas_object_image_data_set(image_ob, t_data); - evas_object_image_fill_set(image_ob, 0, 0, cell_cx, cell_cy); - evas_object_resize(image_ob, cell_cx, cell_cy); - - evas_object_show(image_ob); - - return image_ob; -} - -static sclboolean check_nine_patch_png_file(const char *image_path) -{ - sclboolean found = FALSE; - for (sclint loop = strlen(image_path);!found && loop > 0;loop--) { - if (image_path[loop] == '.') { - found = TRUE; - if (loop >= 2) { // for checking prefix ".#" and ".9" - if (strcasecmp(image_path + loop - 2, ".#.png") == 0 || - strcasecmp(image_path + loop - 2, ".9.png") == 0) { - return TRUE; - } - } - } - } - return FALSE; -} - -SclNinePatchInfo get_nine_patch_info_from_png_file(Evas_Object *image_data, sclint w, sclint h) -{ - /* FIXME : Assuming we're dealing with 32bit image, need to check if there's any other cases */ - SclNinePatchInfo ret = {0}; - unsigned int *data = (unsigned int*)evas_object_image_data_get(image_data, EINA_FALSE); - if (data) { - int x, y; - sclboolean found; - found = FALSE; - for (x = 0;x < w && !found;x++) { - if (data[x] > 0) { - found = TRUE; - ret.left = x; - } - } - found = FALSE; - for (x = w - 1;x >= 0 && !found;x--) { - if (data[x] > 0) { - found = TRUE; - ret.right = w - (x + 1); - } - } - found = FALSE; - for (y = 0;y < h && !found;y++) { - if (data[y * w] > 0) { - found = TRUE; - ret.top = y; - } - } - found = FALSE; - for (y = h - 1;y >= 0 && !found;y--) { - if (data[y * w] > 0) { - found = TRUE; - ret.bottom = h - (y + 1); - } - } - } - return ret; -} - -/** - * Returns Evas_Object representing window - */ -static Evas_Object *get_evas_window_object(sclwindow window) -{ - SclWindowContext *window_context = NULL; - CSCLWindows *windows = CSCLWindows::get_instance(); - - if (!window || !windows) - return NULL; - - Evas_Object *window_object = (Evas_Object*)window; - - window_context = windows->get_window_context(window); - - if (window_context && window_context->is_virtual) { - window_object = static_cast(windows->get_base_window()); - } - - return window_object; -} - -/** - * Callback called on accessibility action - */ -static Eina_Bool access_action(void *data, Evas_Object *obj, Elm_Access_Action_Info *action_info) { - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLEvents* events = CSCLEvents::get_instance(); - - if (!windows || !events || !obj) - return EINA_FALSE; - - Evas_Coord ex, ey, ew, eh; - evas_object_geometry_get(obj, &ex, &ey, &ew, &eh); - scl16 x = ex + ew / 2; - scl16 y = ey + eh / 2; - - LOGD("access_action callback x: %d, y: %d", x, y); - - SclWindowContext *window_context = windows->get_window_context(windows->get_base_window());; - if (window_context) { - x -= window_context->geometry.x; - y -= window_context->geometry.y; - } - - //simulate button press - events->generate_mouse_event(SCL_MOUSE_EVENT_PRESS, x, y); - events->generate_mouse_event(SCL_MOUSE_EVENT_RELEASE, x, y); - return EINA_TRUE; -} - -/** - * Register drawing as atspi object - */ -void CSCLGraphicsImplEfl::register_atspi_object(sclwindow window, scldrawing drawing, const sclchar* name) -{ - SCL_DEBUG(); - - Evas_Object *window_object = get_evas_window_object(window); - Evas_Object *drawing_object = static_cast(drawing); - - if (!drawing_object || !window_object || !name) - return; - - Evas_Object * access_object = elm_access_object_register(drawing_object, window_object); - if (!access_object) - return; - - elm_atspi_accessible_name_set(access_object, name); - elm_atspi_accessible_role_set(access_object, ELM_ATSPI_ROLE_PUSH_BUTTON); - elm_access_action_cb_set(access_object, ELM_ACCESS_ACTION_ACTIVATE, access_action, name); -} - -extern sclint magnifierx, magnifiery; -scldrawing -CSCLGraphicsImplEfl::draw_image(sclwindow window, const scldrawctx draw_ctx, sclchar* image_path, SclImageCachedInfo *cachedinfo, - sclint dest_x, sclint dest_y, sclint dest_width, sclint dest_height, - sclint src_x, sclint src_y, sclint src_width, sclint src_height, sclboolean extrace_image) -{ - SCL_DEBUG(); - - scl_assert_return_null(image_path); - - CSCLResourceCache *cache = CSCLResourceCache::get_instance(); - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLUtils *utils = CSCLUtils::get_instance(); - SclWindowContext *window_context = NULL; - SclWindowContext *target_window_context = NULL; - if (windows && window) { - //window_context = windows->get_window_context(window, FALSE); - window_context = windows->get_window_context(window); - //target_window_context = windows->get_window_context(draw_ctx, FALSE); - target_window_context = windows->get_window_context(draw_ctx); - } - - if (window_context && target_window_context && image_path && utils && cache && windows) { - sclboolean is_highlight_ui = FALSE; - sclchar buf[_POSIX_PATH_MAX] = {0}; - utils->get_decomposed_path(buf, IMG_PATH_PREFIX, image_path); - if (strcmp(buf, SCL_HIGHLIGHT_UI_IMAGE) == 0) { - is_highlight_ui = TRUE; - } - - if (strlen(image_path) > 0) { -#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW - if (window == windows->get_magnifier_window()) { - dest_x += magnifierx; - dest_y += magnifiery; - } -#endif -#ifdef TEST_NEWBACKEND - sclboolean bFound = FALSE; - sclboolean bOrgSizeMinusOne = (src_width == -1 && src_height == -1); - sclint hashval = hash_string(image_path); - /*for(std::list::iterator iter = g_ImageCache.begin(); - bFound && iter != g_ImageCache.end();std::advance(iter, 1)) {*/ - for (sclint loop = 0;loop < (sclint)g_ImageCache.size() && !bFound;loop++) { - if ( - /* (*iter).used && - window == (*iter).window && - hashval == (*iter).imgPathHash && - dest_x == (*iter).dest_x && - dest_y == (*iter).dest_y && - dest_width == (*iter).dest_width && - dest_height == (*iter).dest_height && - src_x == (*iter).src_x && - src_y == (*iter).src_y && - src_width == (*iter).src_width && - src_height == (*iter).src_height && - extrace_image == (*iter).extrace_image*/ - g_ImageCache[loop].used && - window == g_ImageCache[loop].window && - hashval == g_ImageCache[loop].imgPathHash && - dest_x == g_ImageCache[loop].dest_x && - dest_y == g_ImageCache[loop].dest_y && - dest_width == g_ImageCache[loop].dest_width && - dest_height == g_ImageCache[loop].dest_height && - src_x == g_ImageCache[loop].src_x && - src_y == g_ImageCache[loop].src_y && - src_width == g_ImageCache[loop].src_width && - src_height == g_ImageCache[loop].src_height && - extrace_image == g_ImageCache[loop].extrace_image - ) - { - //if (strcmp(image_path, (*iter).image_path) == 0) { - if (strcmp(image_path, g_ImageCache[loop].image_path) == 0) { - bFound = TRUE; - //evas_object_show((*iter).image); - evas_object_show(g_ImageCache[loop].image); - evas_object_raise(g_ImageCache[loop].image); - if (g_ImageCache[loop].clipper) { - evas_object_show(g_ImageCache[loop].clipper); - evas_object_raise(g_ImageCache[loop].clipper); - } - } - } - } - if (!bFound) { -#endif - EFLObject *clip_object = NULL; - - Evas_Object *window_object = (Evas_Object*)window; - if (window_context->is_virtual) { - window_object = static_cast(windows->get_base_window()); - } - - Evas *evas = evas_object_evas_get(window_object); - Evas_Object *image_object = NULL; - if (is_highlight_ui && m_highlight_ui_object) { - image_object = m_highlight_ui_object; - const SclNinePatchInfo *nine_patch_info = utils->get_nine_patch_info(image_path); - if (nine_patch_info) { - evas_object_image_border_set(image_object, - nine_patch_info->left, nine_patch_info->right, nine_patch_info->top, nine_patch_info->bottom); - } - evas_object_move(image_object, dest_x, dest_y); - evas_object_raise(image_object); - evas_object_show(image_object); - } else { - EFLObject *object = new EFLObject; - if (object) { - image_object = evas_object_image_add(evas); - object->extracted = FALSE; - - if (image_object) { - int image_width = 0; - int image_height = 0; - evas_object_image_file_set(image_object, image_path, NULL); - evas_object_image_size_get(image_object, &image_width, &image_height); - - sclboolean is_nine_patch_png = check_nine_patch_png_file(image_path); - if (is_nine_patch_png) { - std::map::iterator it = _nine_patch_map.find(image_path); - if (it != _nine_patch_map.end()) { - evas_object_image_border_set(image_object, - (*it).second.left, (*it).second.right, (*it).second.top, (*it).second.bottom); - } else { - SclNinePatchInfo info = get_nine_patch_info_from_png_file(image_object, image_width, image_height); - evas_object_image_border_set(image_object, info.left, info.right, info.top, info.bottom); - _nine_patch_map[std::string(image_path)] = info; - } - } else if (cachedinfo) { - evas_object_image_border_set(image_object, - cachedinfo->nine_patch_left, - cachedinfo->nine_patch_right, - cachedinfo->nine_patch_top, - cachedinfo->nine_patch_bottom); - } else { - const SclNinePatchInfo *nine_patch_info = utils->get_nine_patch_info(image_path); - if (nine_patch_info) { - evas_object_image_border_set(image_object, - nine_patch_info->left, nine_patch_info->right, nine_patch_info->top, nine_patch_info->bottom); - } - } - const SclLayout *layout = cache->get_cur_layout(window); - if (layout) { - if (layout->display_mode == DISPLAYMODE_PORTRAIT) { - image_width = utils->get_scaled_x(image_width); - image_height = utils->get_scaled_y(image_height); - } else { - image_width = utils->get_scaled_y(image_width); - image_height = utils->get_scaled_x(image_height); - } - } - if (src_width == -1 && src_height == -1) { - src_width = image_width; - src_height = image_height; - } - if ((src_width > 0 && src_height > 0) && - (image_width != dest_width || image_height != dest_height) && extrace_image) { - #ifdef EXTRACT_PARTIMAGE - Evas_Object *newobj = extract_partimage_from_fullimage(image_object, src_x, src_y, 0, 0, src_width, src_height); - object->extracted = TRUE; - evas_object_del(image_object); - image_object = newobj; - evas_object_move(image_object, dest_x, dest_y); - if (dest_width > 0 && dest_height > 0) { - evas_object_image_fill_set(image_object, 0, 0, dest_width, dest_height); - evas_object_resize(image_object, dest_width, dest_height); - } - #else - //evas_object_move(image_object, src_x - dest_x, src_y - dest_y); - evas_object_move(image_object, dest_x - src_x, dest_y - src_y); - evas_object_image_fill_set(image_object, 0, 0, image_width, image_height); - evas_object_resize(image_object, image_width, image_height); - - Evas_Object *clipper = evas_object_rectangle_add(evas); - evas_object_color_set(clipper, 255, 255, 255, 255); - //evas_object_color_set(clipper, 0, 0, 0, 0); - evas_object_move(clipper, dest_x, dest_y); - evas_object_resize(clipper, dest_width, dest_height); - evas_object_clip_set(image_object, clipper); - evas_object_show(clipper); - - clip_object = new EFLObject; - if (clip_object) { - clip_object->object = clipper; - clip_object->type = EFLOBJECT_CLIPOBJECT; - clip_object->position.x = dest_x; - clip_object->position.y = dest_y; - clip_object->position.width = dest_width; - clip_object->position.height = dest_height; - clip_object->etc_info = image_path; - clip_object->extracted = FALSE; - clip_object->data = NULL; - } - #endif - } else { - evas_object_move(image_object, dest_x, dest_y); - if (dest_width > 0 && dest_height > 0) { - if (is_nine_patch_png) { - evas_object_image_fill_set(image_object, -1, -1, dest_width + 2, dest_height + 2); - } else { - evas_object_image_fill_set(image_object, 0, 0, dest_width, dest_height); - } - evas_object_resize(image_object, dest_width, dest_height); - } - } - evas_object_raise(image_object); - evas_object_show(image_object); - - //evas_object_event_callback_add((Evas_Object*)image_object, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, window); - /*evas_object_event_callback_add((Evas_Object*)image_object, EVAS_CALLBACK_MOUSE_UP, mouse_release, window); - evas_object_event_callback_add((Evas_Object*)image_object, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, window);*/ - - object->object = image_object; - object->type = EFLOBJECT_IMAGE; - object->position.x = dest_x; - object->position.y = dest_y; - object->position.width = dest_width; - object->position.height = dest_height; - object->etc_info = image_path; - object->data = clip_object; - - if (is_highlight_ui) { - delete object; - } else { - target_window_context->etc_info = - eina_list_append((Eina_List*)(target_window_context->etc_info), object); - if (clip_object) { - target_window_context->etc_info = - eina_list_append((Eina_List*)(target_window_context->etc_info), clip_object); - } - } - - /* FIXME : this is for placing the background image at the lowest depth */ - sclint window_layer = 29000; - if (!windows->is_base_window(reinterpret_cast(draw_ctx))) { - window_layer = 29010; - } - //SclRectangle rt; - //windows->get_window_rect(window, &rt); - //if (rt.width == dest_width && rt.height == dest_height) { - if (window_context->geometry.width == dest_width && - window_context->geometry.height == dest_height) { - //evas_object_lower(image_object); - evas_object_layer_set(image_object, window_layer + 0); - } else { - evas_object_layer_set(image_object, window_layer + 1); - } - return image_object; - } else { - delete object; - object = NULL; - } - } - } -#ifdef TEST_NEWBACKEND - ImageCache cache; - cache.used = true; - cache.window = window; - strncpy(cache.image_path, image_path, sizeof(cache.image_path)); - cache.imgPathHash = hashval; - cache.dest_x = dest_x; - cache.dest_y = dest_y; - cache.dest_width = dest_width; - cache.dest_height = dest_height; - cache.src_x = src_x; - cache.src_y = src_y; - if (bOrgSizeMinusOne) { - cache.src_width = -1; - cache.src_height = -1; - } else { - cache.src_width = src_width; - cache.src_height = src_height; - } - cache.extrace_image = extrace_image; - cache.image = object->object; - if (clip_object) { - cache.clipper = clip_object->object; - } else { - cache.clipper = NULL; - } - - //g_ImageCache.insert(g_ImageCache.end(), cache); - sclboolean bInserted = FALSE; - for (sclint loop = 0;loop < (sclint)g_ImageCache.size() && !bInserted;loop++) { - if (!g_ImageCache[loop].used) { - g_ImageCache[loop] = cache; - } - } - if (!bInserted) { - g_ImageCache.push_back(cache); - } - } -#endif - } - } - return NULL; -} - -sclimage -CSCLGraphicsImplEfl::load_image(const sclchar *image_path) -{ - SCL_DEBUG(); - return NULL; -} - -void -CSCLGraphicsImplEfl::unload_image(sclimage image_data) -{ - SCL_DEBUG(); -} - -/** - * Initializes the drawing context for double-buffering. - * This func should be called before using a drawing primitive at first. - */ -scldrawctx -CSCLGraphicsImplEfl::begin_paint(const sclwindow window, const sclboolean force_draw /* = FALSE */) -{ - SCL_DEBUG(); - - scldrawctx drawctx = reinterpret_cast(window); - - return drawctx; -} - -/** - * Notices that drawing tasks have done. - */ -void -CSCLGraphicsImplEfl::end_paint(const sclwindow window, scldrawctx draw_ctx) -{ - //Evas_Object *window_object = (Evas_Object*)window; - //Evas *evas = evas_object_evas_get(window_object); - //evas_render_idle_flush(evas); -} - -sclfont -CSCLGraphicsImplEfl::create_font(const SclFontInfo& info) -{ - return NULL; -} - -void -CSCLGraphicsImplEfl::destroy_font(sclfont font) -{ -} - -/** - * Draws the given text on cairo-surface - */ -scldrawing -CSCLGraphicsImplEfl::draw_text(sclwindow window, const scldrawctx draw_ctx, const SclFontInfo& font_info, const SclColor& color, - const sclchar *str, SclTextCachedInfo *cachedinfo, sclint pos_x, sclint pos_y, sclint width, sclint height, - SCLLabelAlignment align, sclint padding_x, sclint padding_y, - sclint inner_width, sclint inner_height) -{ - SCL_DEBUG(); - - CSCLWindows *windows = CSCLWindows::get_instance(); - SclWindowContext *window_context = NULL; - SclWindowContext *target_window_context = NULL; - - if (windows && window) { - //window_context = windows->get_window_context(window, FALSE); - window_context = windows->get_window_context(window); - //target_window_context = windows->get_window_context(draw_ctx, FALSE); - target_window_context = windows->get_window_context(draw_ctx); - } - - if (window_context && target_window_context && str && windows) { - if (strlen(str) > 0) { -#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW - if (window == windows->get_magnifier_window()) { - pos_x += magnifierx; - pos_y += magnifiery; - } -#endif -#ifdef TEST_NEWBACKEND - sclboolean bFound = FALSE; - sclint hashval = hash_string(str); - sclint org_posx = pos_x; - sclint org_posy = pos_y; - /*for(std::list::iterator iter = g_TextCache.begin(); - bFound && iter != g_TextCache.end();std::advance(iter, 1)) {*/ - for (sclint loop = 0;loop < (sclint)g_TextCache.size() && !bFound;loop++) { - if ( - /* - (*iter).used && - window == (*iter).window && - strncmp(font_info.font_name, (*iter).font_info.font_name, MAX_FONT_NAME_LEN) == 0 && - font_info.font_size == (*iter).font_info.font_size && - font_info.is_bold == (*iter).font_info.is_bold && - font_info.is_italic == (*iter).font_info.is_italic && - memcmp(&color, &((*iter).color), sizeof(SclColor)) == 0 && - hashval == (*iter).strHash && - pos_x == (*iter).pos_x&& - pos_y == (*iter).pos_y && - width == (*iter).width && - height == (*iter).height && - align == (*iter).align && - padding_x == (*iter).padding_x && - padding_y == (*iter).padding_y && - inner_width == (*iter).inner_width && - inner_height == (*iter).inner_height */ - - g_TextCache[loop].used && - window == g_TextCache[loop].window && - strncmp(font_info.font_name, g_TextCache[loop].font_info.font_name, MAX_FONT_NAME_LEN) == 0 && - font_info.font_size == g_TextCache[loop].font_info.font_size && - font_info.is_bold == g_TextCache[loop].font_info.is_bold && - font_info.is_italic == g_TextCache[loop].font_info.is_italic && - memcmp(&color, &(g_TextCache[loop].color), sizeof(SclColor)) == 0 && - hashval == g_TextCache[loop].strHash && - pos_x == g_TextCache[loop].pos_x&& - pos_y == g_TextCache[loop].pos_y && - width == g_TextCache[loop].width && - height == g_TextCache[loop].height && - align == g_TextCache[loop].align && - padding_x == g_TextCache[loop].padding_x && - padding_y == g_TextCache[loop].padding_y && - inner_width == g_TextCache[loop].inner_width && - inner_height == g_TextCache[loop].inner_height - ) - { - //if (strcmp(str, (*iter).str) == 0) { - if (strcmp(str, g_TextCache[loop].str) == 0) { - bFound = TRUE; - //evas_object_show((*iter).text); - evas_object_show(g_TextCache[loop].text); - evas_object_raise(g_TextCache[loop].text); - } - } - } - if (!bFound) { -#endif - EFLObject *object = new EFLObject; - if (object) { - object->extracted = FALSE; - Evas_Object *window_object = (Evas_Object*)window; - if (window_context->is_virtual) { - window_object = static_cast(windows->get_base_window()); - } - Evas *evas = evas_object_evas_get(window_object); - Evas_Object *text_object = evas_object_textblock_add(evas); - - if (text_object) { - if (inner_width > 0 || inner_height > 0) { - SclPoint bottom_right; - bottom_right.x = pos_x + width; - bottom_right.y = pos_y + height; - - /* The inner width and height value should be bigger than 0 */ - if (inner_width <= 0) inner_width = width; - if (inner_height <= 0) inner_height = height; - - /* The inner width and height value should not exceed the actual width and height */ - if (inner_width > width) inner_width = width; - if (inner_height > height) inner_height = height; - - /* We need to make a inner rectangle if inner_width and inner_height are not 0 */ - if (align == LABEL_ALIGN_CENTER_TOP || - align == LABEL_ALIGN_CENTER_MIDDLE || - align == LABEL_ALIGN_CENTER_BOTTOM) { - pos_x = pos_x + ((width - inner_width) / 2) + padding_x; - } else if (align == LABEL_ALIGN_RIGHT_TOP || - align == LABEL_ALIGN_RIGHT_MIDDLE || - align == LABEL_ALIGN_RIGHT_BOTTOM) { - pos_x = pos_x + (width - inner_width) - padding_x; - } else { - pos_x += padding_x; - } - if (align == LABEL_ALIGN_LEFT_MIDDLE || - align == LABEL_ALIGN_CENTER_MIDDLE || - align == LABEL_ALIGN_RIGHT_MIDDLE) { - pos_y = pos_y + ((height - inner_height) / 2) + padding_y; - } else if (align == LABEL_ALIGN_LEFT_BOTTOM || - align == LABEL_ALIGN_CENTER_BOTTOM || - align == LABEL_ALIGN_RIGHT_BOTTOM) { - pos_y = pos_y + (height - inner_height) - padding_y; - } else { - pos_y += padding_y; - } - - /* Make sure the inner bounding box does not exceed the original bounding box */ - if (pos_x + inner_width > bottom_right.x) { - width = bottom_right.x - pos_x; - } else { - width = inner_width; - } - if (pos_y + inner_height > bottom_right.y) { - height = bottom_right.y - pos_y; - } else { - height = inner_height; - } - - align = LABEL_ALIGN_CENTER_MIDDLE; - padding_x = 0; - padding_y = 0; - } - - sclchar strStyle[256]; - snprintf(strStyle, 256, - "DEFAULT='font=%s font_size=%d align=%s color=#%02X%02X%02X%02X wrap=word left_margin=%d right_margin=%d'", - font_info.font_name, font_info.font_size, - (((int)align % 3) == 1) ? "center" : ((((int)align % 3) == 2) ? "right" : "left"), - color.r, color.g, color.b, color.a, padding_x, padding_x); - - Evas_Textblock_Style *st; - st = evas_textblock_style_new(); - evas_textblock_style_set(st, strStyle); - evas_object_textblock_style_set(text_object, st); - //evas_textblock_style_free(st); - - //evas_object_textblock_clear(text_object); - char *markup = evas_textblock_text_utf8_to_markup(text_object, str); - if (markup) { - evas_object_textblock_text_markup_set(text_object, markup); - free(markup); - } - evas_object_resize(text_object, width, height); - - object->extracted = FALSE; - object->type = EFLOBJECT_TEXTBLOCK; - object->object = text_object; - object->position.x = pos_x; - object->position.y = pos_y; - object->position.width = width; - object->position.height = height; - object->etc_info = str; - object->data = st; - - sclint calwidth, calheight; - if (cachedinfo) { - calwidth = cachedinfo->actual_size.width; - calheight = cachedinfo->actual_size.height; - } else { - evas_object_textblock_size_native_get(text_object, &calwidth, &calheight); - } - // FIXME: float to int may loose precision - if (calwidth > 0) { - static float _SPACE_RATE = 0.1; - calwidth *= 1 + _SPACE_RATE; - } - if (calheight > 0) { - static float _SPACE_RATE = 0.1; - calheight *= 1 + _SPACE_RATE; - } - - if (calwidth > width || calheight > height) { - sclfloat width_rate = (sclfloat)width / (sclfloat)calwidth; - sclfloat height_rate = (sclfloat)height / (sclfloat)calheight; - sclfloat resize_rate = height_rate; - if (width_rate < height_rate) { - resize_rate = width_rate; - } - - snprintf(strStyle, 128, - "DEFAULT='font=%s font_size=%d align=%s color=#%02X%02X%02X%02X wrap=word left_margin=%d right_margin=%d'", - font_info.font_name, - (int)(SCL_LABEL_OVERLENGTH_TEXT_RESIZE_RATE * font_info.font_size * resize_rate), - (((int)align % 3) == 1) ? "center" : ((((int)align % 3) == 2) ? "right" : "left"), - color.r, color.g, color.b, color.a, padding_x, padding_x); - evas_textblock_style_set(st, strStyle); - evas_object_textblock_style_set(text_object, st); - markup = evas_textblock_text_utf8_to_markup(text_object, str); - if (markup) { - evas_object_textblock_text_markup_set(text_object, markup); - free(markup); - } - evas_object_resize(text_object, width, height); - evas_object_textblock_size_native_get(text_object, &calwidth, &calheight); - } - - /*if (align == LABEL_ALIGN_CENTER_TOP || align == LABEL_ALIGN_CENTER_MIDDLE || align == LABEL_ALIGN_CENTER_BOTTOM) { - pos_x = pos_x + ((width - calwidth) / 2) + padding_x; - } else if (align == LABEL_ALIGN_RIGHT_TOP || align == LABEL_ALIGN_RIGHT_MIDDLE || align == LABEL_ALIGN_RIGHT_BOTTOM) { - pos_x = pos_x + (width - calwidth) - padding_x; - } else { - pos_x += padding_x; - }*/ - if (align == LABEL_ALIGN_LEFT_MIDDLE || - align == LABEL_ALIGN_CENTER_MIDDLE || - align == LABEL_ALIGN_RIGHT_MIDDLE) { - pos_y = pos_y + ((height - calheight) / 2) + padding_y; - } else if (align == LABEL_ALIGN_LEFT_BOTTOM || - align == LABEL_ALIGN_CENTER_BOTTOM || - align == LABEL_ALIGN_RIGHT_BOTTOM) { - pos_y = pos_y + (height - calheight) - padding_y; - } else { - pos_y += padding_y; - } - - evas_object_move(text_object, pos_x, pos_y); - evas_object_raise(text_object); - evas_object_show(text_object); - - //evas_object_event_callback_add((Evas_Object*)text_object, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, window); - /*evas_object_event_callback_add((Evas_Object*)text_object, EVAS_CALLBACK_MOUSE_UP, mouse_release, window); - evas_object_event_callback_add((Evas_Object*)text_object, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, window);*/ - - target_window_context->etc_info = - eina_list_append((Eina_List*)(target_window_context->etc_info), object); - - sclint window_layer = 29000; - if (!windows->is_base_window(reinterpret_cast(draw_ctx))) { - window_layer = 29010; - } - evas_object_layer_set(text_object, window_layer + 1); - return text_object; - } else { - delete object; - object = NULL; - } - } -#ifdef TEST_NEWBACKEND - TextCache cache; - cache.used = true; - cache.window = window; - cache.font_info = font_info; - cache.color = color; - strncpy(cache.font_info.font_name, font_info.font_name, MAX_FONT_NAME_LEN); - cache.font_info.font_size = font_info.font_size; - cache.font_info.is_bold = font_info.is_bold; - cache.font_info.is_italic = font_info.is_italic; - memcpy(&(cache.color), &(color), sizeof(SclColor)); - strncpy(cache.str, str, sizeof(cache.str)); - cache.strHash = hashval; - cache.pos_x = org_posx; - cache.pos_y = org_posy; - cache.width = width; - cache.height = height; - cache.align = align; - cache.padding_x = padding_x; - cache.padding_y = padding_y; - cache.inner_width = inner_width; - cache.inner_height = inner_height; - - cache.text = object->object; - - //g_TextCache.insert(g_TextCache.end(), cache); - sclboolean bInserted = FALSE; - for (sclint loop = 0;loop < (sclint)g_TextCache.size() && !bInserted;loop++) { - if (!g_TextCache[loop].used) { - g_TextCache[loop] = cache; - } - } - if (!bInserted) { - g_TextCache.push_back(cache); - } - } -#endif - } - } - return NULL; -} - -/** - * Draws a rectangle on cairo-surface - */ -scldrawing -CSCLGraphicsImplEfl::draw_rectangle(sclwindow window, const scldrawctx draw_ctx, scldouble pos_x, scldouble pos_y, - scldouble width, scldouble height, const scldouble line_width, const SclColor& line_color, sclboolean fill, const SclColor& fill_color, scldouble radius, sclfloat alpha) -{ - SCL_DEBUG(); - - CSCLResourceCache *cache = CSCLResourceCache::get_instance(); - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLUtils *utils = CSCLUtils::get_instance(); - SclWindowContext *window_context = NULL; - SclWindowContext *target_window_context = NULL; - - if (windows && window) { - //window_context = windows->get_window_context(window, FALSE); - window_context = windows->get_window_context(window); - //target_window_context = windows->get_window_context(draw_ctx, FALSE); - target_window_context = windows->get_window_context(draw_ctx); - } - - if (window_context && utils && cache && windows && target_window_context) { - EFLObject *object = new EFLObject; - if (object) { - Evas_Object *window_object = (Evas_Object*)window; - if (window_context->is_virtual) { - window_object = static_cast(windows->get_base_window()); - } - - Evas *evas = evas_object_evas_get(window_object); - Evas_Object *rectobj = evas_object_rectangle_add(evas); - - evas_object_color_set(rectobj, fill_color.r, fill_color.g, fill_color.b, fill_color.a); - - evas_object_move(rectobj, pos_x, pos_y); - evas_object_resize(rectobj, width, height); - evas_object_show(rectobj); - - object->extracted = FALSE; - object->object = rectobj; - object->type = EFLOBJECT_RECTANGLE; - object->position.x = pos_x; - object->position.y = pos_y; - object->position.width = width; - object->position.height = height; - object->etc_info = NULL; - object->data = NULL; - - target_window_context->etc_info = - eina_list_append((Eina_List*)(target_window_context->etc_info), object); - - /* FIXME : this is for placing the background image at the lowest depth */ - sclint window_layer = 29000; - if (!windows->is_base_window(reinterpret_cast(draw_ctx))) { - window_layer = 29010; - } - if (window_context->geometry.width == width && - window_context->geometry.height == height) { - evas_object_layer_set(rectobj, window_layer + 0); - } else { - evas_object_layer_set(rectobj, window_layer + 1); - } - return rectobj; - } - } - return NULL; -} - -SclSize -CSCLGraphicsImplEfl::get_image_size(sclchar* image_path) -{ - SCL_DEBUG(); - SclSize ret = { 0, 0 }; - - CSCLWindows *windows = CSCLWindows::get_instance(); - if (!windows) return ret; - - Evas_Object *window_object = (Evas_Object*)(windows->get_base_window()); - Evas_Object *image_object = NULL; - - if (window_object) { - Evas *evas = evas_object_evas_get(window_object); - image_object = evas_object_image_add(evas); - } - - if (image_object) { - int w, h; - evas_object_image_file_set(image_object, image_path, NULL); - evas_object_image_size_get(image_object, &w, &h); - evas_object_del(image_object); - ret.width = w; - ret.height = h; - } - - return ret; -} - -SclSize -CSCLGraphicsImplEfl::get_text_size(const SclFontInfo &fontinfo, const sclchar *str) -{ - SCL_DEBUG(); - SclSize ret = { 0, 0 }; - - CSCLWindows *windows = CSCLWindows::get_instance(); - Evas_Object *winobj = NULL; - Evas *evas = NULL; - - if (windows) { - winobj = (Evas_Object*)(windows->get_base_window()); - } - if (winobj) { - evas = evas_object_evas_get(winobj); - } - - int w, h; - - Evas_Textblock_Style *st; - st = evas_textblock_style_new(); - - Evas_Object *text_object = evas_object_textblock_add(evas); - - if (text_object && st) { - const sclint STYLE_STR_LEN = 256; - sclchar strStyle[STYLE_STR_LEN] = {0}; - snprintf(strStyle, STYLE_STR_LEN - 1, "DEFAULT='font=%s font_size=%d'", - fontinfo.font_name, fontinfo.font_size); - - evas_textblock_style_set(st, strStyle); - evas_object_textblock_style_set(text_object, st); - - evas_object_textblock_clear(text_object); - char *markup = evas_textblock_text_utf8_to_markup(text_object, str); - if (markup) { - evas_object_textblock_text_markup_set(text_object, markup); - free(markup); - } - - evas_object_textblock_size_native_get(text_object, &w, &h); - - ret.width = w; - ret.height = h; - } - if (text_object) { - evas_object_del(text_object); - } - if (st) { - evas_textblock_style_free(st); - } - - return ret; -} diff --git a/scl/sclgraphics-efl.h b/scl/sclgraphics-efl.h deleted file mode 100644 index 8725a08..0000000 --- a/scl/sclgraphics-efl.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "sclgraphics.h" - -#ifndef __SCL_GRAPHICS_EFL_H__ -#define __SCL_GRAPHICS_EFL_H__ - -//#define DO_NOT_MOVE_MAGNIFIER_WINDOW -//#define FULL_SCREEN_TEST - -#include - -/* Still an experimental feature.. Will be refined after being stabilized */ -//#define TEST_NEWBACKEND -#ifdef TEST_NEWBACKEND -using namespace scl; - -#include -#include - -typedef struct { - sclboolean used; - - Evas_Object *image; - Evas_Object *clipper; - - sclwindow window; - sclchar image_path[_POSIX_PATH_MAX]; - sclint imgPathHash; - sclint dest_x; - sclint dest_y; - sclint dest_width; - sclint dest_height; - sclint src_x; - sclint src_y; - sclint src_width; - sclint src_height; - sclboolean extrace_image; -} ImageCache; - -typedef struct { - sclboolean used; - - Evas_Object *text; - - sclwindow window; - scl::SclFontInfo font_info; - SclColor color; - sclchar str[_POSIX_PATH_MAX];; - sclint strHash; - sclint pos_x; - sclint pos_y; - sclint width; - sclint height; - SCLLabelAlignment align; - sclint padding_x; - sclint padding_y; - sclint inner_width; - sclint inner_height; -} TextCache; -#else -#endif - -namespace scl -{ -class CSCLGraphicsImplEfl : public CSCLGraphicsImpl -{ -public : - CSCLGraphicsImplEfl(); - ~CSCLGraphicsImplEfl(); - - void init(); - void fini(); - - scldrawing draw_image(sclwindow window, const scldrawctx draw_ctx, sclchar* image_path, SclImageCachedInfo *cachedinfo, - sclint dest_x, sclint dest_y, sclint dest_width, sclint dest_height, - sclint src_x, sclint src_y, sclint src_width, sclint src_height, sclboolean extrace_image); - sclimage load_image(const sclchar* image_path); - void unload_image(sclimage image_data); - - sclfont create_font(const SclFontInfo& info); - void destroy_font(sclfont font); - scldrawing draw_text(sclwindow window, const scldrawctx draw_ctx, const SclFontInfo& font_info, const SclColor& color, - const sclchar *str, SclTextCachedInfo *cachedinfo, sclint pos_x, sclint pos_y, sclint width, sclint height, - SCLLabelAlignment align, sclint padding_x, sclint padding_y, sclint inner_width, sclint inner_height); - - scldrawing draw_rectangle(sclwindow window, const scldrawctx draw_ctx, scldouble pos_x, scldouble pos_y, - scldouble width, scldouble height, const scldouble line_width, const SclColor& line_color, - sclboolean fill, const SclColor& fill_color, scldouble radius, sclfloat alpha); - scldrawctx begin_paint(const sclwindow window, const sclboolean force_draw = FALSE); - void end_paint(const sclwindow window, scldrawctx draw_ctx); - SclSize get_image_size(sclchar* image_path); - SclSize get_text_size(const SclFontInfo &fontinfo, const sclchar *str); - - void register_atspi_object(sclwindow window, scldrawing drawing, const sclchar* name); - -private: - Evas_Object *m_highlight_ui_object; -}; -} /* End of scl namespace */ -#endif diff --git a/scl/sclgraphics-nui.cpp b/scl/sclgraphics-nui.cpp new file mode 100644 index 0000000..98c9fb8 --- /dev/null +++ b/scl/sclgraphics-nui.cpp @@ -0,0 +1,1079 @@ +/* + * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sclgraphics-nui.h" +#include "sclimageproxy.h" +#include "sclfontproxy.h" +#include "scldebug.h" +#include "sclwindows.h" +#include "sclresourcecache.h" +#include "sclwindows-nui.h" +#include "sclutils.h" + +#include +#include +#include +//#include +#include +#include + +//#define EXTRACT_PARTIMAGE + +#ifdef TEST_NEWBACKEND +std::vector g_ImageCache; +std::vector g_TextCache; +sclint hash_string(const sclchar* str) { + sclint ret = 0; + sclint len = strlen(str); + for (sclint loop = 0;loop < len && str[loop];loop++) { + ret = ((loop + 1) * str[loop]); + } + + return ret; +} +#else +#endif +using namespace scl; + +extern void mouse_press(void *data, Evas *e, Evas_Object *object, void *event_info); +extern void mouse_release(void *data, Evas *e, Evas_Object *object, void *event_info); +extern void mouse_move(void *data, Evas *e, Evas_Object *object, void *event_info); + +static std::map _nine_patch_map; + +/** + * Constructor + */ +CSCLGraphicsImplNui::CSCLGraphicsImplNui() +{ + SCL_DEBUG(); + /* Initializes all window resources */ + m_highlight_ui_object = NULL; + m_backend_callback = NULL; + m_backend_callback_data = NULL; +} + +/** + * De-constructor + */ +CSCLGraphicsImplNui::~CSCLGraphicsImplNui() +{ + SCL_DEBUG(); + + fini(); +} + +void CSCLGraphicsImplNui::init() +{ + m_highlight_ui_object = NULL; + m_backend_callback = NULL; + m_backend_callback_data = NULL; +} + +void CSCLGraphicsImplNui::fini() +{ + if (m_highlight_ui_object) { + evas_object_del(m_highlight_ui_object); + m_highlight_ui_object = NULL; + } + + m_backend_callback = NULL; + m_backend_callback_data = NULL; +} + +Evas_Object* extract_partimage_from_fullimage( + Evas_Object* fullimage, + int img_x, int img_y, + int cell_x, int cell_y, + int cell_cx, int cell_cy) +{ + unsigned int *data; + unsigned int *t_data; + int i, j; + int w, h; + Evas_Object *image_ob; + + if (fullimage == NULL) { + return NULL; + } + evas_object_image_size_get(fullimage, &w, &h); + + data = (unsigned int*)evas_object_image_data_get(fullimage, 0); + if (data == NULL) { + return NULL; + } + + t_data = (unsigned int*)malloc(sizeof(unsigned int)*cell_cx*cell_cy); + if (t_data == NULL) { + return NULL; + } + + for (i=img_y; i < img_y+cell_cy; i++) { + for (j=img_x; j < img_x+cell_cx; j++) { + t_data[(i-img_y)*cell_cx+(j-img_x)] = data[i*w+j]; + } + } + + image_ob = evas_object_image_add(evas_object_evas_get(fullimage)); + if (image_ob == NULL) { + free(t_data); + return NULL; + } + evas_object_image_size_set(image_ob, cell_cx, cell_cy); + evas_object_image_data_set(image_ob, t_data); + evas_object_image_fill_set(image_ob, 0, 0, cell_cx, cell_cy); + evas_object_resize(image_ob, cell_cx, cell_cy); + + evas_object_show(image_ob); + + return image_ob; +} + +static sclboolean check_nine_patch_png_file(const char *image_path) +{ + sclboolean found = FALSE; + for (sclint loop = strlen(image_path);!found && loop > 0;loop--) { + if (image_path[loop] == '.') { + found = TRUE; + if (loop >= 2) { // for checking prefix ".#" and ".9" + if (strcasecmp(image_path + loop - 2, ".#.png") == 0 || + strcasecmp(image_path + loop - 2, ".9.png") == 0) { + return TRUE; + } + } + } + } + return FALSE; +} + +SclNinePatchInfo get_nine_patch_info_from_png_file(Evas_Object *image_data, sclint w, sclint h) +{ + /* FIXME : Assuming we're dealing with 32bit image, need to check if there's any other cases */ + SclNinePatchInfo ret = {0}; + unsigned int *data = (unsigned int*)evas_object_image_data_get(image_data, EINA_FALSE); + if (data) { + int x, y; + sclboolean found; + found = FALSE; + for (x = 0;x < w && !found;x++) { + if (data[x] > 0) { + found = TRUE; + ret.left = x; + } + } + found = FALSE; + for (x = w - 1;x >= 0 && !found;x--) { + if (data[x] > 0) { + found = TRUE; + ret.right = w - (x + 1); + } + } + found = FALSE; + for (y = 0;y < h && !found;y++) { + if (data[y * w] > 0) { + found = TRUE; + ret.top = y; + } + } + found = FALSE; + for (y = h - 1;y >= 0 && !found;y--) { + if (data[y * w] > 0) { + found = TRUE; + ret.bottom = h - (y + 1); + } + } + } + return ret; +} + +extern sclint magnifierx, magnifiery; +scldrawing +CSCLGraphicsImplNui::draw_image(sclwindow window, const scldrawctx draw_ctx, sclchar* image_path, SclImageCachedInfo *cachedinfo, + sclint dest_x, sclint dest_y, sclint dest_width, sclint dest_height, + sclint src_x, sclint src_y, sclint src_width, sclint src_height, sclboolean extrace_image) +{ + SCL_DEBUG(); + + scl_assert_return_null(image_path); + + LOGI("image path(%s), x(%d), y(%d), w(%d), h(%d)", image_path, dest_x, dest_y, dest_width, dest_height); + + if (m_backend_callback) { + LOGI("call draw image callback"); + SCL_DEBUG_ELAPSED_TIME_START(); + m_backend_callback->on_draw_image(image_path, dest_x, dest_y, dest_width, dest_height, src_x, src_y, src_width, src_height, m_backend_callback_data); + SCL_DEBUG_ELAPSED_TIME_END(); + } + else { + LOGW("### No draw image callback ###"); + } + + return NULL; + + CSCLResourceCache *cache = CSCLResourceCache::get_instance(); + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLUtils *utils = CSCLUtils::get_instance(); + SclWindowContext *window_context = NULL; + SclWindowContext *target_window_context = NULL; + if (windows && window) { + //window_context = windows->get_window_context(window, FALSE); + window_context = windows->get_window_context(window); + //target_window_context = windows->get_window_context(draw_ctx, FALSE); + target_window_context = windows->get_window_context(draw_ctx); + } + + if (window_context && target_window_context && image_path && utils && cache && windows) { + sclboolean is_highlight_ui = FALSE; + sclchar buf[_POSIX_PATH_MAX] = {0}; + utils->get_decomposed_path(buf, IMG_PATH_PREFIX, image_path); + if (strcmp(buf, SCL_HIGHLIGHT_UI_IMAGE) == 0) { + is_highlight_ui = TRUE; + } + + if (strlen(image_path) > 0) { +#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW + if (window == windows->get_magnifier_window()) { + dest_x += magnifierx; + dest_y += magnifiery; + } +#endif +#ifdef TEST_NEWBACKEND + sclboolean bFound = FALSE; + sclboolean bOrgSizeMinusOne = (src_width == -1 && src_height == -1); + sclint hashval = hash_string(image_path); + /*for(std::list::iterator iter = g_ImageCache.begin(); + bFound && iter != g_ImageCache.end();std::advance(iter, 1)) {*/ + for (sclint loop = 0;loop < (sclint)g_ImageCache.size() && !bFound;loop++) { + if ( + /* (*iter).used && + window == (*iter).window && + hashval == (*iter).imgPathHash && + dest_x == (*iter).dest_x && + dest_y == (*iter).dest_y && + dest_width == (*iter).dest_width && + dest_height == (*iter).dest_height && + src_x == (*iter).src_x && + src_y == (*iter).src_y && + src_width == (*iter).src_width && + src_height == (*iter).src_height && + extrace_image == (*iter).extrace_image*/ + g_ImageCache[loop].used && + window == g_ImageCache[loop].window && + hashval == g_ImageCache[loop].imgPathHash && + dest_x == g_ImageCache[loop].dest_x && + dest_y == g_ImageCache[loop].dest_y && + dest_width == g_ImageCache[loop].dest_width && + dest_height == g_ImageCache[loop].dest_height && + src_x == g_ImageCache[loop].src_x && + src_y == g_ImageCache[loop].src_y && + src_width == g_ImageCache[loop].src_width && + src_height == g_ImageCache[loop].src_height && + extrace_image == g_ImageCache[loop].extrace_image + ) + { + //if (strcmp(image_path, (*iter).image_path) == 0) { + if (strcmp(image_path, g_ImageCache[loop].image_path) == 0) { + bFound = TRUE; + //evas_object_show((*iter).image); + evas_object_show(g_ImageCache[loop].image); + evas_object_raise(g_ImageCache[loop].image); + if (g_ImageCache[loop].clipper) { + evas_object_show(g_ImageCache[loop].clipper); + evas_object_raise(g_ImageCache[loop].clipper); + } + } + } + } + if (!bFound) { +#endif + EFLObject *clip_object = NULL; + + Evas_Object *window_object = (Evas_Object*)window; + if (window_context->is_virtual) { + window_object = static_cast(windows->get_base_window()); + } + + Evas *evas = evas_object_evas_get(window_object); + Evas_Object *image_object = NULL; + if (is_highlight_ui && m_highlight_ui_object) { + image_object = m_highlight_ui_object; + const SclNinePatchInfo *nine_patch_info = utils->get_nine_patch_info(image_path); + if (nine_patch_info) { + evas_object_image_border_set(image_object, + nine_patch_info->left, nine_patch_info->right, nine_patch_info->top, nine_patch_info->bottom); + } + evas_object_move(image_object, dest_x, dest_y); + evas_object_raise(image_object); + evas_object_show(image_object); + } else { + EFLObject *object = new EFLObject; + if (object) { + image_object = evas_object_image_add(evas); + object->extracted = FALSE; + + if (image_object) { + int image_width = 0; + int image_height = 0; + evas_object_image_file_set(image_object, image_path, NULL); + evas_object_image_size_get(image_object, &image_width, &image_height); + + sclboolean is_nine_patch_png = check_nine_patch_png_file(image_path); + if (is_nine_patch_png) { + std::map::iterator it = _nine_patch_map.find(image_path); + if (it != _nine_patch_map.end()) { + evas_object_image_border_set(image_object, + (*it).second.left, (*it).second.right, (*it).second.top, (*it).second.bottom); + } else { + SclNinePatchInfo info = get_nine_patch_info_from_png_file(image_object, image_width, image_height); + evas_object_image_border_set(image_object, info.left, info.right, info.top, info.bottom); + _nine_patch_map[std::string(image_path)] = info; + } + } else if (cachedinfo) { + evas_object_image_border_set(image_object, + cachedinfo->nine_patch_left, + cachedinfo->nine_patch_right, + cachedinfo->nine_patch_top, + cachedinfo->nine_patch_bottom); + } else { + const SclNinePatchInfo *nine_patch_info = utils->get_nine_patch_info(image_path); + if (nine_patch_info) { + evas_object_image_border_set(image_object, + nine_patch_info->left, nine_patch_info->right, nine_patch_info->top, nine_patch_info->bottom); + } + } + const SclLayout *layout = cache->get_cur_layout(window); + if (layout) { + if (layout->display_mode == DISPLAYMODE_PORTRAIT) { + image_width = utils->get_scaled_x(image_width); + image_height = utils->get_scaled_y(image_height); + } else { + image_width = utils->get_scaled_y(image_width); + image_height = utils->get_scaled_x(image_height); + } + } + if (src_width == -1 && src_height == -1) { + src_width = image_width; + src_height = image_height; + } + if ((src_width > 0 && src_height > 0) && + (image_width != dest_width || image_height != dest_height) && extrace_image) { + #ifdef EXTRACT_PARTIMAGE + Evas_Object *newobj = extract_partimage_from_fullimage(image_object, src_x, src_y, 0, 0, src_width, src_height); + object->extracted = TRUE; + evas_object_del(image_object); + image_object = newobj; + evas_object_move(image_object, dest_x, dest_y); + if (dest_width > 0 && dest_height > 0) { + evas_object_image_fill_set(image_object, 0, 0, dest_width, dest_height); + evas_object_resize(image_object, dest_width, dest_height); + } + #else + //evas_object_move(image_object, src_x - dest_x, src_y - dest_y); + evas_object_move(image_object, dest_x - src_x, dest_y - src_y); + evas_object_image_fill_set(image_object, 0, 0, image_width, image_height); + evas_object_resize(image_object, image_width, image_height); + + Evas_Object *clipper = evas_object_rectangle_add(evas); + evas_object_color_set(clipper, 255, 255, 255, 255); + //evas_object_color_set(clipper, 0, 0, 0, 0); + evas_object_move(clipper, dest_x, dest_y); + evas_object_resize(clipper, dest_width, dest_height); + evas_object_clip_set(image_object, clipper); + evas_object_show(clipper); + + clip_object = new EFLObject; + if (clip_object) { + clip_object->object = clipper; + clip_object->type = EFLOBJECT_CLIPOBJECT; + clip_object->position.x = dest_x; + clip_object->position.y = dest_y; + clip_object->position.width = dest_width; + clip_object->position.height = dest_height; + clip_object->etc_info = image_path; + clip_object->extracted = FALSE; + clip_object->data = NULL; + } + #endif + } else { + evas_object_move(image_object, dest_x, dest_y); + if (dest_width > 0 && dest_height > 0) { + if (is_nine_patch_png) { + evas_object_image_fill_set(image_object, -1, -1, dest_width + 2, dest_height + 2); + } else { + evas_object_image_fill_set(image_object, 0, 0, dest_width, dest_height); + } + evas_object_resize(image_object, dest_width, dest_height); + } + } + evas_object_raise(image_object); + evas_object_show(image_object); + + //evas_object_event_callback_add((Evas_Object*)image_object, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, window); + /*evas_object_event_callback_add((Evas_Object*)image_object, EVAS_CALLBACK_MOUSE_UP, mouse_release, window); + evas_object_event_callback_add((Evas_Object*)image_object, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, window);*/ + + object->object = image_object; + object->type = EFLOBJECT_IMAGE; + object->position.x = dest_x; + object->position.y = dest_y; + object->position.width = dest_width; + object->position.height = dest_height; + object->etc_info = image_path; + object->data = clip_object; + + if (is_highlight_ui) { + delete object; + } else { + target_window_context->etc_info = + eina_list_append((Eina_List*)(target_window_context->etc_info), object); + if (clip_object) { + target_window_context->etc_info = + eina_list_append((Eina_List*)(target_window_context->etc_info), clip_object); + } + } + + /* FIXME : this is for placing the background image at the lowest depth */ + sclint window_layer = 29000; + if (!windows->is_base_window(reinterpret_cast(draw_ctx))) { + window_layer = 29010; + } + //SclRectangle rt; + //windows->get_window_rect(window, &rt); + //if (rt.width == dest_width && rt.height == dest_height) { + if (window_context->geometry.width == dest_width && + window_context->geometry.height == dest_height) { + //evas_object_lower(image_object); + evas_object_layer_set(image_object, window_layer + 0); + } else { + evas_object_layer_set(image_object, window_layer + 1); + } + return image_object; + } else { + delete object; + object = NULL; + } + } + } +#ifdef TEST_NEWBACKEND + ImageCache cache; + cache.used = true; + cache.window = window; + strncpy(cache.image_path, image_path, sizeof(cache.image_path)); + cache.imgPathHash = hashval; + cache.dest_x = dest_x; + cache.dest_y = dest_y; + cache.dest_width = dest_width; + cache.dest_height = dest_height; + cache.src_x = src_x; + cache.src_y = src_y; + if (bOrgSizeMinusOne) { + cache.src_width = -1; + cache.src_height = -1; + } else { + cache.src_width = src_width; + cache.src_height = src_height; + } + cache.extrace_image = extrace_image; + cache.image = object->object; + if (clip_object) { + cache.clipper = clip_object->object; + } else { + cache.clipper = NULL; + } + + //g_ImageCache.insert(g_ImageCache.end(), cache); + sclboolean bInserted = FALSE; + for (sclint loop = 0;loop < (sclint)g_ImageCache.size() && !bInserted;loop++) { + if (!g_ImageCache[loop].used) { + g_ImageCache[loop] = cache; + } + } + if (!bInserted) { + g_ImageCache.push_back(cache); + } + } +#endif + } + } + return NULL; +} + +sclimage +CSCLGraphicsImplNui::load_image(const sclchar *image_path) +{ + SCL_DEBUG(); + return NULL; +} + +void +CSCLGraphicsImplNui::unload_image(sclimage image_data) +{ + SCL_DEBUG(); +} + +/** + * Initializes the drawing context for double-buffering. + * This func should be called before using a drawing primitive at first. + */ +scldrawctx +CSCLGraphicsImplNui::begin_paint(const sclwindow window, const sclboolean force_draw /* = FALSE */) +{ + SCL_DEBUG(); + + scldrawctx drawctx = reinterpret_cast(window); + LOGD(""); + + return drawctx; +} + +/** + * Notices that drawing tasks have done. + */ +void +CSCLGraphicsImplNui::end_paint(const sclwindow window, scldrawctx draw_ctx) +{ + //Evas_Object *window_object = (Evas_Object*)window; + //Evas *evas = evas_object_evas_get(window_object); + //evas_render_idle_flush(evas); + + LOGD(""); +} + +sclfont +CSCLGraphicsImplNui::create_font(const SclFontInfo& info) +{ + return NULL; +} + +void +CSCLGraphicsImplNui::destroy_font(sclfont font) +{ +} + +/** + * Draws the given text on cairo-surface + */ +scldrawing +CSCLGraphicsImplNui::draw_text(sclwindow window, const scldrawctx draw_ctx, const SclFontInfo& font_info, const SclColor& color, + const sclchar *str, SclTextCachedInfo *cachedinfo, sclint pos_x, sclint pos_y, sclint width, sclint height, + SCLLabelAlignment align, sclint padding_x, sclint padding_y, + sclint inner_width, sclint inner_height) +{ + SCL_DEBUG(); + /* + CSCLWindows *windows = CSCLWindows::get_instance(); + SclWindowContext *window_context = NULL; + SclWindowContext *target_window_context = NULL; + */ + + LOGD("str(%s), x(%d), y(%d), w(%d), h(%d), pad_x(%d), pad_y(%d), fontsize(%d)", str, pos_x, pos_y, width, height, padding_x, padding_y, font_info.font_size); + + if (m_backend_callback) { + LOGI("call draw text callback"); + SCL_DEBUG_ELAPSED_TIME_START(); + m_backend_callback->on_draw_text(font_info, color, str, pos_x, pos_y, width, height, align, padding_x, padding_y, inner_width, inner_height, m_backend_callback_data); //draw_text_cb_data); + SCL_DEBUG_ELAPSED_TIME_END(); + } + else { + LOGW("### No draw text callback ###"); + } + + /* + if (draw_text_cb) { + LOGI("call draw text callback"); + draw_text_cb(str, pos_x, pos_y, width, height, font_info.font_size, draw_text_cb_data); + } + else + LOGW("### No draw text callback ###"); + */ + +#if 0 + if (windows && window) { + //window_context = windows->get_window_context(window, FALSE); + window_context = windows->get_window_context(window); + //target_window_context = windows->get_window_context(draw_ctx, FALSE); + target_window_context = windows->get_window_context(draw_ctx); + } + + if (window_context && target_window_context && str && windows) { + if (strlen(str) > 0) { +#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW + if (window == windows->get_magnifier_window()) { + pos_x += magnifierx; + pos_y += magnifiery; + } +#endif +#ifdef TEST_NEWBACKEND + sclboolean bFound = FALSE; + sclint hashval = hash_string(str); + sclint org_posx = pos_x; + sclint org_posy = pos_y; + /*for(std::list::iterator iter = g_TextCache.begin(); + bFound && iter != g_TextCache.end();std::advance(iter, 1)) {*/ + for (sclint loop = 0;loop < (sclint)g_TextCache.size() && !bFound;loop++) { + if ( + /* + (*iter).used && + window == (*iter).window && + strncmp(font_info.font_name, (*iter).font_info.font_name, MAX_FONT_NAME_LEN) == 0 && + font_info.font_size == (*iter).font_info.font_size && + font_info.is_bold == (*iter).font_info.is_bold && + font_info.is_italic == (*iter).font_info.is_italic && + memcmp(&color, &((*iter).color), sizeof(SclColor)) == 0 && + hashval == (*iter).strHash && + pos_x == (*iter).pos_x&& + pos_y == (*iter).pos_y && + width == (*iter).width && + height == (*iter).height && + align == (*iter).align && + padding_x == (*iter).padding_x && + padding_y == (*iter).padding_y && + inner_width == (*iter).inner_width && + inner_height == (*iter).inner_height */ + + g_TextCache[loop].used && + window == g_TextCache[loop].window && + strncmp(font_info.font_name, g_TextCache[loop].font_info.font_name, MAX_FONT_NAME_LEN) == 0 && + font_info.font_size == g_TextCache[loop].font_info.font_size && + font_info.is_bold == g_TextCache[loop].font_info.is_bold && + font_info.is_italic == g_TextCache[loop].font_info.is_italic && + memcmp(&color, &(g_TextCache[loop].color), sizeof(SclColor)) == 0 && + hashval == g_TextCache[loop].strHash && + pos_x == g_TextCache[loop].pos_x&& + pos_y == g_TextCache[loop].pos_y && + width == g_TextCache[loop].width && + height == g_TextCache[loop].height && + align == g_TextCache[loop].align && + padding_x == g_TextCache[loop].padding_x && + padding_y == g_TextCache[loop].padding_y && + inner_width == g_TextCache[loop].inner_width && + inner_height == g_TextCache[loop].inner_height + ) + { + //if (strcmp(str, (*iter).str) == 0) { + if (strcmp(str, g_TextCache[loop].str) == 0) { + bFound = TRUE; + //evas_object_show((*iter).text); + evas_object_show(g_TextCache[loop].text); + evas_object_raise(g_TextCache[loop].text); + } + } + } + if (!bFound) { +#endif + + EFLObject *object = new EFLObject; + if (object) { + object->extracted = FALSE; + Evas_Object *window_object = (Evas_Object*)window; + if (window_context->is_virtual) { + window_object = static_cast(windows->get_base_window()); + } + Evas *evas = evas_object_evas_get(window_object); + Evas_Object *text_object = evas_object_textblock_add(evas); + + if (text_object) { + if (inner_width > 0 || inner_height > 0) { + SclPoint bottom_right; + bottom_right.x = pos_x + width; + bottom_right.y = pos_y + height; + + /* The inner width and height value should be bigger than 0 */ + if (inner_width <= 0) inner_width = width; + if (inner_height <= 0) inner_height = height; + + /* The inner width and height value should not exceed the actual width and height */ + if (inner_width > width) inner_width = width; + if (inner_height > height) inner_height = height; + + /* We need to make a inner rectangle if inner_width and inner_height are not 0 */ + if (align == LABEL_ALIGN_CENTER_TOP || + align == LABEL_ALIGN_CENTER_MIDDLE || + align == LABEL_ALIGN_CENTER_BOTTOM) { + pos_x = pos_x + ((width - inner_width) / 2) + padding_x; + } else if (align == LABEL_ALIGN_RIGHT_TOP || + align == LABEL_ALIGN_RIGHT_MIDDLE || + align == LABEL_ALIGN_RIGHT_BOTTOM) { + pos_x = pos_x + (width - inner_width) - padding_x; + } else { + pos_x += padding_x; + } + if (align == LABEL_ALIGN_LEFT_MIDDLE || + align == LABEL_ALIGN_CENTER_MIDDLE || + align == LABEL_ALIGN_RIGHT_MIDDLE) { + pos_y = pos_y + ((height - inner_height) / 2) + padding_y; + } else if (align == LABEL_ALIGN_LEFT_BOTTOM || + align == LABEL_ALIGN_CENTER_BOTTOM || + align == LABEL_ALIGN_RIGHT_BOTTOM) { + pos_y = pos_y + (height - inner_height) - padding_y; + } else { + pos_y += padding_y; + } + + /* Make sure the inner bounding box does not exceed the original bounding box */ + if (pos_x + inner_width > bottom_right.x) { + width = bottom_right.x - pos_x; + } else { + width = inner_width; + } + if (pos_y + inner_height > bottom_right.y) { + height = bottom_right.y - pos_y; + } else { + height = inner_height; + } + + align = LABEL_ALIGN_CENTER_MIDDLE; + padding_x = 0; + padding_y = 0; + } + + sclchar strStyle[256]; + snprintf(strStyle, 256, + "DEFAULT='font=%s font_size=%d align=%s color=#%02X%02X%02X%02X wrap=word left_margin=%d right_margin=%d'", + font_info.font_name, font_info.font_size, + (((int)align % 3) == 1) ? "center" : ((((int)align % 3) == 2) ? "right" : "left"), + color.r, color.g, color.b, color.a, padding_x, padding_x); + + Evas_Textblock_Style *st; + st = evas_textblock_style_new(); + evas_textblock_style_set(st, strStyle); + evas_object_textblock_style_set(text_object, st); + //evas_textblock_style_free(st); + + //evas_object_textblock_clear(text_object); + char *markup = evas_textblock_text_utf8_to_markup(text_object, str); + if (markup) { + evas_object_textblock_text_markup_set(text_object, markup); + free(markup); + } + evas_object_resize(text_object, width, height); + + object->extracted = FALSE; + object->type = EFLOBJECT_TEXTBLOCK; + object->object = text_object; + object->position.x = pos_x; + object->position.y = pos_y; + object->position.width = width; + object->position.height = height; + object->etc_info = str; + object->data = st; + + sclint calwidth, calheight; + if (cachedinfo) { + calwidth = cachedinfo->actual_size.width; + calheight = cachedinfo->actual_size.height; + } else { + evas_object_textblock_size_native_get(text_object, &calwidth, &calheight); + } + // FIXME: float to int may loose precision + if (calwidth > 0) { + static float _SPACE_RATE = 0.1; + calwidth *= 1 + _SPACE_RATE; + } + if (calheight > 0) { + static float _SPACE_RATE = 0.1; + calheight *= 1 + _SPACE_RATE; + } + + if (calwidth > width || calheight > height) { + sclfloat width_rate = (sclfloat)width / (sclfloat)calwidth; + sclfloat height_rate = (sclfloat)height / (sclfloat)calheight; + sclfloat resize_rate = height_rate; + if (width_rate < height_rate) { + resize_rate = width_rate; + } + + snprintf(strStyle, 128, + "DEFAULT='font=%s font_size=%d align=%s color=#%02X%02X%02X%02X wrap=word left_margin=%d right_margin=%d'", + font_info.font_name, + (int)(SCL_LABEL_OVERLENGTH_TEXT_RESIZE_RATE * font_info.font_size * resize_rate), + (((int)align % 3) == 1) ? "center" : ((((int)align % 3) == 2) ? "right" : "left"), + color.r, color.g, color.b, color.a, padding_x, padding_x); + evas_textblock_style_set(st, strStyle); + evas_object_textblock_style_set(text_object, st); + markup = evas_textblock_text_utf8_to_markup(text_object, str); + if (markup) { + evas_object_textblock_text_markup_set(text_object, markup); + free(markup); + } + evas_object_resize(text_object, width, height); + LOGI("[1] text object w: %d, h : %d", width, height); + evas_object_textblock_size_native_get(text_object, &calwidth, &calheight); + } + + /*if (align == LABEL_ALIGN_CENTER_TOP || align == LABEL_ALIGN_CENTER_MIDDLE || align == LABEL_ALIGN_CENTER_BOTTOM) { + pos_x = pos_x + ((width - calwidth) / 2) + padding_x; + } else if (align == LABEL_ALIGN_RIGHT_TOP || align == LABEL_ALIGN_RIGHT_MIDDLE || align == LABEL_ALIGN_RIGHT_BOTTOM) { + pos_x = pos_x + (width - calwidth) - padding_x; + } else { + pos_x += padding_x; + }*/ + if (align == LABEL_ALIGN_LEFT_MIDDLE || + align == LABEL_ALIGN_CENTER_MIDDLE || + align == LABEL_ALIGN_RIGHT_MIDDLE) { + pos_y = pos_y + ((height - calheight) / 2) + padding_y; + } else if (align == LABEL_ALIGN_LEFT_BOTTOM || + align == LABEL_ALIGN_CENTER_BOTTOM || + align == LABEL_ALIGN_RIGHT_BOTTOM) { + pos_y = pos_y + (height - calheight) - padding_y; + } else { + pos_y += padding_y; + } + + LOGI("[2] text object x: %d, y: %d, w: %d, h: %d", pos_x, pos_y, width, height); + + evas_object_move(text_object, pos_x, pos_y); + evas_object_raise(text_object); + evas_object_show(text_object); + + //evas_object_event_callback_add((Evas_Object*)text_object, EVAS_CALLBACK_MOUSE_DOWN, mouse_press, window); + /*evas_object_event_callback_add((Evas_Object*)text_object, EVAS_CALLBACK_MOUSE_UP, mouse_release, window); + evas_object_event_callback_add((Evas_Object*)text_object, EVAS_CALLBACK_MOUSE_MOVE, mouse_move, window);*/ + + target_window_context->etc_info = + eina_list_append((Eina_List*)(target_window_context->etc_info), object); + + sclint window_layer = 29000; + if (!windows->is_base_window(reinterpret_cast(draw_ctx))) { + window_layer = 29010; + } + evas_object_layer_set(text_object, window_layer + 1); + return text_object; + } else { + delete object; + object = NULL; + } + } +#ifdef TEST_NEWBACKEND + TextCache cache; + cache.used = true; + cache.window = window; + cache.font_info = font_info; + cache.color = color; + strncpy(cache.font_info.font_name, font_info.font_name, MAX_FONT_NAME_LEN); + cache.font_info.font_size = font_info.font_size; + cache.font_info.is_bold = font_info.is_bold; + cache.font_info.is_italic = font_info.is_italic; + memcpy(&(cache.color), &(color), sizeof(SclColor)); + strncpy(cache.str, str, sizeof(cache.str)); + cache.strHash = hashval; + cache.pos_x = org_posx; + cache.pos_y = org_posy; + cache.width = width; + cache.height = height; + cache.align = align; + cache.padding_x = padding_x; + cache.padding_y = padding_y; + cache.inner_width = inner_width; + cache.inner_height = inner_height; + + cache.text = object->object; + + //g_TextCache.insert(g_TextCache.end(), cache); + sclboolean bInserted = FALSE; + for (sclint loop = 0;loop < (sclint)g_TextCache.size() && !bInserted;loop++) { + if (!g_TextCache[loop].used) { + g_TextCache[loop] = cache; + } + } + if (!bInserted) { + g_TextCache.push_back(cache); + } + } +#endif /* TEST_NEWBACKEND */ + } + } +#endif /* 0 */ + + return NULL; +} + +/** + * Draws a rectangle on cairo-surface + */ +scldrawing +CSCLGraphicsImplNui::draw_rectangle(sclwindow window, const scldrawctx draw_ctx, scldouble pos_x, scldouble pos_y, + scldouble width, scldouble height, const scldouble line_width, const SclColor& line_color, sclboolean fill, const SclColor& fill_color, scldouble radius, sclfloat alpha) +{ + SCL_DEBUG(); + + LOGI("x(%f), y(%f), w(%f), h(%f)", pos_x, pos_y, width, height); + LOGI("fill(%d), r(%d), g(%d), b(%d), a(%d)", fill, fill_color.r, fill_color.g, fill_color.b, fill_color.a); + + if (m_backend_callback) { + LOGI("call draw rectangle callback"); + SCL_DEBUG_ELAPSED_TIME_START(); + m_backend_callback->on_draw_rectangle(pos_x, pos_y, width, height, fill, fill_color.r, fill_color.g, fill_color.b, fill_color.a, m_backend_callback_data); + SCL_DEBUG_ELAPSED_TIME_END(); + } + else { + LOGW("### No draw text callback ###"); + } + + return NULL; + +#if 0 + CSCLResourceCache *cache = CSCLResourceCache::get_instance(); + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLUtils *utils = CSCLUtils::get_instance(); + SclWindowContext *window_context = NULL; + SclWindowContext *target_window_context = NULL; + + if (windows && window) { + //window_context = windows->get_window_context(window, FALSE); + window_context = windows->get_window_context(window); + //target_window_context = windows->get_window_context(draw_ctx, FALSE); + target_window_context = windows->get_window_context(draw_ctx); + } + + if (window_context && utils && cache && windows && target_window_context) { + EFLObject *object = new EFLObject; + if (object) { + Evas_Object *window_object = (Evas_Object*)window; + if (window_context->is_virtual) { + window_object = static_cast(windows->get_base_window()); + } + + Evas *evas = evas_object_evas_get(window_object); + Evas_Object *rectobj = evas_object_rectangle_add(evas); + + evas_object_color_set(rectobj, fill_color.r, fill_color.g, fill_color.b, fill_color.a); + + evas_object_move(rectobj, pos_x, pos_y); + evas_object_resize(rectobj, width, height); + evas_object_show(rectobj); + + object->extracted = FALSE; + object->object = rectobj; + object->type = EFLOBJECT_RECTANGLE; + object->position.x = pos_x; + object->position.y = pos_y; + object->position.width = width; + object->position.height = height; + object->etc_info = NULL; + object->data = NULL; + + target_window_context->etc_info = + eina_list_append((Eina_List*)(target_window_context->etc_info), object); + + /* FIXME : this is for placing the background image at the lowest depth */ + sclint window_layer = 29000; + if (!windows->is_base_window(reinterpret_cast(draw_ctx))) { + window_layer = 29010; + } + if (window_context->geometry.width == width && + window_context->geometry.height == height) { + evas_object_layer_set(rectobj, window_layer + 0); + } else { + evas_object_layer_set(rectobj, window_layer + 1); + } + return rectobj; + } + } + return NULL; +#endif +} + +SclSize +CSCLGraphicsImplNui::get_image_size(sclchar* image_path) +{ + SCL_DEBUG(); + SclSize ret = { 0, 0 }; + + CSCLWindows *windows = CSCLWindows::get_instance(); + if (!windows) return ret; + + Evas_Object *window_object = (Evas_Object*)(windows->get_base_window()); + Evas_Object *image_object = NULL; + + if (window_object) { + Evas *evas = evas_object_evas_get(window_object); + image_object = evas_object_image_add(evas); + } + + if (image_object) { + int w, h; + evas_object_image_file_set(image_object, image_path, NULL); + evas_object_image_size_get(image_object, &w, &h); + evas_object_del(image_object); + ret.width = w; + ret.height = h; + } + + return ret; +} + +SclSize +CSCLGraphicsImplNui::get_text_size(const SclFontInfo &fontinfo, const sclchar *str) +{ + SCL_DEBUG(); + SclSize ret = { 0, 0 }; + + CSCLWindows *windows = CSCLWindows::get_instance(); + Evas_Object *winobj = NULL; + Evas *evas = NULL; + + if (windows) { + winobj = (Evas_Object*)(windows->get_base_window()); + } + if (winobj) { + evas = evas_object_evas_get(winobj); + } + + int w, h; + + Evas_Textblock_Style *st; + st = evas_textblock_style_new(); + + Evas_Object *text_object = evas_object_textblock_add(evas); + + if (text_object && st) { + const sclint STYLE_STR_LEN = 256; + sclchar strStyle[STYLE_STR_LEN] = {0}; + snprintf(strStyle, STYLE_STR_LEN - 1, "DEFAULT='font=%s font_size=%d'", + fontinfo.font_name, fontinfo.font_size); + + evas_textblock_style_set(st, strStyle); + evas_object_textblock_style_set(text_object, st); + + evas_object_textblock_clear(text_object); + char *markup = evas_textblock_text_utf8_to_markup(text_object, str); + if (markup) { + evas_object_textblock_text_markup_set(text_object, markup); + free(markup); + } + + evas_object_textblock_size_native_get(text_object, &w, &h); + + ret.width = w; + ret.height = h; + } + if (text_object) { + evas_object_del(text_object); + } + if (st) { + evas_textblock_style_free(st); + } + + return ret; +} + +void CSCLGraphicsImplNui::set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data) +{ + m_backend_callback = callback; + m_backend_callback_data = data; +} diff --git a/scl/sclgraphics-nui.h b/scl/sclgraphics-nui.h new file mode 100644 index 0000000..faabf40 --- /dev/null +++ b/scl/sclgraphics-nui.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sclgraphics.h" + +#ifndef __SCL_GRAPHICS_NUI_H__ +#define __SCL_GRAPHICS_NUI_H__ + +//#define DO_NOT_MOVE_MAGNIFIER_WINDOW +//#define FULL_SCREEN_TEST + +#include + +/* Still an experimental feature.. Will be refined after being stabilized */ +//#define TEST_NEWBACKEND +#ifdef TEST_NEWBACKEND +using namespace scl; + +#include +#include + +typedef struct { + sclboolean used; + + Evas_Object *image; + Evas_Object *clipper; + + sclwindow window; + sclchar image_path[_POSIX_PATH_MAX]; + sclint imgPathHash; + sclint dest_x; + sclint dest_y; + sclint dest_width; + sclint dest_height; + sclint src_x; + sclint src_y; + sclint src_width; + sclint src_height; + sclboolean extrace_image; +} ImageCache; + +typedef struct { + sclboolean used; + + Evas_Object *text; + + sclwindow window; + scl::SclFontInfo font_info; + SclColor color; + sclchar str[_POSIX_PATH_MAX];; + sclint strHash; + sclint pos_x; + sclint pos_y; + sclint width; + sclint height; + SCLLabelAlignment align; + sclint padding_x; + sclint padding_y; + sclint inner_width; + sclint inner_height; +} TextCache; +#else +#endif + +namespace scl +{ +class CSCLGraphicsImplNui : public CSCLGraphicsImpl +{ +public : + CSCLGraphicsImplNui(); + ~CSCLGraphicsImplNui(); + + void init(); + void fini(); + + scldrawing draw_image(sclwindow window, const scldrawctx draw_ctx, sclchar* image_path, SclImageCachedInfo *cachedinfo, + sclint dest_x, sclint dest_y, sclint dest_width, sclint dest_height, + sclint src_x, sclint src_y, sclint src_width, sclint src_height, sclboolean extrace_image); + sclimage load_image(const sclchar* image_path); + void unload_image(sclimage image_data); + + sclfont create_font(const SclFontInfo& info); + void destroy_font(sclfont font); + scldrawing draw_text(sclwindow window, const scldrawctx draw_ctx, const SclFontInfo& font_info, const SclColor& color, + const sclchar *str, SclTextCachedInfo *cachedinfo, sclint pos_x, sclint pos_y, sclint width, sclint height, + SCLLabelAlignment align, sclint padding_x, sclint padding_y, sclint inner_width, sclint inner_height); + + scldrawing draw_rectangle(sclwindow window, const scldrawctx draw_ctx, scldouble pos_x, scldouble pos_y, + scldouble width, scldouble height, const scldouble line_width, const SclColor& line_color, + sclboolean fill, const SclColor& fill_color, scldouble radius, sclfloat alpha); + scldrawctx begin_paint(const sclwindow window, const sclboolean force_draw = FALSE); + void end_paint(const sclwindow window, scldrawctx draw_ctx); + SclSize get_image_size(sclchar* image_path); + SclSize get_text_size(const SclFontInfo &fontinfo, const sclchar *str); + + void register_atspi_object(sclwindow window, scldrawing drawing, const sclchar* name); + //void set_draw_text_cb(scl_ui_draw_text_cb callback, void *data); + void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data); + +private: + Evas_Object *m_highlight_ui_object; + ISCLUIGraphicsBackendCallback* m_backend_callback; + void* m_backend_callback_data; +}; +} /* End of scl namespace */ +#endif diff --git a/scl/sclgraphics.cpp b/scl/sclgraphics.cpp index 36856be..deb25d5 100644 --- a/scl/sclgraphics.cpp +++ b/scl/sclgraphics.cpp @@ -22,6 +22,8 @@ #include "sclgraphics-win32.h" #elif defined(__EFL__) #include "sclgraphics-efl.h" +#elif defined(__NUI__) +#include "sclgraphics-nui.h" #elif __GTK__ #include "sclgraphics-gtk.h" #else @@ -71,6 +73,8 @@ CSCLGraphicsImpl* CSCLGraphics::get_scl_graphics_impl() m_impl = new CSCLGraphicsImplWin32; #elif defined(__EFL__) m_impl = new CSCLGraphicsImplEfl; +#elif defined(__NUI__) + m_impl = new CSCLGraphicsImplNui; #elif __GTK__ m_impl = new CSCLGraphicsImplGtk; #else diff --git a/scl/sclgraphics.h b/scl/sclgraphics.h index 1099dc7..105dbe2 100644 --- a/scl/sclgraphics.h +++ b/scl/sclgraphics.h @@ -22,6 +22,8 @@ #include "scltypes.h" #include "sclconfig.h" #include "sclstructs.h" +#include "sclgraphicsbackendcallback.h" +#include "sclgraphicsinfo.h" #ifndef __SCL_GRAPHICS_H__ #define __SCL_GRAPHICS_H__ @@ -32,15 +34,6 @@ namespace scl { -#define MAX_FONT_NAME_LEN 32 -/**@brief font information structure */ -typedef struct _SclFontInfo { - sclchar font_name[MAX_FONT_NAME_LEN]; - sclshort font_size; - sclboolean is_italic; - sclboolean is_bold; -} SclFontInfo; - typedef struct _SclImageCachedInfo { sclint nine_patch_left; sclint nine_patch_right; @@ -52,13 +45,6 @@ typedef struct _SclTextCachedInfo { SclSize actual_size; }SclTextCachedInfo; -typedef void * scldrawing; -const SclColor SCLCOLOR_WHITE = {255, 255, 255, 255}; -const SclColor SCLCOLOR_GREY = {128, 128, 128, 255}; -const SclColor SCLCOLOR_BLACK = {0, 0, 0, 255}; -const SclColor SCLCOLOR_RED = {255, 0, 0, 255}; -const SclColor SCLCOLOR_BLUE = {0, 0, 255, 255}; - /** * @brief The base class to work as a soft-based keyboard * @@ -97,6 +83,7 @@ private: virtual SclSize get_image_size(sclchar* image_path) = 0; virtual SclSize get_text_size(const SclFontInfo &fontinfo, const sclchar *str) = 0; virtual void register_atspi_object(sclwindow window, scldrawing drawing, const sclchar* name) = 0; + virtual void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data) = 0; }; class CSCLGraphics @@ -153,6 +140,10 @@ public : return get_scl_graphics_impl()->register_atspi_object(window, drawing, name); } + void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data) { + return get_scl_graphics_impl()->set_graphics_backend_callback(callback, data); + } + private: sclimage load_image(const sclchar *image_path) { return get_scl_graphics_impl()->load_image(image_path); diff --git a/scl/sclgraphicsbackendcallback.h b/scl/sclgraphicsbackendcallback.h new file mode 100644 index 0000000..93a68f2 --- /dev/null +++ b/scl/sclgraphicsbackendcallback.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __SCL_GRAPHICS_BACKENDCALLBACK_H__ +#define __SCL_GRAPHICS_BACKENDCALLBACK_H__ + +#include "sclgraphicsinfo.h" + +using namespace scl; + +//SCL_BEGIN_DECLS +/* FIXME : Need to check the dependency cause by the next include statement */ + +//typedef void (*scl_ui_draw_text_cb)(const char *str, int x, int y, int w, int h, int fontsize, void* user_data); + +struct ISCLUIGraphicsBackendCallback { + //virtual void on_draw_text(const char *str, int x, int y, int w, int h, int fontsize, void* user_data) { } + virtual void on_draw_text(const SclFontInfo& font_info, const SclColor& color, const char *str, int pos_x, int pos_y, int w, int h, + SCLLabelAlignment align, int padding_x, int padding_y, int inner_width, int inner_height, void* user_data) { } + + /* + const SclFontInfo& font_info, const SclColor& color, + const sclchar *str, SclTextCachedInfo *cachedinfo, sclint pos_x, sclint pos_y, sclint width, sclint height, + SCLLabelAlignment align, sclint padding_x, sclint padding_y, + sclint inner_width, sclint inner_height) + */ + + virtual void on_draw_image(const char *image_path, int dest_x, int dest_y, int dest_weight, int dest_height, int src_x, int src_y, int src_width, int src_height, void* user_data) { } + + virtual void on_draw_rectangle(int pos_x, int pos_y, int width, int height, bool fill, int fill_color_r, int fill_color_g, int fill_color_b, int fill_color_a, void* user_data) { } + + //virtual void update_window(int x, int w, int width, int height, void* user_data) { } + + //virtual void on_draw_image(const char *str, int x, int y, int w, int h, int fontsize, void* user_data) { } +}; + +#endif //__SCL_GRAPHICS_BACKENDCALLBACK_H__ diff --git a/scl/sclgraphicsinfo.h b/scl/sclgraphicsinfo.h new file mode 100644 index 0000000..754d32f --- /dev/null +++ b/scl/sclgraphicsinfo.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include + +#include "scltypes.h" +#include "sclconfig.h" +#include "sclstructs.h" + +#ifndef __SCL_GRAPHICS_INFO_H__ +#define __SCL_GRAPHICS_INFO_H__ + +#ifdef __cplusplus +//SCL_BEGIN_DECLS +#endif + +namespace scl +{ +#define MAX_FONT_NAME_LEN 32 +/**@brief font information structure */ +typedef struct _SclFontInfo { + sclchar font_name[MAX_FONT_NAME_LEN]; + sclshort font_size; + sclboolean is_italic; + sclboolean is_bold; +} SclFontInfo; + +typedef void * scldrawing; +const SclColor SCLCOLOR_WHITE = {255, 255, 255, 255}; +const SclColor SCLCOLOR_GREY = {128, 128, 128, 255}; +const SclColor SCLCOLOR_BLACK = {0, 0, 0, 255}; +const SclColor SCLCOLOR_RED = {255, 0, 0, 255}; +const SclColor SCLCOLOR_BLUE = {0, 0, 255, 255}; + +} /* End of scl namespace */ + +#ifdef __cplusplus +//SCL_END_DECLS +#endif + +#endif //__SCL_GRAPHICS_INFO_H__ diff --git a/scl/sclui.cpp b/scl/sclui.cpp index c243563..0579f8d 100644 --- a/scl/sclui.cpp +++ b/scl/sclui.cpp @@ -85,6 +85,22 @@ CSCLUI::set_ui_event_callback(ISCLUIEventCallback *callback, const sclchar *inpu } } +void +CSCLUI::set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data) +{ + if (m_impl) { + m_impl->set_graphics_backend_callback(callback, data); + } +} + +void +CSCLUI::set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data) +{ + if (m_impl) { + m_impl->set_window_backend_callback(callback, data); + } +} + /** * Sets the current input mode to the given mode * @Usage diff --git a/scl/sclui.h b/scl/sclui.h index fdd00eb..484dab0 100644 --- a/scl/sclui.h +++ b/scl/sclui.h @@ -22,6 +22,8 @@ #include "sclconfig.h" #include "sclstructs.h" #include "scleventcallback.h" +#include "sclgraphicsbackendcallback.h" +#include "sclwindowbackendcallback.h" //SCL_BEGIN_DECLS @@ -450,6 +452,10 @@ public: * @return non-zero value is returned when successful */ sclboolean get_button_geometry(const sclchar* custom_id, SclRectangle *rectangle); + + void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data); + + void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data); private: CSCLUIImpl *m_impl; }; diff --git a/scl/scluibuilder.cpp b/scl/scluibuilder.cpp index c104ca3..a71528b 100644 --- a/scl/scluibuilder.cpp +++ b/scl/scluibuilder.cpp @@ -1303,3 +1303,31 @@ CSCLUIBuilder::draw_magnifier_label(const sclwindow window, const scldrawctx dra } return TRUE; } + +void +CSCLUIBuilder::set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data) +{ + CSCLGraphics *graphics = CSCLGraphics::get_instance(); + + if (graphics) + graphics->set_graphics_backend_callback(callback, data); +} + +void +CSCLUIBuilder::set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data) +{ + CSCLUtils *utils = CSCLUtils::get_instance(); + + if (m_gwes) { + if (m_gwes->m_windows) + m_gwes->m_windows->set_window_backend_callback(callback, data); + else { + if (utils) + utils->log("No window"); + } + } + else { + if (utils) + utils->log("No GWES"); + } +} diff --git a/scl/scluibuilder.h b/scl/scluibuilder.h index 4af8942..67f4370 100644 --- a/scl/scluibuilder.h +++ b/scl/scluibuilder.h @@ -19,6 +19,8 @@ #include #include "sclgwes.h" #include "sclutils.h" +#include "sclgraphicsbackendcallback.h" +#include "sclwindowbackendcallback.h" #ifndef __SCL_UIBUILDER_H__ #define __SCL_UIBUILDER_H__ @@ -51,6 +53,9 @@ public: sclboolean show_magnifier(const sclwindow window, scldrawctx draw_ctx); sclboolean show_autopopup(const sclwindow parent, scldrawctx draw_ctx, const scl16 key_index); + void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data); + void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data); + private: sclboolean draw_button_all(const sclwindow window, const scldrawctx draw_ctx, const scl16 x, const scl16 y, const scl16 width, const scl16 height); scldrawing draw_button_bg_by_sw(const sclwindow window, const scldrawctx draw_ctx, const scl16 key_index, const SCLButtonState state); diff --git a/scl/scluiimpl.cpp b/scl/scluiimpl.cpp index 7bb0715..344cdb0 100644 --- a/scl/scluiimpl.cpp +++ b/scl/scluiimpl.cpp @@ -189,6 +189,32 @@ CSCLUIImpl::set_ui_event_callback(ISCLUIEventCallback *callback, const sclchar * } } +void +CSCLUIImpl::set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data) +{ + SCL_DEBUG(); + + if (m_initialized) { + CSCLUIBuilder *builder = CSCLUIBuilder::get_instance(); + if (builder) { + builder->set_graphics_backend_callback(callback, data); + } + } +} + +void +CSCLUIImpl::set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data) +{ + SCL_DEBUG(); + + if (m_initialized) { + CSCLUIBuilder *builder = CSCLUIBuilder::get_instance(); + if (builder) { + builder->set_window_backend_callback(callback, data); + } + } +} + /** * Sets the current input mode to the given mode * @Usage diff --git a/scl/scluiimpl.h b/scl/scluiimpl.h index fd3b914..847b236 100644 --- a/scl/scluiimpl.h +++ b/scl/scluiimpl.h @@ -21,6 +21,8 @@ #include "scltypes.h" #include "sclstructs.h" #include "scleventcallback.h" +#include "sclgraphicsbackendcallback.h" +#include "sclwindowbackendcallback.h" //SCL_BEGIN_DECLS @@ -48,6 +50,8 @@ public: void hide(); void set_ui_event_callback(ISCLUIEventCallback *callback, const sclchar *input_mode); + void set_graphics_backend_callback(ISCLUIGraphicsBackendCallback *callback, void *data); + void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data); sclboolean set_rotation(SCLRotation degree); SCLRotation get_rotation(); diff --git a/scl/sclutils-linux.cpp b/scl/sclutils-linux.cpp index e93690c..526a141 100644 --- a/scl/sclutils-linux.cpp +++ b/scl/sclutils-linux.cpp @@ -138,6 +138,8 @@ static void accessibility_changed_cb(keynode_t *key, void* data) void CSCLUtilsImplLinux::init() { SCL_DEBUG(); + ecore_wl2_init(); + open_devices(); vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, accessibility_changed_cb, NULL); @@ -151,6 +153,8 @@ CSCLUtilsImplLinux::fini() { vconf_ignore_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, accessibility_changed_cb); close_devices(); + + ecore_wl2_shutdown(); } /* FIXME : Currently the screen resolution is locally cached, should be updated when it gets changed */ diff --git a/scl/sclwindowbackendcallback.h b/scl/sclwindowbackendcallback.h new file mode 100644 index 0000000..a7b7d10 --- /dev/null +++ b/scl/sclwindowbackendcallback.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __SCL_WINDOW_BACKENDCALLBACK_H__ +#define __SCL_WINDOW_BACKENDCALLBACK_H__ + +using namespace scl; + +//SCL_BEGIN_DECLS +/* FIXME : Need to check the dependency cause by the next include statement */ + +struct ISCLUIWindowBackendCallback { + virtual void update_window(int x, int w, int width, int height, void* user_data) { } + +}; + +#endif //__SCL_WINDOW_BACKENDCALLBACK_H__ diff --git a/scl/sclwindows-efl.cpp b/scl/sclwindows-efl.cpp deleted file mode 100644 index 9871aa5..0000000 --- a/scl/sclwindows-efl.cpp +++ /dev/null @@ -1,1224 +0,0 @@ -/* - * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "sclwindows-efl.h" -#include "scldebug.h" -#include "sclcontroller.h" -#include "sclcontext.h" -#include "sclresourcecache.h" -#include "scluibuilder.h" -#include "sclwindows.h" -#include "sclres_manager.h" - -#include -#include -#include -#ifdef WAYLAND -#define EFL_BETA_API_SUPPORT -#include -#else -#include -#include -#include -#include -#endif -#include -#include "sclkeyfocushandler.h" - -using namespace scl; - -#ifndef WAYLAND -static Ecore_X_Atom ATOM_WM_CLASS = 0; -static Ecore_X_Window app_window = 0; -#endif - -const sclint rotation_values_EFL[ROTATION_MAX] = { - 0, // ROTATION_0 - 90, // ROTATION_90_CW - 180, // ROTATION_180 - 270, // ROTATION_90_CCW -}; - -void release_all(Evas_Object *win); - -#include "sclgraphics-efl.h" -#ifdef TEST_NEWBACKEND -#include -#include -#include -extern std::vector g_ImageCache; -extern std::vector g_TextCache; -#else -#endif - -/* When the base window is resized, any mouse events generated before this timestamp value - * that are waiting in the event queue, could be considered as outdated so we are going to - * skip those events */ -unsigned int g_timestamp_last_base_window_resized = 0; - -/** - * Constructor - */ -CSCLWindowsImplEfl::CSCLWindowsImplEfl() -{ - SCL_DEBUG(); -#ifndef WAYLAND - /* Initializes all window resources */ - ATOM_WM_CLASS = ecore_x_atom_get("WM_CLASS"); -#endif -} - -/** - * De-constructor - */ -CSCLWindowsImplEfl::~CSCLWindowsImplEfl() -{ - SCL_DEBUG(); -} - -static void window_show_cb(void *data, Evas *e, Evas_Object *obj, void *event) -{ - LOGD("INSIDE =-=-=-=- window_show_cb, Trying to Grab Key Board : \n"); -#ifdef USING_KEY_GRAB - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance(); - - if (windows && focus_handler) - focus_handler->grab_keyboard(windows->get_base_window()); -#endif -} - -void CSCLWindowsImplEfl::init() -{ -} - -void CSCLWindowsImplEfl::fini() -{ -} - -/** - * Create a content window and binds it into given parent window as a child - */ -sclwindow -CSCLWindowsImplEfl::create_base_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height) -{ - SCL_DEBUG(); - - sclwindow ret = SCLWINDOW_INVALID; - - if (window_context) { - window_context->etc_info = NULL; - window_context->window = parent; - - //Adding window show event handler - evas_object_event_callback_add(static_cast(parent), EVAS_CALLBACK_SHOW, window_show_cb, NULL); - - set_window_accepts_focus(parent, FALSE); - -#ifndef WAYLAND - ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast(parent)), "Virtual Keyboard", "ISF"); -#endif - - ret = window_context->window; - } - - int rots[4] = {0, 90, 180, 270}; - elm_win_wm_rotation_available_rotations_set(static_cast(parent), rots, 4); - - CSCLUtils *utils = CSCLUtils::get_instance(); - if (utils) { - utils->log("WinEfl_createbasewin %p, %d %d\n", - parent, width, height); - } - return ret; -} - -/** - * Creates a window - */ -sclwindow -CSCLWindowsImplEfl::create_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height) -{ - SCL_DEBUG(); - - Evas_Object *win = NULL; - CSCLUtils *utils = CSCLUtils::get_instance(); - - win = elm_win_add(static_cast(parent), "SCLPopup", ELM_WIN_UTILITY); - - elm_win_borderless_set(win, EINA_TRUE); - elm_win_alpha_set(win, EINA_TRUE); - elm_win_title_set(win, "ISF Popup"); - - set_window_accepts_focus(win, FALSE); - - int rots[4] = {0, 90, 180, 270}; - elm_win_wm_rotation_available_rotations_set(win, rots, 4); - - scl16 new_width = 0; - scl16 new_height = 0; - CSCLContext *context = CSCLContext::get_instance(); - if (context) { - if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) { - new_width = height; - new_height = width; - } else { - new_width = width; - new_height = height; - } - } - -#ifndef FULL_SCREEN_TEST - //evas_object_resize(win, width, height); -#endif - -#ifdef WAYLAND - Ecore_Wl2_Window *wl_window = (Ecore_Wl2_Window *)(elm_win_wl_window_get(win)); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_0], 0, 0, new_width, new_height); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_90_CW], 0, 0, new_width, new_height); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_180], 0, 0, new_width, new_height); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_90_CCW], 0, 0, new_width, new_height); -#else - /* - ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), - rotation_values_EFL[ROTATION_0], 0, 0, new_width, new_height); - ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), - rotation_values_EFL[ROTATION_90_CW], 0, 0, new_width, new_height); - ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), - rotation_values_EFL[ROTATION_180], 0, 0, new_width, new_height); - ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), - rotation_values_EFL[ROTATION_90_CCW], 0, 0, new_width, new_height); - */ - ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast(win)), "ISF Popup", "ISF"); - - Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE = 0; - unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect - - ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE"); - if (ATOM_WINDOW_EFFECT_ENABLE) { - ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1); - } else { - if (utils) { - utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n"); - } - } -#endif - - if (context) - set_window_rotation(win, context->get_rotation()); - - //elm_win_override_set(win, EINA_TRUE); - if (utils) { - utils->log("WinEfl_createwin %p, %d %d\n", - win, width, height); - } - return win; -} - - -/** -* Creates a window -*/ -sclwindow -CSCLWindowsImplEfl::create_magnifier_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height) -{ - SCL_DEBUG(); - - Evas_Object *win = NULL; - CSCLUtils *utils = CSCLUtils::get_instance(); - - win = elm_win_add(static_cast(parent), "Magnifier", ELM_WIN_UTILITY); - LOGD("Created magnifier window %p, using parent %p", win, parent); - - elm_win_borderless_set(win, EINA_TRUE); - elm_win_alpha_set(win, EINA_TRUE); - elm_win_title_set(win, "ISF Magnifier"); - - /* We are not going to accept mouse events for magnifier window */ - Eina_Rectangle rect_unset = { -1, -1, 1, 1 }; - elm_win_input_rect_set(win, &rect_unset); - - set_window_accepts_focus(win, FALSE); - - int rots[4] = { 0, 90, 180, 270 }; - elm_win_wm_rotation_available_rotations_set(win, rots, 4); - -#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW - CSCLUtils *utils = CSCLUtils::get_instance(); - CSCLWindows *windows = CSCLWindows::get_instance(); - sclint scrx, scry, winx, winy; - if (windows && utils) { - utils->get_screen_resolution(&scrx, &scry); - SclWindowContext *window_context = windows->get_window_context(windows->get_base_window()); - if (window_context) evas_object_resize(win, scrx, height + window_context->height); - } -#endif - -#ifdef WAYLAND - Ecore_Wl2_Window *wl_window = (Ecore_Wl2_Window *)(elm_win_wl_window_get(win)); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_0], 0, 0, width, height); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_90_CW], 0, 0, height, width); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_180], 0, 0, width, height); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_90_CCW], 0, 0, height, width); -#else - /* - ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), - rotation_values_EFL[ROTATION_0], 0, 0, width, height); - ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), - rotation_values_EFL[ROTATION_90_CW], 0, 0, height, width); - ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), - rotation_values_EFL[ROTATION_180], 0, 0, width, height); - ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), - rotation_values_EFL[ROTATION_90_CCW], 0, 0, height, width); - */ - ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast(win)), "Key Magnifier", "ISF"); - Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE = 0; - unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect - ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE"); - if (ATOM_WINDOW_EFFECT_ENABLE) { - ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1); - } else { - if (utils) { - utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n"); - } - } -#endif - - CSCLContext *context = CSCLContext::get_instance(); - if (context) - set_window_rotation(win, context->get_rotation()); - - if (utils) { - utils->log("WinEfl_createmagwin %p, %d %d\n", - win, width, height); - } - - return win; -} - -/** - * Creates the dim window - */ -sclwindow -CSCLWindowsImplEfl::create_dim_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height) -{ - SCL_DEBUG(); - - Evas_Object *win = NULL; - CSCLUtils *utils = CSCLUtils::get_instance(); - win = elm_win_add(static_cast(parent), "SCLPopup", ELM_WIN_UTILITY); - - elm_win_borderless_set(win, EINA_TRUE); - elm_win_alpha_set(win, EINA_TRUE); - elm_win_title_set(win, "ISF Dim"); - - evas_object_resize(win, width, height); - - int rots[4] = {0, 90, 180, 270}; - elm_win_wm_rotation_available_rotations_set(win, rots, 4); - - set_window_accepts_focus(win, FALSE); - -#ifndef WAYLAND - ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast(win)), "ISF Popup", "ISF"); - - Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE = 0; - unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect - - ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE"); - if (ATOM_WINDOW_EFFECT_ENABLE) { - ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1); - } else { - if (utils) { - utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n"); - } - } -#endif - - CSCLContext *context = CSCLContext::get_instance(); - if (context) - set_window_rotation(win, context->get_rotation()); - - /*Evas_Object *bg; - bg = elm_bg_add(win); - elm_win_resize_object_add(win, bg); - evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - SclColor color = scl_dim_window_configure.dim_color; - evas_object_color_set(bg, color.r, color.g, color.b, color.a); - evas_object_show(bg);*/ - - hide_window(win); - - if (utils) { - utils->log("WinEfl_createdimwin %p, %d %d\n", - win, width, height); - } - return win; -} - -/** - * Make a window relation between parent and child - * Caution: Currently, If we use transient_for them the ISE will occur some crash. It needs to check X11 - */ -void -CSCLWindowsImplEfl::set_parent(const sclwindow parent, const sclwindow window) -{ - SCL_DEBUG(); - -#ifndef WAYLAND - if (parent && window) { - ecore_x_icccm_transient_for_set(elm_win_xwindow_get(static_cast(window)), - elm_win_xwindow_get(static_cast(parent))); - } -#endif -} - -Eina_Bool destroy_later(void *data) -{ - evas_object_hide((Evas_Object*)data); - evas_object_del((Evas_Object*)data); - return ECORE_CALLBACK_CANCEL; -} - -/** - * Destroys the given window - */ -bool -CSCLWindowsImplEfl::destroy_window(sclwindow window) -{ - SCL_DEBUG(); - - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLUtils *utils = CSCLUtils::get_instance(); - - SclWindowContext *window_context = NULL; - if (windows && window && utils) { - window_context = windows->get_window_context(window); - if (window_context) { - utils->log("WinEfl_destroywin %p %p (basewin %p mag %p)\n", window, - (!(window_context->is_virtual)) ? elm_win_xwindow_get(static_cast(window)) : 0x01, - windows->get_base_window(), windows->get_magnifier_window()); - if (window_context->etc_info) { - Eina_List *list = (Eina_List*)(window_context->etc_info); - Eina_List *iter = NULL; - Eina_List *iter_next = NULL; - void *data = NULL; - - EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) { - if (data) { - EFLObject *object = (EFLObject*)(data); - if (object) { - Evas_Object* eo = object->object; - if (object->extracted) { - //evas_object_image_data_set(eo, NULL); - void *image_data = evas_object_image_data_get(eo, 1); - if (image_data) { - free(image_data); - } - } - if (eo) { - evas_object_del(eo); - object->object = NULL; - } - if (object->type == EFLOBJECT_TEXTBLOCK) { - Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data); - if (st) { - evas_textblock_style_free(st); - } -#ifdef TEST_NEWBACKEND - for (sclint loop = 0;loop < (sclint)g_TextCache.size();loop++) { - if (g_TextCache[loop].text == object->object) { - g_TextCache[loop].used = FALSE; - } - } -#endif - } else if (object->type == EFLOBJECT_IMAGE) { -#ifdef TEST_NEWBACKEND - for (sclint loop = 0;loop < (sclint)g_ImageCache.size();loop++) { - if (g_ImageCache[loop].image == object->object) { - g_ImageCache[loop].used = FALSE; - } - } -#endif - } - delete object; - } - } - list = eina_list_remove_list(list, iter); - } - window_context->etc_info = NULL; - } - - if (!(window_context->is_virtual)) { - /* FIXME : A workaround for the bug that event on a window being hidden is delivered to - e17, instead of the window itself or the window right below - Should report to WM */ - if (window == windows->get_nth_popup_window(SCL_WINDOW_Z_TOP)) { - ecore_timer_add(0.1f, destroy_later, (void*)window); - } else { - Evas_Object *win = (Evas_Object*)window; - evas_object_hide(win); - evas_object_del(win); - } - } - utils->log("WinEfl_destroywin %p (basewin %p mag %p)\n", window, - windows->get_base_window(), windows->get_magnifier_window()); - } - } - - return TRUE; -} - -/** - * Shows the given window - */ -void -CSCLWindowsImplEfl::show_window(const sclwindow window, sclboolean queue) -{ - SCL_DEBUG(); - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLContext *context = CSCLContext::get_instance(); - CSCLUtils *utils = CSCLUtils::get_instance(); - if (windows && context && window) { - SclWindowContext *window_context = windows->get_window_context(window); - if (!(context->get_hidden_state())) { - if (window_context) { - if (!(window_context->is_virtual)) { - evas_object_show((Evas_Object*)window); - } - - if (!(windows->get_update_pending())) { - update_window(window); - } - } - } - -#ifndef WAYLAND - if (windows->get_base_window() == window) { - int ret = 0; - Atom type_return; - int format_return; - unsigned long nitems_return; - unsigned long bytes_after_return; - unsigned char *data = NULL; - - Ecore_X_Window win = elm_win_xwindow_get(static_cast(window)); - ret = XGetWindowProperty((Display *)ecore_x_display_get(), - ecore_x_window_root_get(win), - ecore_x_atom_get("_ISF_ACTIVE_WINDOW"), - 0, G_MAXLONG, False, XA_WINDOW, &type_return, - &format_return, &nitems_return, &bytes_after_return, - &data); - - if (data) { - if (ret == Success) { - if ((type_return == XA_WINDOW) && (format_return == 32) && (data)) { - app_window = *(Window *)data; - } - } - XFree(data); - } - } -#endif - scl8 popup_index = windows->find_popup_window_index(window); - if (windows->get_magnifier_window() == window || popup_index != NOT_USED) { - /* - * FIXME a solution to make magnifier window always on top - * N_SE-17689: magnifier window showing behind of candidate window - * - * N_SE-52548: ...and modified if() for other popup windows as well... - */ - if (window_context && !(window_context->is_virtual)) { -#ifndef WAYLAND - ecore_x_icccm_transient_for_set - (elm_win_xwindow_get(static_cast(window)), app_window); -#endif - elm_win_raise((Evas_Object *)window); - } - } - - if (utils) { - utils->log("WinEfl_showwin %p (basewin %p mag %p)\n", - window, - windows->get_base_window(), windows->get_magnifier_window()); - } - } -} - -/** - * Hides the given window - */ -void -CSCLWindowsImplEfl::hide_window(const sclwindow window, sclboolean fForce) -{ - SCL_DEBUG(); - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLUtils *utils = CSCLUtils::get_instance(); - SclWindowContext *window_context = NULL; - - if (windows && window) { -#ifdef USING_KEY_GRAB - if (window == windows->get_base_window()) { - CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance(); - focus_handler->ungrab_keyboard(window); - } -#endif - - window_context = windows->get_window_context(window); - if (window_context) { - if (!(window_context->is_virtual)) { - Evas_Object *win = (Evas_Object*)window; - /* FIXME : A workaround for the bug that event on a window being hidden is delivered to - e17, instead of the window itself or the window right below - Should report to WM */ - if (window == windows->get_nth_popup_window(SCL_WINDOW_Z_TOP)) { - evas_object_move(win, -10000, -10000); - } else { -#ifdef WAYLAND - /* Under wayland environment, the visibility of keyboard window is controlled by - * wayland server, so it is not allowed to call evas_object_hide() for keyboard window - * directly on the keyboard side */ - if (win != windows->get_base_window()) { - evas_object_hide(win); - } -#else - evas_object_hide(win); -#endif - } - } - } - } - - if (windows && utils && window) { - // Memory optimization */ - if (window == windows->get_magnifier_window() || window == windows->get_dim_window()) { - if (window_context) { - if (window_context->etc_info) { -#ifdef TEST_NEWBACKEND -#else - Eina_List *list = (Eina_List*)(window_context->etc_info); - Eina_List *iter = NULL; - Eina_List *iter_next = NULL; - void *data = NULL; - int iIndex = 0; - EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) { - if (data) { - EFLObject *object = (EFLObject*)(data); - if (object) { - sclboolean bShouldRemove = FALSE; - bShouldRemove = TRUE; - if (bShouldRemove) { - Evas_Object* eo = object->object; - if (object->extracted) { - void *image_data = evas_object_image_data_get(eo, 1); - if (image_data) { - free(image_data); - } - } - if (eo) { - evas_object_del(eo); - object->object = NULL; - } - if (object->type == EFLOBJECT_TEXTBLOCK) { - Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data); - if (st) { - evas_textblock_style_free(st); - } -#ifdef TEST_NEWBACKEND - for (sclint loop = 0;loop < g_TextCache.size();loop++) { - if (g_TextCache[loop].text == object->object) { - g_TextCache[loop].used = FALSE; - } - } -#endif - } else if (object->type == EFLOBJECT_IMAGE) { -#ifdef TEST_NEWBACKEND - for (sclint loop = 0;loop < g_ImageCache.size();loop++) { - if (g_ImageCache[loop].image == object->object) { - g_ImageCache[loop].used = FALSE; - } - } -#endif - } - delete object; - list = eina_list_remove_list(list, iter); - } - } - iIndex++; - } - } - window_context->etc_info = list; -#endif - } - } - //Evas *evas = evas_object_evas_get((Evas_Object*)window); - //evas_render_idle_flush(evas); - } - if (window == windows->get_base_window()) { - elm_cache_all_flush(); - malloc_trim(0); - } - utils->log("WinEfl_hidewin %p (basewin %p mag %p)\n", - window, - windows->get_base_window(), windows->get_magnifier_window()); - } -} - -/** - * Moves the window to the given position - */ -sclint magnifierx, magnifiery; -void -CSCLWindowsImplEfl::move_window(const sclwindow window, scl16 x, scl16 y) -{ - SCL_DEBUG(); - CSCLUtils *utils = CSCLUtils::get_instance(); - CSCLContext *context = CSCLContext::get_instance(); - CSCLWindows *windows = CSCLWindows::get_instance(); - - if (utils && context && windows && window) { - SclWindowContext *window_context = windows->get_window_context(window); - unsigned short win_width = 0; - unsigned short win_height = 0; - if (window_context) { - win_width = window_context->geometry.width; - win_height = window_context->geometry.height; - } - - scl16 rotatex = x; - scl16 rotatey = y; - scl16 orgx = x; - scl16 orgy = y; - - sclint scr_w, scr_h; - /* get window size */ - utils->get_screen_resolution(&scr_w, &scr_h); - -#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW - if (window == windows->get_magnifier_window()) { - SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window(), FALSE); - rotatex = orgx = 0; - if (context->get_rotation_degree() == 90 || context->get_rotation_degree() == 270) { - rotatey = orgy = scr_w - base_window_context->height - win_height; - win_width = base_window_context->width; - win_height = base_window_context->height + win_height; - } else { - rotatey = orgy = scr_h - base_window_context->height - win_height; - win_width = base_window_context->width; - win_height = base_window_context->height + win_height; - } - magnifierx = x; - magnifiery = y - orgy; - } -#endif - - switch (context->get_rotation()) { - case ROTATION_90_CW: { - rotatex = orgy; - rotatey = scr_w - orgx - win_width; - } - break; - case ROTATION_180: { - rotatex = scr_w - orgx - win_width; - rotatey = scr_h - orgy - win_height; - } - break; - case ROTATION_90_CCW: { - rotatex = scr_h - orgy - win_height; - rotatey = orgx; - } - break; - case ROTATION_0: break; - default: break; - } - - #ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW - if (window == windows->get_magnifier_window()) { - if (rotatex == window_context->x && rotatey == windonw_context->y) return; - } - #endif - - Evas_Object *win = (Evas_Object*)window; -#ifndef FULL_SCREEN_TEST - if (window != windows->get_base_window()) { - evas_object_move(win, rotatex, rotatey); - } -#endif - //Evas_Object *window_object = (Evas_Object*)window; - //Evas *evas = evas_object_evas_get(window_object); - //evas_render_idle_flush(evas); - - utils->log("WinEfl_movewin %p %d %d %d %d (basewin %p mag %p)\n", - window, - x, y, rotatex, rotatey, - windows->get_base_window(), windows->get_magnifier_window()); - } -} - -/** -* Resizes the window to the given metric -*/ -void -CSCLWindowsImplEfl::resize_window(const sclwindow window, scl16 width, scl16 height) -{ - SCL_DEBUG(); - - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLUtils *utils = CSCLUtils::get_instance(); - - if (!windows || !utils) return; - -#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW - if (window == windows->get_magnifier_window()) { - SclWindowContext *window_context = windows->get_window_context(windows->get_base_window()); - if (window_context->width != width || window_context->height != height) { - sclint scrx, scry, winx, winy; - utils->get_screen_resolution(&scrx, &scry); - if (context->get_rotation_degree() == 90 || context->get_rotation_degree() == 270) { - evas_object_resize((Evas_Object*)window, scry, height + window_context->height); - } else { - evas_object_resize((Evas_Object*)window, scrx, height + window_context->height); - } - } - return; - } -#endif - - Evas_Object *win = (Evas_Object*)window; -#ifndef FULL_SCREEN_TEST - if (windows && utils && window) { - utils->log("WinEfl_resizewin %p %d %d (basewin %p mag %p)\n", - window, width, height, - windows->get_base_window(), windows->get_magnifier_window()); - } -#endif - //Evas_Object *window_object = (Evas_Object*)window; - //Evas *evas = evas_object_evas_get(window_object); - /*CSCLWindows *windows = CSCLWindows::get_instance(); - if (windows) { - windows->update_window(window); - }*/ - //evas_render_idle_flush(evas); - if (windows && window) { - if (window != windows->get_base_window()) { -#ifdef WAYLAND - Ecore_Wl2_Window *wl_window = (Ecore_Wl2_Window *)(elm_win_wl_window_get(win)); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_0], 0, 0, width, height); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_90_CW], 0, 0, height, width); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_180], 0, 0, width, height); - ecore_wl2_window_rotation_geometry_set(wl_window, - rotation_values_EFL[ROTATION_90_CCW], 0, 0, height, width); -#else - evas_object_resize(win, width, height); -#endif - } else { - g_timestamp_last_base_window_resized = (unsigned int)(ecore_loop_time_get() * 1000.0f); - } - - if (window == windows->get_dim_window()) { - hide_window(window); - } - } -} - -/** -* Resizes the window to the given metric -*/ -void -CSCLWindowsImplEfl::move_resize_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height) -{ - SCL_DEBUG(); - Evas_Object *win = (Evas_Object*)window; -#ifndef FULL_SCREEN_TEST - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLUtils *utils = CSCLUtils::get_instance(); - if (windows && utils && window) { - if (window != windows->get_base_window()) { - evas_object_move(win, x, y); - evas_object_resize(win, width, height); - } - utils->log("WinEfl_moveresizewin %p %d %d %d %d (basewin %p)\n", - window, x, y, width, height, windows->get_base_window()); - } -#endif - //Evas_Object *window_object = (Evas_Object*)window; - //Evas *evas = evas_object_evas_get(window_object); - /*CSCLWindows *windows = CSCLWindows::get_instance(); - if (windows) { - windows->update_window(window); - }*/ - //evas_render_idle_flush(evas); -} - -/** -* Update the window to redraw given area -*/ -void -CSCLWindowsImplEfl::update_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height) -{ - SCL_DEBUG(); - - sclboolean removeall = FALSE; - SclRectangle updatearea = {x, y, width, height}; - if (x + y + width + height == 0) { - removeall = TRUE; - } - - CSCLWindows *windows = CSCLWindows::get_instance(); - CSCLUtils *utils = CSCLUtils::get_instance(); - SclWindowContext *window_context = NULL; - - if (windows && window) { - //window_context = windows->get_window_context(window, FALSE); - window_context = windows->get_window_context(window); - } - if (windows && utils && window_context) { - if (window_context->is_virtual) { - SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window()); - if (base_window_context) { - updatearea.x += (window_context->geometry.x - base_window_context->geometry.x); - updatearea.y += (window_context->geometry.y - base_window_context->geometry.y); - } - } - if (window_context->etc_info) { - Eina_List *list = (Eina_List*)(window_context->etc_info); - Eina_List *iter = NULL; - Eina_List *iter_next = NULL; - void *data = NULL; - int iIndex = 0; - - EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) { - if (data) { - EFLObject *object = (EFLObject*)(data); - if (object) { - Evas_Object* eo = object->object; - sclboolean bShouldRemove = FALSE; - if (removeall || utils->is_rect_overlap(object->position, updatearea)) { - bShouldRemove = TRUE; - } - if (iIndex == 0 && !removeall) { - bShouldRemove = FALSE; // window's background - } - if (object->type == EFLOBJECT_CLIPOBJECT) { - bShouldRemove = FALSE; // Clip objects are removed when the parent image object is removed - } - if (eo == NULL) { /* If this object is already removed, proceed removing */ - bShouldRemove = TRUE; - } - if (bShouldRemove) { -#ifdef TEST_NEWBACKEND - //if (object->type == EFLOBJECT_IMAGE) { - SCL_DEBUG_ELAPSED_TIME_START(); - if (TRUE) { - if (window_context->width != object->position.width || window_context->height != object->position.height || - object->type == EFLOBJECT_TEXTBLOCK || window == windows->get_magnifier_window()) { - evas_object_hide(object->object); - } - } else { -#else - if (object->extracted) { - void *image_data = evas_object_image_data_get(eo, 1); - if (image_data) { - free(image_data); - } - } - if (eo) { - evas_object_del(eo); - object->object = NULL; - } - if (object->type == EFLOBJECT_TEXTBLOCK) { - Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data); - if (st) { - evas_textblock_style_free(st); - } -#ifdef TEST_NEWBACKEND - for (sclint loop = 0;loop < g_TextCache.size();loop++) { - if (g_TextCache[loop].text == object->object) { - g_TextCache[loop].used = FALSE; - } - } -#endif - } else if (object->type == EFLOBJECT_IMAGE) { -#ifdef TEST_NEWBACKEND - for (sclint loop = 0;loop < g_ImageCache.size();loop++) { - if (g_ImageCache[loop].image == object->object) { - g_ImageCache[loop].used = FALSE; - } - } -#endif - EFLObject *clip_object = (EFLObject*)(object->data); - if (clip_object) { - if (clip_object->object) { - evas_object_del(clip_object->object); - clip_object->object = NULL; - } - } - } - delete object; - list = eina_list_remove_list(list, iter); -#endif -#ifdef TEST_NEWBACKEND - } -#endif - } - } - iIndex++; - } - } - window_context->etc_info = list; - - /*while ((Eina_List*)(window_context->etc_info)) - { - EFLObject *object = (EFLObject*)eina_list_data_get((Eina_List*)(window_context->etc_info)); - if (object) { - Evas_Object* eo = object->object; - if (eo) { - evas_object_del(eo); - object->object = NULL; - } - } - window_context->etc_info = eina_list_remove_list((Eina_List*)(window_context->etc_info), (Eina_List*)(winctx->etc_info)); - delete object; - } - window_context->etc_info = NULL;*/ - } - CSCLUIBuilder *builder = CSCLUIBuilder::get_instance(); - builder->show_layout(window, x, y, width, height); - } - - /*evas_image_cache_flush(evas_object_evas_get((Evas_Object*)window)); - elm_cache_all_flush(); - malloc_trim(0);*/ - //edje_file_cache_flush(); -} - -/** - * Returns the position of x,y,width,height of the given window - */ -sclboolean -CSCLWindowsImplEfl::get_window_rect(const sclwindow window, SclRectangle *rect) -{ - SCL_DEBUG(); - CSCLUtils *utils = CSCLUtils::get_instance(); - CSCLContext *context = CSCLContext::get_instance(); - - if (utils && context && rect && window) { - int x = 0, y = 0, width = 0, height = 0; - sclint scr_w = 0, scr_h = 0; - elm_win_screen_position_get(static_cast(window), &x, &y); - evas_object_geometry_get(static_cast(window), NULL, NULL, &width, &height); - - utils->log("WinEfl_getwinrect %p %d %d %d %d\n", - window, x, y, width, height); - - /* get window size */ - utils->get_screen_resolution(&scr_w, &scr_h); - - switch (context->get_rotation()) - { - case ROTATION_90_CW: - { - rect->width = width; - rect->height = height; - rect->x = scr_w - y - width; - rect->y = x; - } - break; - case ROTATION_180: - { - rect->x = scr_w - width - x; - rect->y = scr_h - height - y; - rect->width = width; - rect->height = height; - } - break; - case ROTATION_90_CCW: - { - rect->width = width; - rect->height = height; - rect->x = y; - rect->y = scr_h - x - height; - } - break; - default: - { - rect->x = x; - rect->y = y; - rect->width = width; - rect->height = height; - } - break; - } - } - - return TRUE; -} - -/** - * Sets rotation - */ -void -CSCLWindowsImplEfl::set_window_rotation(const sclwindow window, SCLRotation rotation) -{ - SCL_DEBUG(); - -#ifndef WAYLAND - CSCLWindows *windows = CSCLWindows::get_instance(); - SclWindowContext *window_context = NULL; - - if (windows && window) { - //window_context = windows->get_window_context(window, FALSE); - window_context = windows->get_window_context(window); - - if (window_context) { - if (window_context->is_virtual) { - return; - } - } - - XSizeHints hint; - long int mask; - Window win; - Display *dpy; - - dpy = (Display*)ecore_x_display_get(); - win = elm_win_xwindow_get((Evas_Object*)window); - - if (!XGetWMNormalHints(dpy, win, &hint, &mask)) - memset(&hint, 0, sizeof(XSizeHints)); - - hint.flags |= USPosition; - - XSetWMNormalHints(dpy, win, &hint); - /*if (window_context) { - windows->resize_window(window_context->window, window_context->width, winctx->height); - }*/ - } -#endif -} - -/** - * Shows a message box - */ -void -CSCLWindowsImplEfl::show_message_box(const sclwindow parent, scl8 msgType, sclchar* title, sclchar* msg) -{ - SCL_DEBUG(); -} - -void -CSCLWindowsImplEfl::set_keep_above(const sclwindow window, sclboolean keepabove) -{ - SCL_DEBUG(); -} - -void release_all(Evas_Object *win) -{ - SCL_DEBUG(); - //if (window == windows->get_magnifier_window()) { - //evas_object_move(win, -10000, -10000); - //Evas *evas = evas_object_evas_get(win); - //evas_render_idle_flush(evas); - /*} else { - evas_object_hide(win); - }*/ - //LOGD("HIDE_WINDOW : %p\n", window); - - CSCLWindows *windows = CSCLWindows::get_instance(); - if (!windows) return; - - SclWindowContext *window_context = windows->get_window_context(win); - if (window_context && win) { - if (window_context->etc_info) { -#ifdef TEST_NEWBACKEND -#else - Eina_List *list = (Eina_List*)(window_context->etc_info); - Eina_List *iter = NULL; - Eina_List *iter_next = NULL; - void *data = NULL; - int iIndex = 0; - EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) { - if (data) { - EFLObject *object = (EFLObject*)(data); - if (object) { - sclboolean bShouldRemove = FALSE; - bShouldRemove = TRUE; - if (bShouldRemove) { - Evas_Object* eo = object->object; - if (object->extracted) { - void *image_data = evas_object_image_data_get(eo, 1); - if (image_data) { - free(image_data); - } - } - if (eo) { - evas_object_del(eo); - object->object = NULL; - } - if (object->type == EFLOBJECT_TEXTBLOCK) { - Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data); - if (st) { - evas_textblock_style_free(st); - } -#ifdef TEST_NEWBACKEND - for (sclint loop = 0;loop < g_TextCache.size();loop++) { - if (g_TextCache[loop].text == object->object) { - g_TextCache[loop].used = FALSE; - } - } -#endif - } else if (object->type == EFLOBJECT_IMAGE) { -#ifdef TEST_NEWBACKEND - for (sclint loop = 0;loop < g_ImageCache.size();loop++) { - if (g_ImageCache[loop].image == object->object) { - g_ImageCache[loop].used = FALSE; - } - } -#endif - } - delete object; - list = eina_list_remove_list(list, iter); - } - } - iIndex++; - } - } - window_context->etc_info = list; -#endif - } - } - //Evas *evas = evas_object_evas_get((Evas_Object*)win); - //evas_render_idle_flush(evas); - //} - /*evas_image_cache_flush(evas_object_evas_get((Evas_Object*)win)); - elm_cache_all_flush(); - malloc_trim(0);*/ -} - -void CSCLWindowsImplEfl::set_window_accepts_focus(const sclwindow window, sclboolean acceptable) -{ - elm_win_prop_focus_skip_set(static_cast(window), !acceptable); -} diff --git a/scl/sclwindows-efl.h b/scl/sclwindows-efl.h deleted file mode 100644 index 3a22325..0000000 --- a/scl/sclwindows-efl.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "sclwindows.h" -#include -#include - -#ifndef __SCL_WINDOWS_EFL_H__ -#define __SCL_WINDOWS_EFL_H__ - -typedef enum { - EFLOBJECT_NONE, - EFLOBJECT_IMAGE, - EFLOBJECT_CLIPOBJECT, - EFLOBJECT_TEXTBLOCK, - EFLOBJECT_RECTANGLE, -} EFLOBJECT_TYPE; - -namespace scl -{ -typedef struct { - EFLOBJECT_TYPE type; - SclRectangle position; - Evas_Object *object; - const char *etc_info; - sclboolean extracted; - void *data; -} EFLObject; -class CSCLWindowsImplEfl : public CSCLWindowsImpl -{ -public : - CSCLWindowsImplEfl(); - ~CSCLWindowsImplEfl(); - - void init(); - void fini(); - - sclwindow create_base_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height); - sclwindow create_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height); - sclwindow create_magnifier_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height); - sclwindow create_dim_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height); - bool destroy_window(sclwindow window); - void show_window(const sclwindow window, sclboolean queue); - void hide_window(const sclwindow window, sclboolean fForce = FALSE); - void move_window(const sclwindow window, scl16 x, scl16 y); - void resize_window(const sclwindow window, scl16 width, scl16 height); - void move_resize_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height); - void update_window(const sclwindow window, scl16 x = 0, scl16 y = 0, scl16 width = 0, scl16 height = 0); - void set_window_rotation(const sclwindow window, SCLRotation rotation); - void show_message_box(const sclwindow parent, scl8 msgType, sclchar* title, sclchar* msg); - sclboolean get_window_rect(const sclwindow window, SclRectangle *rect); - void set_parent(const sclwindow parent, const sclwindow window); - void set_keep_above(const sclwindow window, sclboolean keepabove); - - /* EFL specific utility functions */ - void set_window_accepts_focus(const sclwindow window, sclboolean accepts); -}; -} /* End of scl namespace */ -#endif diff --git a/scl/sclwindows-nui.cpp b/scl/sclwindows-nui.cpp new file mode 100644 index 0000000..8badcb6 --- /dev/null +++ b/scl/sclwindows-nui.cpp @@ -0,0 +1,937 @@ +/* + * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sclwindows-nui.h" +#include "scldebug.h" +#include "sclcontroller.h" +#include "sclcontext.h" +#include "sclresourcecache.h" +#include "scluibuilder.h" +#include "sclwindows.h" +#include "sclres_manager.h" + +#include +#include +#include +#define EFL_BETA_API_SUPPORT +#include +#include +#include "sclkeyfocushandler.h" + +using namespace scl; + +const sclint rotation_values_EFL[ROTATION_MAX] = { + 0, // ROTATION_0 + 90, // ROTATION_90_CW + 180, // ROTATION_180 + 270, // ROTATION_90_CCW +}; + +#include "sclgraphics-nui.h" +#ifdef TEST_NEWBACKEND +#include +#include +#include +extern std::vector g_ImageCache; +extern std::vector g_TextCache; +#else +#endif + +/* When the base window is resized, any mouse events generated before this timestamp value + * that are waiting in the event queue, could be considered as outdated so we are going to + * skip those events */ +unsigned int g_timestamp_last_base_window_resized = 0; + +/** + * Constructor + */ +CSCLWindowsImplNui::CSCLWindowsImplNui() +{ + SCL_DEBUG(); + + m_window_backend_callback = NULL; + m_window_backend_callback_data = NULL; +} + +/** + * De-constructor + */ +CSCLWindowsImplNui::~CSCLWindowsImplNui() +{ + SCL_DEBUG(); +} + +static void window_show_cb(void *data, Evas *e, Evas_Object *obj, void *event) +{ + LOGD("INSIDE =-=-=-=- window_show_cb, Trying to Grab Key Board : \n"); +#ifdef USING_KEY_GRAB + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance(); + + if (windows && focus_handler) + focus_handler->grab_keyboard(windows->get_base_window()); +#endif +} + +void CSCLWindowsImplNui::init() +{ +} + +void CSCLWindowsImplNui::fini() +{ +} + +/** + * Create a content window and binds it into given parent window as a child + */ +sclwindow +CSCLWindowsImplNui::create_base_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height) +{ + SCL_DEBUG(); + + sclwindow ret = SCLWINDOW_INVALID; + + if (window_context) { + window_context->etc_info = NULL; + window_context->window = parent; + + //Adding window show event handler + evas_object_event_callback_add(static_cast(parent), EVAS_CALLBACK_SHOW, window_show_cb, NULL); + + set_window_accepts_focus(parent, FALSE); + +#ifndef WAYLAND + ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast(parent)), "Virtual Keyboard", "ISF"); +#endif + + ret = window_context->window; + } + + int rots[4] = {0, 90, 180, 270}; + elm_win_wm_rotation_available_rotations_set(static_cast(parent), rots, 4); + + CSCLUtils *utils = CSCLUtils::get_instance(); + if (utils) { + utils->log("WinNui_createbasewin %p, %d %d\n", + parent, width, height); + } + return ret; +} + +/** + * Creates a window + */ +sclwindow +CSCLWindowsImplNui::create_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height) +{ + SCL_DEBUG(); + + Evas_Object *win = NULL; + CSCLUtils *utils = CSCLUtils::get_instance(); + + win = elm_win_add(static_cast(parent), "SCLPopup", ELM_WIN_UTILITY); + + elm_win_borderless_set(win, EINA_TRUE); + elm_win_alpha_set(win, EINA_TRUE); + elm_win_title_set(win, "ISF Popup"); + + set_window_accepts_focus(win, FALSE); + + int rots[4] = {0, 90, 180, 270}; + elm_win_wm_rotation_available_rotations_set(win, rots, 4); + + scl16 new_width = 0; + scl16 new_height = 0; + CSCLContext *context = CSCLContext::get_instance(); + if (context) { + if (context->get_rotation() == ROTATION_90_CW || context->get_rotation() == ROTATION_90_CCW) { + new_width = height; + new_height = width; + } else { + new_width = width; + new_height = height; + } + } + +#ifndef FULL_SCREEN_TEST + //evas_object_resize(win, width, height); +#endif + +#ifdef WAYLAND + Ecore_Wl2_Window *wl_window = (Ecore_Wl2_Window *)(elm_win_wl_window_get(win)); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_0], 0, 0, new_width, new_height); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_90_CW], 0, 0, new_width, new_height); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_180], 0, 0, new_width, new_height); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_90_CCW], 0, 0, new_width, new_height); +#else + /* + ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), + rotation_values_EFL[ROTATION_0], 0, 0, new_width, new_height); + ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), + rotation_values_EFL[ROTATION_90_CW], 0, 0, new_width, new_height); + ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), + rotation_values_EFL[ROTATION_180], 0, 0, new_width, new_height); + ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), + rotation_values_EFL[ROTATION_90_CCW], 0, 0, new_width, new_height); + */ + ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast(win)), "ISF Popup", "ISF"); + + Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE = 0; + unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect + + ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE"); + if (ATOM_WINDOW_EFFECT_ENABLE) { + ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1); + } else { + if (utils) { + utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n"); + } + } +#endif + + if (context) + set_window_rotation(win, context->get_rotation()); + + //elm_win_override_set(win, EINA_TRUE); + if (utils) { + utils->log("WinNui_createwin %p, %d %d\n", + win, width, height); + } + return win; +} + + +/** +* Creates a window +*/ +sclwindow +CSCLWindowsImplNui::create_magnifier_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height) +{ + SCL_DEBUG(); + + Evas_Object *win = NULL; + CSCLUtils *utils = CSCLUtils::get_instance(); + + // FIXME +#if 0 + win = elm_win_add(static_cast(parent), "Magnifier", ELM_WIN_UTILITY); + LOGD("Created magnifier window %p, using parent %p", win, parent); + + elm_win_borderless_set(win, EINA_TRUE); + elm_win_alpha_set(win, EINA_TRUE); + elm_win_title_set(win, "ISF Magnifier"); + + /* We are not going to accept mouse events for magnifier window */ + Eina_Rectangle rect_unset = { -1, -1, 1, 1 }; + elm_win_input_rect_set(win, &rect_unset); + + set_window_accepts_focus(win, FALSE); + + int rots[4] = { 0, 90, 180, 270 }; + elm_win_wm_rotation_available_rotations_set(win, rots, 4); + +#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW + CSCLUtils *utils = CSCLUtils::get_instance(); + CSCLWindows *windows = CSCLWindows::get_instance(); + sclint scrx, scry, winx, winy; + if (windows && utils) { + utils->get_screen_resolution(&scrx, &scry); + SclWindowContext *window_context = windows->get_window_context(windows->get_base_window()); + if (window_context) evas_object_resize(win, scrx, height + window_context->height); + } +#endif + +#ifdef WAYLAND + Ecore_Wl2_Window *wl_window = (Ecore_Wl2_Window *)(elm_win_wl_window_get(win)); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_0], 0, 0, width, height); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_90_CW], 0, 0, height, width); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_180], 0, 0, width, height); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_90_CCW], 0, 0, height, width); +#else + /* + ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), + rotation_values_EFL[ROTATION_0], 0, 0, width, height); + ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), + rotation_values_EFL[ROTATION_90_CW], 0, 0, height, width); + ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), + rotation_values_EFL[ROTATION_180], 0, 0, width, height); + ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(win), + rotation_values_EFL[ROTATION_90_CCW], 0, 0, height, width); + */ + ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast(win)), "Key Magnifier", "ISF"); + Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE = 0; + unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect + ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE"); + if (ATOM_WINDOW_EFFECT_ENABLE) { + ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1); + } else { + if (utils) { + utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n"); + } + } +#endif + + CSCLContext *context = CSCLContext::get_instance(); + if (context) + set_window_rotation(win, context->get_rotation()); +#endif + + if (utils) { + utils->log("WinNui_createmagwin %p, %d %d\n", + win, width, height); + } + + return win; +} + +/** + * Creates the dim window + */ +sclwindow +CSCLWindowsImplNui::create_dim_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height) +{ + SCL_DEBUG(); + + Evas_Object *win = NULL; + CSCLUtils *utils = CSCLUtils::get_instance(); + win = elm_win_add(static_cast(parent), "SCLPopup", ELM_WIN_UTILITY); + + elm_win_borderless_set(win, EINA_TRUE); + elm_win_alpha_set(win, EINA_TRUE); + elm_win_title_set(win, "ISF Dim"); + + evas_object_resize(win, width, height); + + int rots[4] = {0, 90, 180, 270}; + elm_win_wm_rotation_available_rotations_set(win, rots, 4); + + set_window_accepts_focus(win, FALSE); + +#ifndef WAYLAND + ecore_x_icccm_name_class_set(elm_win_xwindow_get(static_cast(win)), "ISF Popup", "ISF"); + + Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE = 0; + unsigned int effect_state = 0; // 0 -> disable effect 1-> enable effect + + ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE"); + if (ATOM_WINDOW_EFFECT_ENABLE) { + ecore_x_window_prop_card32_set(elm_win_xwindow_get(static_cast(win)), ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1); + } else { + if (utils) { + utils->log("Could not get _NET_CM_WINDOW_EFFECT_ENABLE ATOM \n"); + } + } +#endif + + CSCLContext *context = CSCLContext::get_instance(); + if (context) + set_window_rotation(win, context->get_rotation()); + + hide_window(win); + + if (utils) { + utils->log("WinNui_createdimwin %p, %d %d\n", + win, width, height); + } + return win; +} + +/** + * Make a window relation between parent and child + * Caution: Currently, If we use transient_for them the ISE will occure some crash. It needs to check X11 + */ +void +CSCLWindowsImplNui::set_parent(const sclwindow parent, const sclwindow window) +{ + SCL_DEBUG(); + +#ifndef WAYLAND + if (parent && window) { + ecore_x_icccm_transient_for_set(elm_win_xwindow_get(static_cast(window)), + elm_win_xwindow_get(static_cast(parent))); + } +#endif +} + +Eina_Bool destroy_later(void *data) +{ + evas_object_hide((Evas_Object*)data); + evas_object_del((Evas_Object*)data); + return ECORE_CALLBACK_CANCEL; +} + +/** + * Destroys the given window + */ +bool +CSCLWindowsImplNui::destroy_window(sclwindow window) +{ + SCL_DEBUG(); + + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLUtils *utils = CSCLUtils::get_instance(); + + SclWindowContext *window_context = NULL; + if (windows && window && utils) { + window_context = windows->get_window_context(window); + if (window_context) { + utils->log("WinNui_destroywin %p %p (basewin %p mag %p)\n", window, + (!(window_context->is_virtual)) ? elm_win_xwindow_get(static_cast(window)) : 0x01, + windows->get_base_window(), windows->get_magnifier_window()); + if (window_context->etc_info) { + Eina_List *list = (Eina_List*)(window_context->etc_info); + Eina_List *iter = NULL; + Eina_List *iter_next = NULL; + void *data = NULL; + + EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) { + if (data) { + EFLObject *object = (EFLObject*)(data); + if (object) { + Evas_Object* eo = object->object; + if (object->extracted) { + //evas_object_image_data_set(eo, NULL); + void *image_data = evas_object_image_data_get(eo, 1); + if (image_data) { + free(image_data); + } + } + if (eo) { + evas_object_del(eo); + object->object = NULL; + } + if (object->type == EFLOBJECT_TEXTBLOCK) { + Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data); + if (st) { + evas_textblock_style_free(st); + } +#ifdef TEST_NEWBACKEND + for (sclint loop = 0;loop < (sclint)g_TextCache.size();loop++) { + if (g_TextCache[loop].text == object->object) { + g_TextCache[loop].used = FALSE; + } + } +#endif + } else if (object->type == EFLOBJECT_IMAGE) { +#ifdef TEST_NEWBACKEND + for (sclint loop = 0;loop < (sclint)g_ImageCache.size();loop++) { + if (g_ImageCache[loop].image == object->object) { + g_ImageCache[loop].used = FALSE; + } + } +#endif + } + delete object; + } + } + list = eina_list_remove_list(list, iter); + } + window_context->etc_info = NULL; + } + + if (!(window_context->is_virtual)) { + /* FIXME : A workaround for the bug that event on a window being hidden is delivered to + e17, instead of the window itself or the window right below - Should report to WM */ + if (window == windows->get_nth_popup_window(SCL_WINDOW_Z_TOP)) { + ecore_timer_add(0.1f, destroy_later, (void*)window); + } else { + Evas_Object *win = (Evas_Object*)window; + evas_object_hide(win); + evas_object_del(win); + } + } + utils->log("WinNui_destroywin %p (basewin %p mag %p)\n", window, + windows->get_base_window(), windows->get_magnifier_window()); + } + } + + return TRUE; +} + +/** + * Shows the given window + */ +void +CSCLWindowsImplNui::show_window(const sclwindow window, sclboolean queue) +{ + SCL_DEBUG(); + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLContext *context = CSCLContext::get_instance(); + CSCLUtils *utils = CSCLUtils::get_instance(); + if (windows && context && window) { + SclWindowContext *window_context = windows->get_window_context(window); + if (!(context->get_hidden_state())) { + if (window_context) { + if (!(window_context->is_virtual)) { + evas_object_show((Evas_Object*)window); + } + + if (!(windows->get_update_pending())) { + update_window(window); + } + } + } + + scl8 popup_index = windows->find_popup_window_index(window); + if (windows->get_magnifier_window() == window || popup_index != NOT_USED) { + /* + * FIXME a solution to make magnifier window always on top + * N_SE-17689: magnifier window showing behind of candidate window + * + * N_SE-52548: ...and modified if() for other popup windows as well... + */ + if (window_context && !(window_context->is_virtual)) { + elm_win_raise((Evas_Object *)window); + } + } + + if (utils) { + utils->log("WinNui_showwin %p (basewin %p mag %p)\n", + window, + windows->get_base_window(), windows->get_magnifier_window()); + } + } +} + +/** + * Hides the given window + */ +void +CSCLWindowsImplNui::hide_window(const sclwindow window, sclboolean fForce) +{ + SCL_DEBUG(); + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLUtils *utils = CSCLUtils::get_instance(); + SclWindowContext *window_context = NULL; + + if (windows && window) { +#ifdef USING_KEY_GRAB + if (window == windows->get_base_window()) { + CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance(); + focus_handler->ungrab_keyboard(window); + } +#endif + + window_context = windows->get_window_context(window); + if (window_context) { + if (!(window_context->is_virtual)) { + Evas_Object *win = (Evas_Object*)window; + /* FIXME : A workaround for the bug that event on a window being hidden is delivered to + e17, instead of the window itself or the window right below - Should report to WM */ + if (window == windows->get_nth_popup_window(SCL_WINDOW_Z_TOP)) { + evas_object_move(win, -10000, -10000); + } else { +#ifdef WAYLAND + /* Under wayland environment, the visibility of keyboard window is controlled by + * wayland server, so it is not allowed to call evas_object_hide() for keyboard window + * directly on the keyboard side */ + if (win != windows->get_base_window()) { + evas_object_hide(win); + } +#else + evas_object_hide(win); +#endif + } + } + } + } + + if (windows && utils && window) { + // Memory optimization */ + if (window == windows->get_magnifier_window() || window == windows->get_dim_window()) { + if (window_context) { + if (window_context->etc_info) { +#ifdef TEST_NEWBACKEND +#else + Eina_List *list = (Eina_List*)(window_context->etc_info); + Eina_List *iter = NULL; + Eina_List *iter_next = NULL; + void *data = NULL; + int iIndex = 0; + EINA_LIST_FOREACH_SAFE(list, iter, iter_next, data) { + if (data) { + EFLObject *object = (EFLObject*)(data); + if (object) { + sclboolean bShouldRemove = FALSE; + bShouldRemove = TRUE; + if (bShouldRemove) { + Evas_Object* eo = object->object; + if (object->extracted) { + void *image_data = evas_object_image_data_get(eo, 1); + if (image_data) { + free(image_data); + } + } + if (eo) { + evas_object_del(eo); + object->object = NULL; + } + if (object->type == EFLOBJECT_TEXTBLOCK) { + Evas_Textblock_Style *st = (Evas_Textblock_Style*)(object->data); + if (st) { + evas_textblock_style_free(st); + } +#ifdef TEST_NEWBACKEND + for (sclint loop = 0;loop < g_TextCache.size();loop++) { + if (g_TextCache[loop].text == object->object) { + g_TextCache[loop].used = FALSE; + } + } +#endif + } else if (object->type == EFLOBJECT_IMAGE) { +#ifdef TEST_NEWBACKEND + for (sclint loop = 0;loop < g_ImageCache.size();loop++) { + if (g_ImageCache[loop].image == object->object) { + g_ImageCache[loop].used = FALSE; + } + } +#endif + } + delete object; + list = eina_list_remove_list(list, iter); + } + } + iIndex++; + } + } + window_context->etc_info = list; +#endif + } + } + //Evas *evas = evas_object_evas_get((Evas_Object*)window); + //evas_render_idle_flush(evas); + } + if (window == windows->get_base_window()) { + elm_cache_all_flush(); + malloc_trim(0); + } + utils->log("WinNui_hidewin %p (basewin %p mag %p)\n", + window, + windows->get_base_window(), windows->get_magnifier_window()); + } +} + +/** + * Moves the window to the given position + */ +sclint magnifierx, magnifiery; +void +CSCLWindowsImplNui::move_window(const sclwindow window, scl16 x, scl16 y) +{ + SCL_DEBUG(); + CSCLUtils *utils = CSCLUtils::get_instance(); + CSCLContext *context = CSCLContext::get_instance(); + CSCLWindows *windows = CSCLWindows::get_instance(); + + if (utils && context && windows && window) { + SclWindowContext *window_context = windows->get_window_context(window); + unsigned short win_width = 0; + unsigned short win_height = 0; + if (window_context) { + win_width = window_context->geometry.width; + win_height = window_context->geometry.height; + } + + scl16 rotatex = x; + scl16 rotatey = y; + scl16 orgx = x; + scl16 orgy = y; + + sclint scr_w, scr_h; + /* get window size */ + utils->get_screen_resolution(&scr_w, &scr_h); + +#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW + if (window == windows->get_magnifier_window()) { + SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window(), FALSE); + rotatex = orgx = 0; + if (context->get_rotation_degree() == 90 || context->get_rotation_degree() == 270) { + rotatey = orgy = scr_w - base_window_context->height - win_height; + win_width = base_window_context->width; + win_height = base_window_context->height + win_height; + } else { + rotatey = orgy = scr_h - base_window_context->height - win_height; + win_width = base_window_context->width; + win_height = base_window_context->height + win_height; + } + magnifierx = x; + magnifiery = y - orgy; + } +#endif + + switch (context->get_rotation()) { + case ROTATION_90_CW: { + rotatex = orgy; + rotatey = scr_w - orgx - win_width; + } + break; + case ROTATION_180: { + rotatex = scr_w - orgx - win_width; + rotatey = scr_h - orgy - win_height; + } + break; + case ROTATION_90_CCW: { + rotatex = scr_h - orgy - win_height; + rotatey = orgx; + } + break; + case ROTATION_0: break; + default: break; + } + + #ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW + if (window == windows->get_magnifier_window()) { + if (rotatex == window_context->x && rotatey == window_context->y) return; + } + #endif + + Evas_Object *win = (Evas_Object*)window; +#ifndef FULL_SCREEN_TEST + if (window != windows->get_base_window()) { + evas_object_move(win, rotatex, rotatey); + } +#endif + //Evas_Object *window_object = (Evas_Object*)window; + //Evas *evas = evas_object_evas_get(window_object); + //evas_render_idle_flush(evas); + + utils->log("WinNui_movewin %p %d %d %d %d (basewin %p mag %p)\n", + window, + x, y, rotatex, rotatey, + windows->get_base_window(), windows->get_magnifier_window()); + } +} + +/** +* Resizes the window to the given metric +*/ +void +CSCLWindowsImplNui::resize_window(const sclwindow window, scl16 width, scl16 height) +{ + SCL_DEBUG(); + + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLUtils *utils = CSCLUtils::get_instance(); + + if (!windows || !utils) return; + +#ifdef DO_NOT_MOVE_MAGNIFIER_WINDOW + if (window == windows->get_magnifier_window()) { + SclWindowContext *window_context = windows->get_window_context(windows->get_base_window()); + if (window_context->width != width || window_context->height != height) { + sclint scrx, scry, winx, winy; + utils->get_screen_resolution(&scrx, &scry); + if (context->get_rotation_degree() == 90 || context->get_rotation_degree() == 270) { + evas_object_resize((Evas_Object*)window, scry, height + window_context->height); + } else { + evas_object_resize((Evas_Object*)window, scrx, height + window_context->height); + } + } + return; + } +#endif + + Evas_Object *win = (Evas_Object*)window; +#ifndef FULL_SCREEN_TEST + if (windows && utils && window) { + utils->log("WinNui_resizewin %p %d %d (basewin %p mag %p)\n", + window, width, height, + windows->get_base_window(), windows->get_magnifier_window()); + } +#endif + //Evas_Object *window_object = (Evas_Object*)window; + //Evas *evas = evas_object_evas_get(window_object); + /*CSCLWindows *windows = CSCLWindows::get_instance(); + if (windows) { + windows->update_window(window); + }*/ + //evas_render_idle_flush(evas); + if (windows && window) { + if (window != windows->get_base_window()) { +#ifdef WAYLAND + Ecore_Wl2_Window *wl_window = (Ecore_Wl2_Window *)(elm_win_wl_window_get(win)); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_0], 0, 0, width, height); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_90_CW], 0, 0, height, width); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_180], 0, 0, width, height); + ecore_wl2_window_rotation_geometry_set(wl_window, + rotation_values_EFL[ROTATION_90_CCW], 0, 0, height, width); +#else + evas_object_resize(win, width, height); +#endif + } else { + g_timestamp_last_base_window_resized = (unsigned int)(ecore_loop_time_get() * 1000.0f); + } + + if (window == windows->get_dim_window()) { + hide_window(window); + } + } +} + +/** +* Resizes the window to the given metric +*/ +void +CSCLWindowsImplNui::move_resize_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height) +{ + SCL_DEBUG(); + Evas_Object *win = (Evas_Object*)window; +#ifndef FULL_SCREEN_TEST + CSCLWindows *windows = CSCLWindows::get_instance(); + CSCLUtils *utils = CSCLUtils::get_instance(); + if (windows && utils && window) { + if (window != windows->get_base_window()) { + evas_object_move(win, x, y); + evas_object_resize(win, width, height); + } + utils->log("WinNui_moveresizewin %p %d %d %d %d (basewin %p)\n", + window, x, y, width, height, windows->get_base_window()); + } +#endif + //Evas_Object *window_object = (Evas_Object*)window; + //Evas *evas = evas_object_evas_get(window_object); + /*CSCLWindows *windows = CSCLWindows::get_instance(); + if (windows) { + windows->update_window(window); + }*/ + //evas_render_idle_flush(evas); +} + +/** +* Update the window to redraw given area +*/ +void +CSCLWindowsImplNui::update_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height) +{ + SCL_DEBUG(); + + if (m_window_backend_callback) { + LOGI("call update_window. x(%d), y(%d), w(%d), h(%d)", x, y, width, height); + m_window_backend_callback->update_window(x, y, width, height, m_window_backend_callback_data); + } + else { + LOGW("### No update window callback ###"); + } +} + +/** + * Returns the position of x,y,width,height of the given window + */ +sclboolean +CSCLWindowsImplNui::get_window_rect(const sclwindow window, SclRectangle *rect) +{ + SCL_DEBUG(); + CSCLUtils *utils = CSCLUtils::get_instance(); + CSCLContext *context = CSCLContext::get_instance(); + + if (utils && context && rect && window) { + int x = 0, y = 0, width = 0, height = 0; + sclint scr_w = 0, scr_h = 0; + elm_win_screen_position_get(static_cast(window), &x, &y); + evas_object_geometry_get(static_cast(window), NULL, NULL, &width, &height); + + utils->log("WinNui_getwinrect %p %d %d %d %d\n", + window, x, y, width, height); + + /* get window size */ + utils->get_screen_resolution(&scr_w, &scr_h); + + switch (context->get_rotation()) + { + case ROTATION_90_CW: + { + rect->width = width; + rect->height = height; + rect->x = scr_w - y - width; + rect->y = x; + } + break; + case ROTATION_180: + { + rect->x = scr_w - width - x; + rect->y = scr_h - height - y; + rect->width = width; + rect->height = height; + } + break; + case ROTATION_90_CCW: + { + rect->width = width; + rect->height = height; + rect->x = y; + rect->y = scr_h - x - height; + } + break; + default: + { + rect->x = x; + rect->y = y; + rect->width = width; + rect->height = height; + } + break; + } + } + + return TRUE; +} + +/** + * Sets rotation + */ +void +CSCLWindowsImplNui::set_window_rotation(const sclwindow window, SCLRotation rotation) +{ + SCL_DEBUG(); +} + +/** + * Shows a message box + */ +void +CSCLWindowsImplNui::show_message_box(const sclwindow parent, scl8 msgType, sclchar* title, sclchar* msg) +{ + SCL_DEBUG(); +} + +void +CSCLWindowsImplNui::set_keep_above(const sclwindow window, sclboolean keepabove) +{ + SCL_DEBUG(); +} + +void CSCLWindowsImplNui::set_window_accepts_focus(const sclwindow window, sclboolean acceptable) +{ + elm_win_prop_focus_skip_set(static_cast(window), !acceptable); +} + +void CSCLWindowsImplNui::set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data) +{ + m_window_backend_callback = callback; + m_window_backend_callback_data = data; +} diff --git a/scl/sclwindows-nui.h b/scl/sclwindows-nui.h new file mode 100644 index 0000000..9b96235 --- /dev/null +++ b/scl/sclwindows-nui.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sclwindows.h" +#include "sclwindowbackendcallback.h" +#include +#include + +#ifndef __SCL_WINDOWS_NUI_H__ +#define __SCL_WINDOWS_NUI_H__ + +typedef enum { + EFLOBJECT_NONE, + EFLOBJECT_IMAGE, + EFLOBJECT_CLIPOBJECT, + EFLOBJECT_TEXTBLOCK, + EFLOBJECT_RECTANGLE, +} EFLOBJECT_TYPE; + +namespace scl +{ +typedef struct { + EFLOBJECT_TYPE type; + SclRectangle position; + Evas_Object *object; + const char *etc_info; + sclboolean extracted; + void *data; +} EFLObject; + +class CSCLWindowsImplNui : public CSCLWindowsImpl +{ +public : + CSCLWindowsImplNui(); + ~CSCLWindowsImplNui(); + + void init(); + void fini(); + + sclwindow create_base_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height); + sclwindow create_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height); + sclwindow create_magnifier_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height); + sclwindow create_dim_window(const sclwindow parent, SclWindowContext *window_context, scl16 width, scl16 height); + bool destroy_window(sclwindow window); + void show_window(const sclwindow window, sclboolean queue); + void hide_window(const sclwindow window, sclboolean fForce = FALSE); + void move_window(const sclwindow window, scl16 x, scl16 y); + void resize_window(const sclwindow window, scl16 width, scl16 height); + void move_resize_window(const sclwindow window, scl16 x, scl16 y, scl16 width, scl16 height); + void update_window(const sclwindow window, scl16 x = 0, scl16 y = 0, scl16 width = 0, scl16 height = 0); + void set_window_rotation(const sclwindow window, SCLRotation rotation); + void show_message_box(const sclwindow parent, scl8 msgType, sclchar* title, sclchar* msg); + sclboolean get_window_rect(const sclwindow window, SclRectangle *rect); + void set_parent(const sclwindow parent, const sclwindow window); + void set_keep_above(const sclwindow window, sclboolean keepabove); + + /* EFL specific utility functions */ + void set_window_accepts_focus(const sclwindow window, sclboolean accepts); + + void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data); + +private: + ISCLUIWindowBackendCallback* m_window_backend_callback; + void* m_window_backend_callback_data; +}; +} /* End of scl namespace */ +#endif diff --git a/scl/sclwindows.cpp b/scl/sclwindows.cpp index 45730c6..3c7631b 100644 --- a/scl/sclwindows.cpp +++ b/scl/sclwindows.cpp @@ -20,6 +20,8 @@ #include "sclwindows-win32.h" #elif defined(__EFL__) #include "sclwindows-efl.h" +#elif defined(__NUI__) +#include "sclwindows-nui.h" #else #include "sclwindows-gtk.h" #endif @@ -123,6 +125,8 @@ CSCLWindows::get_scl_windows_impl() m_impl = new CSCLWindowsImplWin32; #elif defined(__EFL__) m_impl = new CSCLWindowsImplEfl; +#elif defined(__NUI__) + m_impl = new CSCLWindowsImplNui; #else m_impl = new CSCLWindowsImplGtk; #endif @@ -1077,6 +1081,9 @@ CSCLWindows::update_window(const sclwindow window, coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index); if (coordinate) { // Update the highlighted area as well + LOGD("startx: %d, starty: %d", startx, starty); + LOGD("coordinate x(%d), y(%d), w(%d), h(%d)", coordinate->x, coordinate->y, coordinate->width, coordinate->height); + impl->update_window(window, startx + coordinate->x, starty + coordinate->y, coordinate->width, coordinate->height); } } @@ -1129,3 +1136,11 @@ CSCLWindows::get_window_rect(const sclwindow window, SclRectangle *rect) { return ret; } + +void CSCLWindows::set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data) +{ + CSCLWindowsImpl* impl = get_scl_windows_impl(); + if (impl) { + impl->set_window_backend_callback(callback, data); + } +} \ No newline at end of file diff --git a/scl/sclwindows.h b/scl/sclwindows.h index 15d54eb..579b2dd 100644 --- a/scl/sclwindows.h +++ b/scl/sclwindows.h @@ -21,6 +21,7 @@ #include "scltypes.h" #include "sclconfig.h" +#include "sclwindowbackendcallback.h" #ifndef __SCL_WINDOWS_H__ #define __SCL_WINDOWS_H__ @@ -95,6 +96,8 @@ public : virtual sclboolean get_window_rect(const sclwindow window, SclRectangle *rect) = 0; virtual void set_keep_above(const sclwindow window, sclboolean keep_above) = 0; + + virtual void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data) = 0; }; class CSCLWindows @@ -150,6 +153,8 @@ public : void set_update_pending(sclboolean pend); sclboolean get_update_pending(); + void set_window_backend_callback(ISCLUIWindowBackendCallback *callback, void *data); + protected : CSCLWindowsImpl* get_scl_windows_impl();