From d6c07c6cc58188a6c913fd5285b716657466caad Mon Sep 17 00:00:00 2001 From: Nakamura Hayato Date: Mon, 29 Jul 2013 14:33:50 +0900 Subject: [PATCH] Support Tizen 3.0 Change-Id: Icefff6e8437189cab41f9465919d09e3c97a0988 Signed-off-by: Nakamura Hayato --- configure.ac | 4 +- packaging/ico-uxf-weston-plugin.changes | 11 +- packaging/ico-uxf-weston-plugin.spec | 28 +- protocol/desktop-shell.xml | 112 + protocol/ico_input_mgr.xml | 39 +- protocol/ico_ivi_shell.xml | 51 - protocol/ico_window_mgr.xml | 204 +- protocol/input-method.xml | 273 ++ protocol/workspaces.xml | 27 + settings/ico_weston.csh | 2 + settings/ico_weston.sh | 2 + settings/weston.ini | 53 + settings/weston.service | 9 + src/Makefile.am | 77 +- src/config-parser.c | 223 -- src/ico_input_mgr.c | 86 +- src/ico_input_mgr.h | 46 + src/ico_ivi_common.c | 334 -- src/ico_ivi_common.h | 82 +- src/ico_ivi_shell.c | 6022 ++++++++++++++++++++++--------- src/ico_ivi_shell.h | 63 +- src/ico_plugin_loader.c | 82 +- src/ico_window_animation.c | 242 +- src/ico_window_mgr.c | 2076 +++++++---- src/ico_window_mgr.h | 82 +- tests/test-client.c | 20 +- tests/test-common.c | 15 +- tests/test-eflapp.c | 26 +- tests/test-homescreen.c | 241 +- tests/testdata/cl_surface1.dat | 12 +- tests/testdata/cl_surface4.dat | 11 + tests/testdata/hs_alltest.dat | 172 +- tests/testdata/hs_animatest.dat | 69 + tests/testdata/hs_animatest_all.dat | 67 + tests/weston-plugin-test | 19 +- tests/weston-plugin-test.anima | 69 + tests/weston-plugin-test.input | 2 +- tests/weston-plugin-test.notouch | 2 +- tests/weston-plugin-test.resize | 2 +- tests/weston-plugin-test.resize_flower | 2 +- tests/weston-plugin-test.resize_native | 2 +- tests/weston-plugin-test.resize_smoke | 2 +- tests/weston-plugin-test.resize_smoke2 | 2 +- tests/weston-plugin-test.slide | 2 +- tests/weston-plugin-test_gdb | 2 +- tests/weston-plugin-vbox | 72 + tests/weston.ini | 32 +- tests/weston_ivi_plugin.ini | 23 - weston.ini | 23 - weston_ivi_plugin.ini | 23 - 50 files changed, 7628 insertions(+), 3514 deletions(-) create mode 100644 protocol/desktop-shell.xml delete mode 100644 protocol/ico_ivi_shell.xml create mode 100644 protocol/input-method.xml create mode 100644 protocol/workspaces.xml create mode 100644 settings/ico_weston.csh create mode 100644 settings/ico_weston.sh create mode 100644 settings/weston.ini create mode 100644 settings/weston.service delete mode 100644 src/config-parser.c create mode 100644 src/ico_input_mgr.h delete mode 100644 src/ico_ivi_common.c create mode 100644 tests/testdata/cl_surface4.dat create mode 100644 tests/testdata/hs_animatest.dat create mode 100644 tests/testdata/hs_animatest_all.dat create mode 100755 tests/weston-plugin-test.anima create mode 100755 tests/weston-plugin-vbox delete mode 100644 tests/weston_ivi_plugin.ini delete mode 100644 weston.ini delete mode 100644 weston_ivi_plugin.ini diff --git a/configure.ac b/configure.ac index f4c05be..f38b3eb 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.68]) AC_INIT([ico-uxf-weston-plugin], - [0.5.02], + [0.7.01], [https://BUG-REPORT-ADDRESS]) AC_CONFIG_HEADERS([config.h]) @@ -30,7 +30,7 @@ AC_CHECK_HEADERS([execinfo.h]) AC_CHECK_FUNCS([mkostemp strchrnul]) -PKG_CHECK_MODULES([PLUGIN], [weston >= 1.0.6 pixman-1 xkbcommon]) +PKG_CHECK_MODULES([PLUGIN], [weston >= 1.1.1 pixman-1 xkbcommon]) if test "x$GCC" = "xyes"; then my_common_gcc_flags="-Wall -Wextra -Wno-unused-parameter \ diff --git a/packaging/ico-uxf-weston-plugin.changes b/packaging/ico-uxf-weston-plugin.changes index 8f7d9be..5a29c36 100644 --- a/packaging/ico-uxf-weston-plugin.changes +++ b/packaging/ico-uxf-weston-plugin.changes @@ -1,3 +1,13 @@ +* Mon Jul 29 2013 Shibata Makoto accepted/2.0alpha-wayland/20130612.174820@2b428f3 +- 0.7.01 release +- Following corrections for TizenIVI 3.0M1. +-- Correspondence to version up of Wayland/Weston(1.1.x => 1.2.0). +-- A change and the addition of the Wayland expansion protocol for referencePF version 0.9. +-- Correspondence to start method of TizenIVI 3.0(system V => systemd). + +- 0.5.07 release +- fix for - When application generated Surface, ico_ivi_shell may not notify application of configure event. + * Wed Jun 12 2013 Shibata Makoto submit/2.0alpha-wayland/20130612.051916@5247a37 - 0.5.06 release - fixed for - weston loop forever when a fading animation is required in an animation of the fading again by same surface. @@ -43,4 +53,3 @@ * Fri Apr 26 2013 Shibata Makoto 3224fe9 - Import initial. - diff --git a/packaging/ico-uxf-weston-plugin.spec b/packaging/ico-uxf-weston-plugin.spec index 9a6373d..f9db9b4 100644 --- a/packaging/ico-uxf-weston-plugin.spec +++ b/packaging/ico-uxf-weston-plugin.spec @@ -1,22 +1,25 @@ Name: ico-uxf-weston-plugin Summary: Weston Plugins for IVI -Version: 0.5.06 +Version: 0.7.01 Release: 1.1 Group: System/GUI/Libraries License: MIT URL: "" Source0: %{name}-%{version}.tar.bz2 -BuildRequires: pkgconfig(weston) >= 1.0.6 +BuildRequires: pkgconfig(weston) >= 1.2 +BuildRequires: pkgconfig(pixman-1) +BuildRequires: pkgconfig(xkbcommon) >= 0.0.578 BuildRequires: pkgconfig(eina) BuildRequires: pkgconfig(evas) BuildRequires: pkgconfig(eina) BuildRequires: pkgconfig(elementary) BuildRequires: pkgconfig(ecore-wayland) +BuildRequires: mesa-devel BuildRequires: aul-devel BuildRequires: ecore-devel -BuildRequires: weston-devel -Requires: weston >= 1.0.6 +BuildRequires: weston-devel >= 1.2 +Requires: weston >= 1.2 %description Weston Plugins for IVI @@ -47,20 +50,27 @@ rm -rf %{buildroot} # configurations %define weston_conf %{_sysconfdir}/xdg/weston mkdir -p %{buildroot}%{weston_conf} > /dev/null 2>&1 -install -m 0644 weston.ini %{buildroot}%{weston_conf} -install -m 0644 weston_ivi_plugin.ini %{buildroot}%{weston_conf} +install -m 0644 settings/weston.ini %{buildroot}%{weston_conf} +mkdir -p %{buildroot}%{_sysconfdir}/profile.d/ +install -m 0644 settings/ico_weston.sh %{buildroot}%{_sysconfdir}/profile.d/ +install -m 0644 settings/ico_weston.csh %{buildroot}%{_sysconfdir}/profile.d/ %files %defattr(-,root,root,-) %dir %{_libdir}/weston/ %{_libdir}/weston/*.so %{_libdir}/libico-uxf-weston-plugin.so.* -%config(noreplace) %{weston_conf}/weston.ini -%config(noreplace) %{weston_conf}/weston_ivi_plugin.ini +%{weston_conf}/weston.ini +%{_sysconfdir}/profile.d/ico_weston.sh +%{_sysconfdir}/profile.d/ico_weston.csh %files devel %defattr(-,root,root,-) +%{_includedir}/%{name}/desktop-shell-client-protocol.h +%{_includedir}/%{name}/input-method-client-protocol.h +%{_includedir}/%{name}/workspaces-client-protocol.h %{_includedir}/%{name}/ico_input_mgr-client-protocol.h -%{_includedir}/%{name}/ico_ivi_shell-client-protocol.h %{_includedir}/%{name}/ico_window_mgr-client-protocol.h +%{_includedir}/%{name}/ico_input_mgr.h %{_libdir}/libico-uxf-weston-plugin.so + diff --git a/protocol/desktop-shell.xml b/protocol/desktop-shell.xml new file mode 100644 index 0000000..65e44a7 --- /dev/null +++ b/protocol/desktop-shell.xml @@ -0,0 +1,112 @@ + + + + + Traditional user interfaces can rely on this interface to define the + foundations of typical desktops. Currently it's possible to set up + background, panels and locking surfaces. + + + + + + + + + + + + + + + + + + + + + The surface set by this request will receive a fake + pointer.enter event during grabs at position 0, 0 and is + expected to set an appropriate cursor image as described by + the grab_cursor event sent just before the enter event. + + + + + + + Tell the server, that enough desktop elements have been drawn + to make the desktop look ready for use. During start-up, the + server can wait for this request with a black screen before + starting to fade in the desktop, for instance. If the client + parts of a desktop take a long time to initialize, we avoid + showing temporary garbage. + + + + + + + + + + + + + + Tell the shell we want it to create and set the lock surface, which is + a GUI asking the user to unlock the screen. The lock surface is + announced with 'set_lock_surface'. Whether or not the shell actually + implements locking, it MUST send 'unlock' request to let the normal + desktop resume. + + + + + + This event will be sent immediately before a fake enter event on the + grab surface. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Only one client can bind this interface at a time. + + + + + A screensaver surface is normally hidden, and only visible after an + idle timeout. + + + + + + + + diff --git a/protocol/ico_input_mgr.xml b/protocol/ico_input_mgr.xml index 25df531..ff1c86d 100644 --- a/protocol/ico_input_mgr.xml +++ b/protocol/ico_input_mgr.xml @@ -13,7 +13,8 @@ - + + @@ -24,6 +25,17 @@ + + + + Mouse, Touch or Keyboard event sent to application. + + + + + + + @@ -32,6 +44,23 @@ and notify application of ON/OFF of the switch. + + + + + + + + + + + + + + + + + Send Input device and switch information to application @@ -80,6 +109,7 @@ + @@ -114,6 +144,13 @@ + + + + Send input region to haptic controller. + + + diff --git a/protocol/ico_ivi_shell.xml b/protocol/ico_ivi_shell.xml deleted file mode 100644 index 7efa339..0000000 --- a/protocol/ico_ivi_shell.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - In-Vehicle Infortaiment(IVI) interface to define the - foundations of typical desktops. Currently it's possible to set up - background, panels and locking surfaces. - - - - - Select active target(pointer/keyboard). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/protocol/ico_window_mgr.xml b/protocol/ico_window_mgr.xml index e69fb4c..b6914f5 100644 --- a/protocol/ico_window_mgr.xml +++ b/protocol/ico_window_mgr.xml @@ -1,19 +1,41 @@ - - for IVI HomeScreen interface. + + for IVI SystemController interface. + + + General values for ico_window_mgr. + + + + + + + Declare manager application(ex. SystemController). + + + + + + + + Layer attribute. + + + + + + + Surface show/hide control define. - - - @@ -22,77 +44,178 @@ - - - - Set client application attribute. + + + With/Without animation of surface change. - + + - - - + + + Type of the cutaway for surface animation. + + + + + + + + + + Event type of mapped surface change. + + + + + + + + + + Set surface active target device. + + + + + + + + + + Surafce change hint information. + + + + + + + + Set manager application(ex.SystemController). + + - - + + + Create layer Id and set attribute. + + + + + Surface belong to a layer. + - + + + Set surface display position and surface size. + + + + + Show/Hide and Raise/Lower surface. + + + + Set surface animation type. + + + + Set active surface. + - + - + + Show/Hide layer. + + - + + + Get surfaces of the application. + - - + + + + + Map surfaces to shared memory. + + + + + + + + + Unmap surfaces to shared memory. + + + + Surface create event to manager. + + + + + Surface name event to manager. + + + + + + + Surface destory event to manager. + + + Surface visibility change event to manager. + @@ -100,9 +223,12 @@ + + Surface attribute change event to manager. + - - + + @@ -111,10 +237,40 @@ + + Surface active change event to manager. + - + + + + + + Layer visibility change event to manager. + + + + + + Reply of app_surfaces request. + + + + + + + + Reply of map_surface request. + + + + + + + + diff --git a/protocol/input-method.xml b/protocol/input-method.xml new file mode 100644 index 0000000..70afdcb --- /dev/null +++ b/protocol/input-method.xml @@ -0,0 +1,273 @@ + + + + Copyright © 2012, 2013 Intel Corporation + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + + + + + Corresponds to a text model on input method side. An input method context + is created on text mode activation on the input method side. It allows to + receive information about the text model from the application via events. + Input method contexts do not keep state after deactivation and should be + destroyed after deactivation is handled. + + Text is generally UTF-8 encoded, indices and lengths are in bytes. + + Serials are used to synchronize the state between the text input and + an input method. New serials are sent by the text input in the + commit_state request and are used by the input method to indicate + the known text input state in events like preedit_string, commit_string, + and keysym. The text input can then ignore events from the input method + which are based on an outdated state (for example after a reset). + + + + + Send the commit string text for insertion to the application. + + The text to commit could be either just a single character after a key + press or the result of some composing (pre-edit). It could be also an + empty text when some text should be removed (see + delete_surrounding_text) or when the input cursor should be moved (see + cursor_position). + + Any previously set composing text will be removed. + + + + + + + Send the pre-edit string text to the application text input. + + The commit text can be used to replace the preedit text on reset (for + example on unfocus). + + Also previously sent preedit_style and preedit_cursor requests are + processed bt the text_input also. + + + + + + + + Sets styling information on composing text. The style is applied for + length in bytes from index relative to the beginning of + the composing text (as byte offset). Multiple styles can + be applied to a composing text. + + This request should be sent before sending preedit_string request. + + + + + + + + Sets the cursor position inside the composing text (as byte offset) + relative to the start of the composing text. + + When index is negative no cursor should be displayed. + + This request should be sent before sending preedit_string request. + + + + + + + + This request will be handled on text_input side as part of a directly + following commit_string request. + + + + + + + Sets the cursor and anchor to a new position. Index is the new cursor + position in bytess (when >= 0 relative to the end of inserted text + else relative to beginning of inserted text). Anchor is the new anchor + position in bytes (when >= 0 relative to the end of inserted text, else + relative to beginning of inserted text). When there should be no + selected text anchor should be the same as index. + + This request will be handled on text_input side as part of a directly + following commit_string request. + + + + + + + + + + Notify when a key event was sent. Key events should not be used for + normal text input operations, which should be done with commit_string, + delete_surrounfing_text, etc. The key event follows the wl_keyboard key + event convention. Sym is a XKB keysym, state a wl_keyboard key_state. + + + + + + + + + + Allows an input method to receive hardware keyboard input and process + key events to generate text events (with pre-edit) over the wire. This + allows input methods which compose multiple key events for inputting + text like it is done for CJK languages. + + + + + + Should be used when filtering key events with grab_keyboard. + + When the wl_keyboard::key event is not processed by the input + method itself and should be sent to the client instead, forward it + with this request. The arguments should be the ones from the + wl_keyboard::key event. + + For generating custom key events use the keysym request instead. + + + + + + + + + Should be used when filtering key events with grab_keyboard. + + When the wl_keyboard::modifiers event should be also send to the + client, forward it with this request. The arguments should be the ones + from the wl_keyboard::modifiers event. + + + + + + + + + + + + + + + + + + The plain surrounding text around the input position. Cursor is the + position in bytes within the surrounding text relative to the beginning + of the text. Anchor is the position in bytes of the selection anchor + within the surrounding text relative to the beginning of the text. If + there is no selected text anchor is the same as cursor. + + + + + + + + + + + + + + + + + + + + + + + + + + An input method object is responsible to compose text in response to + input from hardware or virtual keyboards. There is one input method + object per seat. On activate there is a new input method context object + created which allows the input method to communicate with the text model. + + + + A text model was activated. Creates an input method context object + which allows communication with the text model. + + + + + + The text model corresponding to the context argument was deactivated. + The input method context should be destroyed after deactivation is + handled. + + + + + + + + Only one client can bind this interface at a time. + + + + + + + + + + + + + + + + A keybaord surface is only shown, when a text model is active + + + + + + + + An overlay panel is shown near the input cursor above the application + window when a text model is active. + + + + diff --git a/protocol/workspaces.xml b/protocol/workspaces.xml new file mode 100644 index 0000000..22f4802 --- /dev/null +++ b/protocol/workspaces.xml @@ -0,0 +1,27 @@ + + + + + An interface for managing surfaces in workspaces. + + + + + Move the given surface to the specified workspace. + + + + + + + + The current workspace state, such as current workspace and workspace + count, has changed. + + + + + + + + diff --git a/settings/ico_weston.csh b/settings/ico_weston.csh new file mode 100644 index 0000000..66a11e2 --- /dev/null +++ b/settings/ico_weston.csh @@ -0,0 +1,2 @@ +setenv XDG_RUNTIME_DIR /run/user/5000 +setenv XDG_CONFIG_HOME /etc/xdg/weston diff --git a/settings/ico_weston.sh b/settings/ico_weston.sh new file mode 100644 index 0000000..65a827f --- /dev/null +++ b/settings/ico_weston.sh @@ -0,0 +1,2 @@ +export XDG_RUNTIME_DIR=/run/user/5000 +export XDG_CONFIG_HOME=/etc/xdg/weston diff --git a/settings/weston.ini b/settings/weston.ini new file mode 100644 index 0000000..aa0f78c --- /dev/null +++ b/settings/weston.ini @@ -0,0 +1,53 @@ +[core] +modules=ico_plugin_loader.so + +#[input-method] +#path=/no_input_method_err_but_no_problem.so + +[shell] +num-workspaces=1 +shell-exe= + +[output] +name=HDMI3 +#mode=1680x945 +mode=173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync +#transform=90 + +#[output] +#name=LVDS1 +#mode=1680x1050 +#transform=90 + +#[output] +#name=VGA1 +#mode=173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync +#transform=90 + +#[output] +#name=X1 +#mode=1024x768 +#transform=flipped-270 + +[ivi-plugin] +modules=ico_ivi_shell.so,ico_window_mgr.so,ico_window_animation.so,ico_input_mgr.so + +[ivi-display] +displayno=1,0 + +[ivi-animation] +# default animation +default=fade +# animation time (ms) +time=500 +# animation frame rate(frame/sec) +fps=15 + +[ivi-debug] +# debug flags +# bit.0 0=hide on surface create(for with HomeScreen)/1=show on surface create +flag=0 + +# 0=no debug log write(1=err/2=warn/3=info/4=debug) +log=4 + diff --git a/settings/weston.service b/settings/weston.service new file mode 100644 index 0000000..16d2980 --- /dev/null +++ b/settings/weston.service @@ -0,0 +1,9 @@ +[Unit] +Description=Weston +Requires=dbus.socket + +[Service] +ExecStart=/usr/bin/weston-launch --user app -- -i0 --log=/tmp/weston.log + +[Install] +WantedBy=weston.target diff --git a/src/Makefile.am b/src/Makefile.am index 784549f..26e6570 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,14 +1,19 @@ lib_LTLIBRARIES = libico-uxf-weston-plugin.la pkginclude_HEADERS = \ - ico_ivi_shell-client-protocol.h \ + desktop-shell-client-protocol.h \ + input-method-client-protocol.h \ + workspaces-client-protocol.h \ ico_window_mgr-client-protocol.h \ - ico_input_mgr-client-protocol.h + ico_input_mgr-client-protocol.h \ + ico_input_mgr.h libico_uxf_weston_plugin_la_LIBADD = -lrt -lm -libico_uxf_weston_plugin_la_LDFLAGS = -version-info 0:5:0 +libico_uxf_weston_plugin_la_LDFLAGS = -version-info 0:7:0 libico_uxf_weston_plugin_la_SOURCES = \ - ico_ivi_shell-protocol.c \ + desktop-shell-protocol.c \ + input-method-protocol.c \ + workspaces-protocol.c \ ico_window_mgr-protocol.c \ ico_input_mgr-protocol.c @@ -29,7 +34,6 @@ git-version.h : .FORCE moduledir = @libdir@/weston module_LTLIBRARIES = \ $(ico_plugin_loader) \ - $(ico_ivi_common) \ $(ico_ivi_shell) \ $(ico_window_mgr) \ $(ico_window_animation) \ @@ -40,18 +44,9 @@ ico_plugin_loader = ico_plugin_loader.la ico_plugin_loader_la_LDFLAGS = -module -avoid-version ico_plugin_loader_la_LIBADD = $(PLUGIN_LIBS) ico_plugin_loader_la_CFLAGS = $(GCC_CFLAGS) $(EXT_CFLAGS) $(PLUGIN_CFLAGS) -ico_plugin_loader_la_SOURCES = \ - ico_plugin_loader.c \ - config-parser.c # Remove once Weston SDK exports config functions. - -# IVI Common Functions -ico_ivi_common = ico_ivi_common.la -ico_ivi_common_la_LDFLAGS = -module -avoid-version -ico_ivi_common_la_LIBADD = $(PLUGIN_LIBS) -ico_ivi_common_la_CFLAGS = $(GCC_CFLAGS) $(EXT_CFLAGS) $(PLUGIN_CFLAGS) -ico_ivi_common_la_SOURCES = \ - ico_ivi_common.c \ - config-parser.c # Remove once Weston SDK exports config functions. +ico_plugin_loader_la_SOURCES = \ + ico_plugin_loader.c \ + ico_ivi_common.h # IVI-Shell ico_ivi_shell = ico_ivi_shell.la @@ -59,10 +54,15 @@ ico_ivi_shell_la_LDFLAGS = -module -avoid-version ico_ivi_shell_la_LIBADD = $(PLUGIN_LIBS) ico_ivi_shell_la_CFLAGS = $(GCC_CFLAGS) $(EXT_CFLAGS) $(PLUGIN_CFLAGS) ico_ivi_shell_la_SOURCES = \ - ico_ivi_shell.c \ - ico_ivi_shell-protocol.c \ - ico_ivi_shell-server-protocol.h \ - config-parser.c # Remove once Weston SDK exports config functions. + ico_ivi_shell.c \ + ico_ivi_shell.h \ + ico_ivi_common.h \ + desktop-shell-protocol.c \ + input-method-protocol.c \ + workspaces-protocol.c \ + desktop-shell-server-protocol.h \ + input-method-server-protocol.h \ + workspaces-server-protocol.h # Multi Window Manager ico_window_mgr = ico_window_mgr.la @@ -70,7 +70,10 @@ ico_window_mgr_la_LDFLAGS = -module -avoid-version ico_window_mgr_la_LIBADD = $(PLUGIN_LIBS) $(AUL_LIBS) ico_window_mgr_la_CFLAGS = $(GCC_CFLAGS) $(EXT_CFLAGS) $(PLUGIN_CFLAGS) ico_window_mgr_la_SOURCES = \ - ico_window_mgr.c \ + ico_window_mgr.c \ + ico_window_mgr.h \ + ico_ivi_common.h \ + ico_ivi_shell.h \ ico_window_mgr-protocol.c \ ico_window_mgr-server-protocol.h # @@ -79,8 +82,10 @@ ico_window_animation = ico_window_animation.la ico_window_animation_la_LDFLAGS = -module -avoid-version ico_window_animation_la_LIBADD = $(PLUGIN_LIBS) $(AUL_LIBS) ico_window_animation_la_CFLAGS = $(GCC_CFLAGS) $(EXT_CFLAGS) $(PLUGIN_CFLAGS) -ico_window_animation_la_SOURCES = \ - ico_window_animation.c +ico_window_animation_la_SOURCES = \ + ico_window_animation.c \ + ico_window_mgr.h \ + ico_ivi_common.h # Multi Input Manager ico_input_mgr = ico_input_mgr.la @@ -88,22 +93,30 @@ ico_input_mgr_la_LDFLAGS = -module -avoid-version ico_input_mgr_la_LIBADD = $(PLUGIN_LIBS) ico_input_mgr_la_CFLAGS = $(GCC_CFLAGS) $(EXT_CFLAGS) $(PLUGIN_CFLAGS) ico_input_mgr_la_SOURCES = \ - ico_input_mgr.c \ + ico_input_mgr.c \ + ico_input_mgr.h \ + ico_window_mgr.h \ + ico_ivi_common.h \ ico_input_mgr-protocol.c \ ico_input_mgr-server-protocol.h # Wayland protocol(Build by wayland-scanner) -BUILT_SOURCES = \ - ico_ivi_shell-protocol.c \ - ico_ivi_shell-server-protocol.h \ - ico_ivi_shell-client-protocol.h \ +BUILT_SOURCES = \ + desktop-shell-protocol.c \ + desktop-shell-server-protocol.h \ + desktop-shell-client-protocol.h \ + input-method-protocol.c \ + input-method-server-protocol.h \ + input-method-client-protocol.h \ + workspaces-protocol.c \ + workspaces-server-protocol.h \ + workspaces-client-protocol.h \ ico_window_mgr-protocol.c \ ico_window_mgr-server-protocol.h \ ico_window_mgr-client-protocol.h \ ico_input_mgr-protocol.c \ - ico_input_mgr-server-protocol.h \ - ico_input_mgr-client-protocol.h \ - git-version.h + ico_input_mgr-server-protocol.h \ + ico_input_mgr-client-protocol.h CLEANFILES = $(BUILT_SOURCES) diff --git a/src/config-parser.c b/src/config-parser.c deleted file mode 100644 index 261c425..0000000 --- a/src/config-parser.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#define _GNU_SOURCE /* for stchrnul() */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static int -handle_key(const struct config_key *key, const char *value) -{ - char *end, *s; - int i, len; - unsigned int ui; - - switch (key->type) { - case CONFIG_KEY_INTEGER: - i = strtol(value, &end, 0); - if (*end != '\n') { - fprintf(stderr, "invalid integer: %s\n", value); - return -1; - } - *(int *)key->data = i; - return 0; - - case CONFIG_KEY_UNSIGNED_INTEGER: - ui = strtoul(value, &end, 0); - if (*end != '\n') { - fprintf(stderr, "invalid integer: %s\n", value); - return -1; - } - *(unsigned int *)key->data = ui; - return 0; - - case CONFIG_KEY_STRING: - len = strlen(value); - while (len > 0 && isspace(value[len - 1])) - len--; - s = malloc(len + 1); - if (s == NULL) - return -1; - memcpy(s, value, len); - s[len] = '\0'; - *(char **)key->data = s; - return 0; - - case CONFIG_KEY_BOOLEAN: - if (strcmp(value, "false\n") == 0) - *(int *)key->data = 0; - else if (strcmp(value, "true\n") == 0) - *(int *)key->data = 1; - else { - fprintf(stderr, "invalid bool: %s\n", value); - return -1; - } - return 0; - - default: - assert(0); - break; - } - - return -1; -} - -int -parse_config_file(int fd, - const struct config_section *sections, int num_sections, - void *data) -{ - FILE *fp; - char line[512], *p; - const struct config_section *current = NULL; - int i; - - if (fd == -1) - return -1; - - fp = fdopen(dup(fd), "r"); - if (fp == NULL) { - perror("couldn't open config file"); - return -1; - } - - rewind(fp); - - while (fgets(line, sizeof line, fp)) { - if (line[0] == '#' || line[0] == '\n') { - continue; - } if (line[0] == '[') { - p = strchr(&line[1], ']'); - if (!p || p[1] != '\n') { - fprintf(stderr, "malformed " - "section header: %s\n", line); - fclose(fp); - return -1; - } - if (current && current->done) - current->done(data); - p[0] = '\0'; - for (i = 0; i < num_sections; i++) { - if (strcmp(sections[i].name, &line[1]) == 0) { - current = §ions[i]; - break; - } - } - if (i == num_sections) - current = NULL; - } else if (p = strchr(line, '='), p != NULL) { - if (current == NULL) - continue; - p[0] = '\0'; - for (i = 0; i < current->num_keys; i++) { - if (strcmp(current->keys[i].name, line) == 0) { - if (handle_key(¤t->keys[i], &p[1]) < 0) { - fclose(fp); - return -1; - } - break; - } - } - } else { - fprintf(stderr, "malformed config line: %s\n", line); - fclose(fp); - return -1; - } - } - - if (current && current->done) - current->done(data); - - fclose(fp); - - return 0; -} - -int -open_config_file(const char *name) -{ - const char *config_dir = getenv("XDG_CONFIG_HOME"); - const char *home_dir = getenv("HOME"); - const char *config_dirs = getenv("XDG_CONFIG_DIRS"); - char path[PATH_MAX]; - const char *p, *next; - int fd; - - /* Precedence is given to config files in the home directory, - * and then to directories listed in XDG_CONFIG_DIRS and - * finally to the current working directory. */ - - /* $XDG_CONFIG_HOME */ - if (config_dir) { - snprintf(path, sizeof path, "%s/%s", config_dir, name); - fd = open(path, O_RDONLY | O_CLOEXEC); - if (fd >= 0) - return fd; - } - - /* $HOME/.config */ - if (home_dir) { - snprintf(path, sizeof path, "%s/.config/%s", home_dir, name); - fd = open(path, O_RDONLY | O_CLOEXEC); - if (fd >= 0) - return fd; - } - - /* For each $XDG_CONFIG_DIRS: weston/ */ - if (!config_dirs) - config_dirs = "/etc/xdg"; /* See XDG base dir spec. */ - - for (p = config_dirs; *p != '\0'; p = next) { - next = strchrnul(p, ':'); - snprintf(path, sizeof path, - "%.*s/weston/%s", (int)(next - p), p, name); - fd = open(path, O_RDONLY | O_CLOEXEC); - if (fd >= 0) - return fd; - - if (*next == ':') - next++; - } - - /* Current working directory. */ - snprintf(path, sizeof path, "./%s", name); - fd = open(path, O_RDONLY | O_CLOEXEC); - - if (fd >= 0) - fprintf(stderr, - "using config in current working directory: %s\n", - path); - else - fprintf(stderr, "config file \"%s\" not found.\n", name); - - return fd; -} diff --git a/src/ico_input_mgr.c b/src/ico_input_mgr.c index b7d8882..1b28d6a 100644 --- a/src/ico_input_mgr.c +++ b/src/ico_input_mgr.c @@ -24,7 +24,7 @@ /** * @brief Multi Input Manager (Weston(Wayland) PlugIn) * - * @date Feb-08-2013 + * @date Jul-26-2013 */ #include @@ -44,6 +44,7 @@ #include "ico_ivi_common.h" #include "ico_ivi_shell.h" #include "ico_window_mgr.h" +#include "ico_input_mgr.h" #include "ico_input_mgr-server-protocol.h" /* degine maximum length */ @@ -122,7 +123,7 @@ static struct ico_app_mgr *find_app_by_appid(const char *appid); /* add input event to application */ static void ico_mgr_add_input_app(struct wl_client *client, struct wl_resource *resource, const char *appid, const char *device, int32_t input, - uint32_t fix); + int32_t fix, int32_t keycode); /* delete input event to application */ static void ico_mgr_del_input_app(struct wl_client *client, struct wl_resource *resource, const char *appid, const char *device, int32_t input); @@ -140,9 +141,6 @@ static void ico_device_input_event(struct wl_client *client, struct wl_resource uint32_t time, const char *device, int32_t input, int32_t code, int32_t state); -/* entry finction called by Weston */ -WL_EXPORT int module_init(struct weston_compositor *ec); - /* definition of Wayland protocol */ /* mgr interface */ static const struct ico_input_mgr_control_interface ico_input_mgr_implementation = { @@ -171,15 +169,17 @@ struct ico_input_mgr *pInputMgr = NULL; * @param[in] device device name * @param[in] input input switch number * @param[in] fix fix to application(1=fix,0=general) + * @param[in] keycode switch map to keyboard operation(0=not map to keyboard) * @return none */ /*--------------------------------------------------------------------------*/ static void ico_mgr_add_input_app(struct wl_client *client, struct wl_resource *resource, - const char *appid, const char *device, int32_t input, uint32_t fix) + const char *appid, const char *device, int32_t input, + int32_t fix, int32_t keycode) { - uifw_trace("ico_mgr_add_input_app: Enter(appid=%s,dev=%s,input=%d,fix=%d)", - appid, device, input, fix); + uifw_trace("ico_mgr_add_input_app: Enter(appid=%s,dev=%s,input=%d,fix=%d,key=%d)", + appid, device, input, fix, keycode); struct ico_ictl_mgr *pIctlMgr; struct ico_ictl_input *pInput; @@ -602,7 +602,7 @@ ico_control_bind(struct wl_client *client, void *data, uint32_t version, uint32_ struct ico_app_mgr *pAppMgr; uifw_trace("ico_control_bind: Enter(client=%08x)", (int)client); - appid = ico_window_mgr_appid(client); + appid = ico_window_mgr_get_appid(client); if (! appid) { /* client dose not exist */ @@ -625,11 +625,13 @@ ico_control_bind(struct wl_client *client, void *data, uint32_t version, uint32_ } pAppMgr->client = client; if (! pAppMgr->mgr_resource) { - pAppMgr->mgr_resource = wl_client_add_object(client, - &ico_input_mgr_control_interface, - &ico_input_mgr_implementation, - id, pInputMgr); - pAppMgr->mgr_resource->destroy = ico_control_unbind; + pAppMgr->mgr_resource = wl_resource_create(client, + &ico_input_mgr_control_interface, 1, id); + if (pAppMgr->mgr_resource) { + wl_resource_set_implementation(pAppMgr->mgr_resource, + &ico_input_mgr_implementation, + pInputMgr, ico_control_unbind); + } } uifw_trace("ico_control_bind: Leave"); } @@ -656,8 +658,6 @@ ico_control_unbind(struct wl_resource *resource) break; } } - - free(resource); uifw_trace("ico_control_unbind: Leave"); } @@ -679,10 +679,11 @@ ico_device_bind(struct wl_client *client, void *data, uint32_t version, uint32_t uifw_trace("ico_device_bind: Enter(client=%08x)", (int)client); - mgr_resource = wl_client_add_object(client, &ico_input_mgr_device_interface, - &input_mgr_ictl_implementation, - id, NULL); - mgr_resource->destroy = ico_device_unbind; + mgr_resource = wl_resource_create(client, &ico_input_mgr_device_interface, 1, id); + if (mgr_resource) { + wl_resource_set_implementation(mgr_resource, &input_mgr_ictl_implementation, + NULL, ico_device_unbind); + } uifw_trace("ico_device_bind: Leave"); } @@ -698,7 +699,6 @@ static void ico_device_unbind(struct wl_resource *resource) { uifw_trace("ico_device_unbind: Enter(resource=%08x)", (int)resource); - free(resource); uifw_trace("ico_device_unbind: Leave"); } @@ -722,7 +722,7 @@ ico_exinput_bind(struct wl_client *client, void *data, uint32_t version, uint32_ struct ico_ictl_mgr *pIctlMgr; struct ico_ictl_input *pInput; - appid = ico_window_mgr_appid(client); + appid = ico_window_mgr_get_appid(client); uifw_trace("ico_exinput_bind: Enter(client=%08x,%s)", (int)client, appid ? appid : "(NULL)"); @@ -748,9 +748,11 @@ ico_exinput_bind(struct wl_client *client, void *data, uint32_t version, uint32_ } pAppMgr->client = client; if (! pAppMgr->resource) { - pAppMgr->resource = wl_client_add_object(client, &ico_exinput_interface, - NULL, id, pInputMgr); - pAppMgr->resource->destroy = ico_exinput_unbind; + pAppMgr->resource = wl_resource_create(client, &ico_exinput_interface, 1, id); + if (pAppMgr->resource) { + wl_resource_set_implementation(pAppMgr->resource, NULL, + pInputMgr, ico_exinput_unbind); + } } /* send all capabilities */ @@ -766,7 +768,7 @@ ico_exinput_bind(struct wl_client *client, void *data, uint32_t version, uint32_ uifw_trace("ico_exinput_bind: Input %s not initialized", pIctlMgr->device); continue; } - if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) { + if ((pInput->app != NULL) && (pInput->app != pAppMgr) && (pInput->fix)) { uifw_trace("ico_exinput_bind: Input %s.%s fixed assign to App.%s", pIctlMgr->device, pInput->swname, pInput->app->appid); continue; @@ -835,8 +837,6 @@ ico_exinput_unbind(struct wl_resource *resource) } } } - - free(resource); uifw_trace("ico_exinput_unbind: Leave"); } @@ -915,15 +915,17 @@ find_app_by_appid(const char *appid) * @brief module_init: initialization of this plugin * * @param[in] ec weston compositor + * @param[in] argc number of arguments(unused) + * @param[in] argv argument list(unused) * @return result * @retval 0 OK * @retval -1 error */ /*--------------------------------------------------------------------------*/ WL_EXPORT int -module_init(struct weston_compositor *ec) +module_init(struct weston_compositor *ec, int *argc, char *argv[]) { - uifw_trace("ico_input_mgr: Enter(module_init)"); + uifw_info("ico_input_mgr: Enter(module_init)"); /* initialize management table */ pInputMgr = (struct ico_input_mgr *)malloc(sizeof(struct ico_input_mgr)); @@ -935,27 +937,23 @@ module_init(struct weston_compositor *ec) pInputMgr->compositor = ec; /* interface to desktop manager(ex.HomeScreen) */ - if (wl_display_add_global(ec->wl_display, - &ico_input_mgr_control_interface, - pInputMgr, - ico_control_bind) == NULL) { - uifw_trace("ico_input_mgr: wl_display_add_global mgr failed"); + if (wl_global_create(ec->wl_display, &ico_input_mgr_control_interface, 1, + pInputMgr, ico_control_bind) == NULL) { + uifw_trace("ico_input_mgr: wl_global_create mgr failed"); return -1; } /* interface to Input Controller(ictl) */ - if (wl_display_add_global(ec->wl_display, - &ico_input_mgr_device_interface, - pInputMgr, - ico_device_bind) == NULL) { - uifw_trace("ico_input_mgr: wl_display_add_global ictl failed"); + if (wl_global_create(ec->wl_display, &ico_input_mgr_device_interface, 1, + pInputMgr, ico_device_bind) == NULL) { + uifw_trace("ico_input_mgr: wl_global_create ictl failed"); return -1; } /* interface to App(exinput) */ - if (wl_display_add_global(ec->wl_display, &ico_exinput_interface, - pInputMgr, ico_exinput_bind) == NULL) { - uifw_trace("ico_input_mgr: wl_display_add_global exseat failed"); + if (wl_global_create(ec->wl_display, &ico_exinput_interface, 1, + pInputMgr, ico_exinput_bind) == NULL) { + uifw_trace("ico_input_mgr: wl_global_create exseat failed"); return -1; } @@ -963,7 +961,7 @@ module_init(struct weston_compositor *ec) wl_list_init(&pInputMgr->ictl_list); wl_list_init(&pInputMgr->app_list); - uifw_trace("ico_input_mgr: Leave(module_init)"); + uifw_info("ico_input_mgr: Leave(module_init)"); return 0; } diff --git a/src/ico_input_mgr.h b/src/ico_input_mgr.h new file mode 100644 index 0000000..4961289 --- /dev/null +++ b/src/ico_input_mgr.h @@ -0,0 +1,46 @@ +/* + * Copyright © 2013 TOYOTA MOTOR CORPORATION. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/** + * @brief Multi Input Manager header for Device Input Controller + * + * @date Jul-26-2013 + */ + +#ifndef _ICO_INPUT_MGR_H_ +#define _ICO_INPUT_MGR_H_ + +/* Input Region struct for Haptic Device Controller */ +struct ico_uifw_input_region { + uint16_t node; /* display node */ + uint16_t res; /* (unused) */ + uint32_t surfaceid; /* surface Id */ + uint16_t surface_x; /* surface absolute X coordinate */ + uint16_t surface_y; /* surface absolute Y coordinate */ + uint16_t x; /* input region relative X coordinate */ + uint16_t y; /* input region relative Y coordinate */ + uint16_t width; /* input region width */ + uint16_t height; /* input region height */ + int32_t attr; /* input region attribute */ +}; + +#endif /*_ICO_INPUT_MGR_H_*/ + diff --git a/src/ico_ivi_common.c b/src/ico_ivi_common.c deleted file mode 100644 index 9f12614..0000000 --- a/src/ico_ivi_common.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright © 2010-2011 Intel Corporation - * Copyright © 2008-2011 Kristian Høgsberg - * Copyright © 2013 TOYOTA MOTOR CORPORATION. - * - * Permission to use, copy, modify, distribute, and sell this software and - * its documentation for any purpose is hereby granted without fee, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of the copyright holders not be used in - * advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. The copyright holders make - * no representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF - * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/** - * @brief Weston(Wayland) Plugin: IVI Common Functions. - * - * @date Feb-08-2013 - */ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include - -#include -#include "ico_ivi_common.h" - -/* IVI Plugin Common Table */ -struct ico_ivi_common { - int32_t myNodeId; /* (HostId << 16) | DisplayNo */ - int (*usurf_2_node)(const int surfaceid); - /* Function address of nodeId from surfaceId*/ - int (*send_to_mgr)(const int event, const int surfaceid, const char *appid, - const int param1, const int param2, const int param3, - const int param4, const int param5, const int param6); - /* Function address of send to manager */ - int (*send_surface_change)(struct weston_surface *surface, - const int x, const int y, const int width, const int height); - /* Function address of send configure to manager*/ -}; - -/* This function is called from the ico_plugin-loader and initializes this module.*/ -int module_init(struct weston_compositor *ec); - -/* Static area for control ico_ivi_common */ -static struct ico_ivi_common *_ico_ivi_common = NULL; - -/* Special options */ -static int _ico_option_flag = 0; - -/* Debug level */ -static int _ico_ivi_debug = 3; - -static const struct config_key debug_config_keys[] = { - { "option_flag", CONFIG_KEY_INTEGER, &_ico_option_flag }, - { "ivi_debug", CONFIG_KEY_INTEGER, &_ico_ivi_debug }, - }; - -static const struct config_section conf_debug[] = { - { "debug", debug_config_keys, ARRAY_LENGTH(debug_config_keys) }, - }; - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_special_option: Answer special option flag - * - * @param None - * @return Special option flag - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT int -ico_option_flag(void) -{ - return _ico_option_flag; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_ivi_debuglevel: Answer debug output level. - * - * @param None - * @return Debug output level - * @retval 0 No debug output - * @retval 1 Only error output - * @retval 2 Error and information output - * @retval 3 All output with debug write - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT int -ico_ivi_debuglevel(void) -{ - return _ico_ivi_debug; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_ivi_get_mynode: Get my NodeId - * - * @param None - * @return NodeId of my node - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT int -ico_ivi_get_mynode(void) -{ - /* Reference Platform 0.50 only support 1 ECU */ - return 0; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_ivi_set_usurf_2_node: Regist function of convert surfaceId to NodeId - * - * @param[in] usurf_2_node Function address of usurf_2_node - * @return None - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ico_ivi_set_usurf_2_node(int (*usurf_2_node)(const int surfaceid)) -{ - _ico_ivi_common->usurf_2_node = usurf_2_node; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_ivi_usurf_2_node: Convert surfaceId to NodeId - * - * @param[in] surfaceid ivi-shell surfaceId - * @return NodeId - * @retval >= 0 NodeId - * @retval < 0 Surface dose not exist - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT int -ico_ivi_usurf_2_node(const int surfaceid) -{ - int nodeId; - - if (_ico_ivi_common->usurf_2_node) { - /* If declared convert function, call function */ - nodeId = (*_ico_ivi_common->usurf_2_node) (surfaceid); - if (nodeId >= 0) { - return nodeId; - } - } - - /* If NOT declare convert function, convert from surfaceId */ - return ICO_IVI_SURFACEID_2_NODEID(surfaceid); -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_ivi_set_send_to_mgr: Regist function of send to manager - * - * @param[in] send_to_mgr Function address of send to manager - * @return None - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ico_ivi_set_send_to_mgr(int (*send_to_mgr)(const int event, - const int surfaceid, const char *appid, - const int param1, const int param2, const int param3, - const int param4, const int param5, const int param6)) -{ - _ico_ivi_common->send_to_mgr = send_to_mgr; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_ivi_send_to_mgr: Send event to manager - * - * @param[in] event Event code - * @param[in] client_resource Client resource - * @param[in] surfaceid SurfaceId (depend of event code) - * @param[in] appid ApplicationId (depend of event code) - * @param[in] param1 Parameter.1 (depend of event code) - * @param[in] param2 Parameter.2 (depend of event code) - * @param[in] : - * @param[in] param6 Parameter.6 (depend of event code) - * @return number of managers - * @retval > 0 number of managers - * @retval 0 manager not exist - * @retval -1 Multi Input Manager not exist - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT int -ico_ivi_send_to_mgr(const int event, struct wl_resource *client_resource, - const int surfaceid, const char *appid, - const int param1, const int param2, const int param3, - const int param4, const int param5, const int param6) -{ - if (_ico_ivi_common->send_to_mgr) { - return (*_ico_ivi_common->send_to_mgr)(event, surfaceid, appid, - param1, param2, param3, - param4, param5, param6); - } - return -1; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_ivi_set_send_surface_change: Regist function of surface change - * - * @param[in] send_surface_change Function address of surface change - * @return None - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ico_ivi_set_send_surface_change(int (*send_surface_change)(struct weston_surface *surface, - const int x, const int y, - const int width, - const int height)) -{ - _ico_ivi_common->send_surface_change = send_surface_change; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_ivi_send_surface_change: Send surface change event to manager - * - * @param[in] surface Weston surface - * @return number of managers - * @retval > 0 number of managers - * @retval 0 manager not exist - * @retval -1 Multi Input Manager not exist - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT int -ico_ivi_send_surface_change(struct weston_surface *surface, - const int x, const int y, const int width, const int height) -{ - if (_ico_ivi_common->send_surface_change) { - return (*_ico_ivi_common->send_surface_change)(surface, x, y, width, height); - } - return -1; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_ivi_nodename_2_node: Convert node name to hostId - * - * @param[in] nodename Node name(same as host name) - * @return HostId - * @retval >= 0 HostId - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT int -ico_ivi_nodename_2_node(const char *nodename) -{ - if (nodename == NULL) { - uifw_trace("ico_ivi_nodename_2_node: NULL => %d", - ICO_IVI_NODEID_2_HOSTID(_ico_ivi_common->myNodeId)); - return ICO_IVI_NODEID_2_HOSTID(_ico_ivi_common->myNodeId); - } - - /* Reference Platform 0.50 only support 1 ECU */ - uifw_trace("ico_ivi_nodename_2_node: %s => None", nodename ); - return 0; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_ivi_dispname_2_node: Convert display name to nodeId - * - * @param[in] dispname Node name(same as display name) - * @return NodeId - * @retval >= 0 NodeId - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT int -ico_ivi_dispname_2_node(const char *dispname) -{ - if (dispname == NULL) { - uifw_trace("ico_ivi_dispname_2_node: NULL => %x", _ico_ivi_common->myNodeId); - return _ico_ivi_common->myNodeId; - } - - /* Reference Platform 0.50 only support 1 ECU */ - uifw_trace("ico_ivi_dispname_2_node: %s => None", dispname); - return 0; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief IVI Common: Initialize function of ico_ivi_common. - * - * @param[in] ec Weston compositor. (from Weston) - * @return result - * @retval 0 Normal end - * @retval -1 Error - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT int -module_init(struct weston_compositor *ec) -{ - int config_fd; - - uifw_info("ico_ivi_common: Enter(module_init)"); - - /* Get debug level from config file */ - config_fd = open_config_file(ICO_IVI_PLUGIN_CONFIG); - parse_config_file(config_fd, conf_debug, ARRAY_LENGTH(conf_debug), NULL); - close(config_fd); - - uifw_info("ico_ivi_common: option flag=0x%08x debug=%d", - ico_option_flag(), ico_ivi_debuglevel()); - - /* Allocate static area */ - _ico_ivi_common = (struct ico_ivi_common *) malloc(sizeof(struct ico_ivi_common)); - if (! _ico_ivi_common) { - uifw_error("ico_ivi_common: Leave(No Memory)"); - return -1; - } - memset(_ico_ivi_common, 0, sizeof(struct ico_ivi_common)); - - uifw_info("ico_ivi_common: Leave(module_init)"); - - return 0; -} - diff --git a/src/ico_ivi_common.h b/src/ico_ivi_common.h index 58c4193..a277027 100644 --- a/src/ico_ivi_common.h +++ b/src/ico_ivi_common.h @@ -24,43 +24,32 @@ /** * @brief The common functions that each Plugin is available. * - * @date Feb-08-2013 + * @date Jul-26-2013 */ #ifndef _ICO_IVI_COMMON_H_ #define _ICO_IVI_COMMON_H_ /* Macros */ -#define ICO_IVI_NODEID_2_HOSTID( nodeid ) (((unsigned int)nodeid) >> 16) -#define ICO_IVI_NODEID_2_DISPLAYNO( nodeid ) (((unsigned int)nodeid) & 0x0ffff) -#define ICO_IVI_NODEDISP_2_NODEID( nodeid, displayno ) \ - ((nodeid << 16) | displayno) -#define ICO_IVI_SURFACEID_2_HOSTID( surfid ) (((unsigned int)surfid) >> 24) -#define ICO_IVI_SURFACEID_2_DISPLAYNO( surfid ) ((((unsigned int)surfid) >> 16) & 0x0ff) -#define ICO_IVI_SURFACEID_2_NODEID( surfid ) \ - ICO_IVI_NODEDISP_2_NODEID( ICO_IVI_SURFACEID_2_HOSTID(surfid), \ - ICO_IVI_SURFACEID_2_DISPLAYNO(surfid) ) -#define ICO_IVI_SURFACEID_BASE( nodeid ) \ - (ICO_IVI_NODEID_2_HOSTID(nodeid) << 24) | \ - (ICO_IVI_NODEID_2_DISPLAYNO(nodeid) << 16) - -/* Return value */ -#define ICO_IVI_EOK 0 /* OK */ -#define ICO_IVI_ENOENT -2 /* No such object */ -#define ICO_IVI_EIO -5 /* Send error */ -#define ICO_IVI_ENOMEM -12 /* Out of memory */ -#define ICO_IVI_EBUSY -16 /* Not available now */ -#define ICO_IVI_EINVAL -22 /* Invalid argument */ - -/* Configuration file */ -#define ICO_IVI_PLUGIN_CONFIG "weston_ivi_plugin.ini" +#define ICO_IVI_NODEID_2_HOSTID(nodeid) (((unsigned int)nodeid) >> 8) +#define ICO_IVI_NODEID_2_DISPLAYNO(nodeid) (((unsigned int)nodeid) & 0x0ff) +#define ICO_IVI_NODEDISP_2_NODEID(nodeid, displayno) \ + ((nodeid << 8) | displayno) +#define ICO_IVI_SURFACEID_2_HOSTID(surfid) (((unsigned int)surfid) >> 24) +#define ICO_IVI_SURFACEID_2_DISPLAYNO(surfid) ((((unsigned int)surfid) >> 16) & 0x0ff) +#define ICO_IVI_SURFACEID_2_NODEID(surfid) (((unsigned int)surfid) >> 16) +#define ICO_IVI_SURFACEID_BASE(nodeid) (((unsigned int)nodeid) << 16) /* System limit */ -#define ICO_IVI_APPID_LENGTH (128) /* Maximum length of applicationId(AppCore) */ +#define ICO_IVI_MAX_DISPLAY (8) /* Maximum display number of one ECU */ +#define ICO_IVI_APPID_LENGTH (128) /* Maximum length of applicationId(AppCore) */ /* (with terminate NULL) */ -#define ICO_IVI_MAX_COORDINATE (16383) /* Maximum X or Y coordinate */ +#define ICO_IVI_WINNAME_LENGTH (32) /* Maximum length of window name (with NULL)*/ +#define ICO_IVI_ANIMATION_LENGTH (16) /* Maximum length of animation name (w NULL)*/ +#define ICO_IVI_MAX_COORDINATE (16383) /* Maximum X or Y coordinate */ + /* Fixed value */ -#define ICO_IVI_DEFAULT_LAYER (0) /* Default layerId for surface creation */ +#define ICO_IVI_DEFAULT_LAYER (0) /* Default layerId for surface creation */ #ifndef TRUE #define TRUE 1 #endif @@ -68,36 +57,17 @@ #define FALSE 0 #endif -/* Function prototype */ - /* Get my node numner */ -int ico_ivi_get_mynode(void); - /* Convert host name to ECU number */ -int ico_ivi_nodename_2_node(const char *nodename); - /* Convert display name to nodeId */ -int ico_ivi_dispname_2_node(const char *dispname); - /* Regist function of display to nodeId convert*/ -void ico_ivi_set_usurf_2_node(int (*usurf_2_node)(const int surfaceid)); - /* Convery surfaceId to nodeId */ -int ico_ivi_usurf_2_node(const int surfaceid); - /* Regist function of send event to manager */ -void ico_ivi_set_send_to_mgr(int (*send_to_mgr)(const int event, - const int surfaceid, const char *appid, - const int param1, const int param2, const int param3, - const int param4, const int param5, const int param6)); - /* Send event to manager */ -int ico_ivi_send_to_mgr(const int event, struct wl_resource *client_resource, - const int surfaceid, const char *appid, - const int param1, const int param2, const int param3, - const int param4, const int param5, const int param6); - -void ico_ivi_set_send_surface_change(int (*send_surface_change)( - struct weston_surface *surface, - const int x, const int y, const int width, const int height)); -int ico_ivi_send_surface_change(struct weston_surface *surface, - const int x, const int y, const int width, const int height); +/* Debug flags */ +#define ICO_IVI_DEBUG_SHOW_SURFACE 0x01 /* new surface show on create */ -int ico_option_flag(void); -int ico_ivi_debuglevel(void); +/* Function prototype */ +int ico_ivi_get_mynode(void); /* Get my node numner */ +int ico_ivi_debugflag(void); /* Get debug flag */ +int ico_ivi_debuglevel(void); /* Get debug level */ + /* Get default animation name */ +const char *ico_ivi_default_animation_name(void); +int ico_ivi_default_animation_time(void); /* Get default animation time(ms) */ +int ico_ivi_default_animation_fps(void); /* Get animation frame rate(fps) */ /* Debug Traces */ /* Define for debug write */ diff --git a/src/ico_ivi_shell.c b/src/ico_ivi_shell.c index 64d7a0f..de92b62 100644 --- a/src/ico_ivi_shell.c +++ b/src/ico_ivi_shell.c @@ -1,6 +1,6 @@ /* - * Copyright © 2010-2011 Intel Corporation - * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2010-2012 Intel Corporation + * Copyright © 2011-2012 Collabora, Ltd. * Copyright © 2013 TOYOTA MOTOR CORPORATION. * * Permission to use, copy, modify, distribute, and sell this software and @@ -21,12 +21,6 @@ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/** - * @brief Weston(Wayland) IVI Shell - * @brief Shell for IVI(In-Vehicle Infotainment). - * - * @date Feb-08-2013 - */ #include #include @@ -38,82 +32,170 @@ #include #include #include -#include -#include #include #include -#include "ico_ivi_common.h" +#include "desktop-shell-server-protocol.h" +#include "input-method-server-protocol.h" +#include "workspaces-server-protocol.h" +#include #include "ico_ivi_shell.h" -#include "ico_ivi_shell-server-protocol.h" - -/* Layer management */ -struct ivi_layer_list { - int layer; /* Layer.ID */ - int visible; - struct wl_list surface_list; /* Surfacae list */ - struct wl_list link; /* Link pointer for layer list */ + +#define DEFAULT_NUM_WORKSPACES 1 +#define DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH 200 + +enum animation_type { + ANIMATION_NONE, + + ANIMATION_ZOOM, + ANIMATION_FADE +}; + +enum fade_type { + FADE_IN, + FADE_OUT +}; + +struct focus_state { + struct weston_seat *seat; + struct workspace *ws; + struct weston_surface *keyboard_focus; + struct wl_list link; + struct wl_listener seat_destroy_listener; + struct wl_listener surface_destroy_listener; +}; + +struct workspace { + struct weston_layer layer; + + struct wl_list focus_list; + struct wl_listener seat_destroyed_listener; }; -/* Static table for Shell */ -struct shell_surface; -struct ivi_shell { +struct input_panel_surface { + struct wl_resource *resource; + struct wl_signal destroy_signal; + + struct desktop_shell *shell; + + struct wl_list link; + struct weston_surface *surface; + struct wl_listener surface_destroy_listener; + + struct weston_output *output; + uint32_t panel; +}; + +struct desktop_shell { struct weston_compositor *compositor; + + struct wl_listener idle_listener; + struct wl_listener wake_listener; struct wl_listener destroy_listener; - struct weston_layer surface; /* Surface list */ - struct ivi_layer_list ivi_layer; /* Layer list */ - char win_animation[ICO_WINDOW_ANIMATION_LEN]; - /* Default animation name */ - int win_animation_time; /* animation time(ms) */ - int win_animation_fps; /* animation frame rate(fps) */ - int win_visible_on_create; /* Visible on create surface */ - struct shell_surface *active_pointer_shsurf; - /* Pointer active shell surface */ - struct shell_surface *active_keyboard_shsurf; - /* Keyboard active shell surface*/ + struct wl_listener show_input_panel_listener; + struct wl_listener hide_input_panel_listener; + struct wl_listener update_input_panel_listener; + + struct weston_layer fullscreen_layer; + struct weston_layer panel_layer; + struct weston_layer background_layer; + struct weston_layer lock_layer; + struct weston_layer input_panel_layer; + + struct wl_listener pointer_focus_listener; + struct weston_surface *grab_surface; + + struct { + struct weston_process process; + struct wl_client *client; + struct wl_resource *desktop_shell; + + unsigned deathcount; + uint32_t deathstamp; + } child; + + bool locked; + bool showing_input_panels; + bool prepare_event_sent; + + struct { + struct weston_surface *surface; + pixman_box32_t cursor_rectangle; + } text_input; + + struct weston_surface *lock_surface; + struct wl_listener lock_surface_listener; + + struct { + struct wl_array array; + unsigned int current; + unsigned int num; + + struct wl_list client_list; + + struct weston_animation animation; + struct wl_list anim_sticky_list; + int anim_dir; + uint32_t anim_timestamp; + double anim_current; + struct workspace *anim_from; + struct workspace *anim_to; + } workspaces; + + struct { + char *path; + int duration; + struct wl_resource *binding; + struct weston_process process; + struct wl_event_source *timer; + } screensaver; + + struct { + struct wl_resource *binding; + struct wl_list surfaces; + } input_panel; + + struct { + struct weston_surface *surface; + struct weston_surface_animation *animation; + enum fade_type type; + struct wl_event_source *startup_timer; + } fade; + + uint32_t binding_modifier; + enum animation_type win_animation_type; }; -/* Surface type */ enum shell_surface_type { - SHELL_SURFACE_NONE, /* Surface type undefine */ - SHELL_SURFACE_TOPLEVEL, /* Top level surface for application */ - SHELL_SURFACE_TRANSIENT, /* Child surface */ - SHELL_SURFACE_FULLSCREEN, /* Full screen surface */ - SHELL_SURFACE_MAXIMIZED, /* maximum screen */ - SHELL_SURFACE_POPUP /* pop up screen */ + SHELL_SURFACE_NONE, + SHELL_SURFACE_TOPLEVEL, + SHELL_SURFACE_TRANSIENT, + SHELL_SURFACE_FULLSCREEN, + SHELL_SURFACE_MAXIMIZED, + SHELL_SURFACE_POPUP, + SHELL_SURFACE_XWAYLAND +}; + +struct ping_timer { + struct wl_event_source *source; + uint32_t serial; }; -/* Shell surface table */ struct shell_surface { - struct wl_resource resource; + struct wl_resource *resource; + struct wl_signal destroy_signal; struct weston_surface *surface; struct wl_listener surface_destroy_listener; struct weston_surface *parent; - struct ivi_shell *shell; - - enum shell_surface_type type; - enum shell_surface_type next_type; - char *title; - char *class; - - int geometry_x; - int geometry_y; - int geometry_width; - int geometry_height; - char visible; - char mapped; - char noconfigure; - char restrain; - struct ivi_layer_list *layer_list; - struct wl_list ivi_layer; + struct desktop_shell *shell; - struct { - unsigned short x; - unsigned short y; - unsigned short width; - unsigned short height; - } configure_app; + enum shell_surface_type type, next_type; + char *title, *class; + int32_t saved_x, saved_y; + bool saved_position_valid; + bool saved_rotation_valid; + int unresponsive; struct { struct weston_transform transform; @@ -121,28 +203,105 @@ struct shell_surface { } rotation; struct { - int32_t x; - int32_t y; + struct wl_list grab_link; + int32_t x, y; + struct shell_seat *shseat; + uint32_t serial; + } popup; + + struct { + int32_t x, y; uint32_t flags; } transient; + struct { + enum wl_shell_surface_fullscreen_method type; + struct weston_transform transform; /* matrix from x, y */ + uint32_t framerate; + struct weston_surface *black_surface; + } fullscreen; + + struct ping_timer *ping_timer; + + struct weston_transform workspace_transform; + + struct weston_output *fullscreen_output; + struct weston_output *output; struct wl_list link; - struct wl_client *wclient; + const struct weston_shell_client *client; }; -static struct ivi_shell *default_shell = NULL; +struct shell_grab { + struct weston_pointer_grab grab; + struct shell_surface *shsurf; + struct wl_listener shsurf_destroy_listener; + struct weston_pointer *pointer; +}; + +struct weston_move_grab { + struct shell_grab base; + wl_fixed_t dx, dy; +}; + +struct rotate_grab { + struct shell_grab base; + struct weston_matrix rotation; + struct { + float x; + float y; + } center; +}; + +struct shell_seat { + struct weston_seat *seat; + struct wl_listener seat_destroy_listener; + + struct { + struct weston_pointer_grab grab; + struct wl_list surfaces_list; + struct wl_client *client; + int32_t initial_up; + } popup_grab; +}; + +static void +activate(struct desktop_shell *shell, struct weston_surface *es, + struct weston_seat *seat); + +static struct workspace * +get_current_workspace(struct desktop_shell *shell); + +static struct shell_surface * +get_shell_surface(struct weston_surface *surface); +static struct desktop_shell * +shell_surface_get_shell(struct shell_surface *shsurf); -/* static function prototype */ -static void bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id); -static void unbind_shell(struct wl_resource *resource); -static struct shell_surface *get_shell_surface(struct weston_surface *surface); -static struct ivi_shell *shell_surface_get_shell(struct shell_surface *shsurf); -static void ivi_shell_restack_ivi_layer(struct ivi_shell *shell, - struct shell_surface *shsurf); +static void +surface_rotate(struct shell_surface *surface, struct weston_seat *seat); -static void (*shell_hook_bind)(struct wl_client *client) = NULL; +static void +shell_fade_startup(struct desktop_shell *shell); + +/* shell management table */ +static struct desktop_shell *_ico_ivi_shell = NULL; +/* shell program path for ico-ivi */ +static char *shell_exe = NULL; +static int ico_debug_level = 3; /* Debug Level */ + +/* debug log macros */ +#define uifw_trace(fmt,...) \ + { if (ico_debug_level >= 4) {weston_log("DBG>"fmt" (%s:%d)\n",##__VA_ARGS__,__FILE__,__LINE__);} } +#define uifw_info(fmt,...) \ + { if (ico_debug_level >= 3) {weston_log("INF>"fmt" (%s:%d)\n",##__VA_ARGS__,__FILE__,__LINE__);} } +#define uifw_warn(fmt,...) \ + { if (ico_debug_level >= 2) {weston_log("WRN>"fmt" (%s:%d)\n",##__VA_ARGS__,__FILE__,__LINE__);} } +#define uifw_error(fmt,...) \ + { if (ico_debug_level >= 1) {weston_log("ERR>"fmt" (%s:%d)\n",##__VA_ARGS__,__FILE__,__LINE__);} } + +/* hook functions */ +static void (*shell_hook_bind)(struct wl_client *client, void *shell) = NULL; static void (*shell_hook_unbind)(struct wl_client *client) = NULL; static void (*shell_hook_create)(struct wl_client *client, struct wl_resource *resource, struct weston_surface *surface, @@ -153,1986 +312,4583 @@ static void (*shell_hook_map)(struct weston_surface *surface, int32_t *width, static void (*shell_hook_change)(struct weston_surface *surface, const int to, const int manager) = NULL; static void (*shell_hook_select)(struct weston_surface *surface) = NULL; +static void (*shell_hook_title)(struct weston_surface *surface, const char *title) = NULL; +static void (*shell_hook_move)(struct weston_surface *surface, int *dx, int *dy) = NULL; - -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_configuration: initiale configuration ico_ivi_shell - * - * @param[in] shell ico_ivi_shell static table area - * @return none - */ -/*--------------------------------------------------------------------------*/ -static void -shell_configuration(struct ivi_shell *shell) +static bool +shell_surface_is_top_fullscreen(struct shell_surface *shsurf) { - int config_fd; - char *win_animation = NULL; - int win_animation_time = 800; - int win_animation_fps = 15; - - struct config_key shell_keys[] = { - { "animation", CONFIG_KEY_STRING, &win_animation }, - { "animation_time", CONFIG_KEY_INTEGER, &win_animation_time }, - { "animation_fps", CONFIG_KEY_INTEGER, &win_animation_fps }, - { "visible_on_create", CONFIG_KEY_INTEGER, &shell->win_visible_on_create }, - }; + struct desktop_shell *shell; + struct weston_surface *top_fs_es; - struct config_section cs[] = { - { "shell", shell_keys, ARRAY_LENGTH(shell_keys), NULL }, - }; + shell = shell_surface_get_shell(shsurf); - config_fd = open_config_file(ICO_IVI_PLUGIN_CONFIG); - parse_config_file(config_fd, cs, ARRAY_LENGTH(cs), shell); - close(config_fd); + if (wl_list_empty(&shell->fullscreen_layer.surface_list)) + return false; - if (win_animation) { - strncpy(shell->win_animation, win_animation, sizeof(shell->win_animation)-1); - } - if (win_animation_time < 100) win_animation_time = 100; - shell->win_animation_time = win_animation_time; - if (win_animation_fps > 30) win_animation_fps = 30; - if (win_animation_fps < 5) win_animation_fps = 5; - shell->win_animation_fps = win_animation_fps; - uifw_info("shell_configuration: Anima=%s,%dms,%dfps Visible=%d Debug=%d", - shell->win_animation, shell->win_animation_time, shell->win_animation_fps, - shell->win_visible_on_create, ico_ivi_debuglevel()); + top_fs_es = container_of(shell->fullscreen_layer.surface_list.next, + struct weston_surface, + layer_link); + return (shsurf == get_shell_surface(top_fs_es)); } -/*--------------------------------------------------------------------------*/ -/** - * @brief send_configure: send configure(resize) event to client applicstion - * - * @param[in] surface weston surface - * @param[in] edges surface resize position - * @param[in] width surface width - * @param[in] height surface height - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -send_configure(struct weston_surface *surface, - uint32_t edges, int32_t width, int32_t height) +destroy_shell_grab_shsurf(struct wl_listener *listener, void *data) { - struct shell_surface *shsurf = get_shell_surface(surface); + struct shell_grab *grab; - uifw_trace("send_configure: %08x edges=%x w/h=%d/%d map=%d", - (int)shsurf->surface, edges, width, height, shsurf->mapped); - if (shsurf->mapped == 0) return; + grab = container_of(listener, struct shell_grab, + shsurf_destroy_listener); - shsurf->configure_app.width = width; - shsurf->configure_app.height = height; - wl_shell_surface_send_configure(&shsurf->resource, - edges, width, height); + grab->shsurf = NULL; } -static const struct weston_shell_client shell_client = { - send_configure -}; +static void +popup_grab_end(struct weston_pointer *pointer); -/*--------------------------------------------------------------------------*/ -/** - * @brief reset_shell_surface_type: reset surface type - * - * @param[in] shsurf shell surface - * @return always 0 - */ -/*--------------------------------------------------------------------------*/ -static int -reset_shell_surface_type(struct shell_surface *shsurf) +static void +shell_grab_start(struct shell_grab *grab, + const struct weston_pointer_grab_interface *interface, + struct shell_surface *shsurf, + struct weston_pointer *pointer, + enum desktop_shell_cursor cursor) { - uifw_trace("reset_shell_surface_type: [%08x]", (int)shsurf); - shsurf->type = SHELL_SURFACE_NONE; - return 0; + struct desktop_shell *shell = shsurf->shell; + + popup_grab_end(pointer); + + grab->grab.interface = interface; + grab->shsurf = shsurf; + grab->shsurf_destroy_listener.notify = destroy_shell_grab_shsurf; + wl_signal_add(&shsurf->destroy_signal, + &grab->shsurf_destroy_listener); + + grab->pointer = pointer; + + weston_pointer_start_grab(pointer, &grab->grab); + if (shell->child.desktop_shell) { + desktop_shell_send_grab_cursor(shell->child.desktop_shell, + cursor); + weston_pointer_set_focus(pointer, shell->grab_surface, + wl_fixed_from_int(0), + wl_fixed_from_int(0)); + } } -/*--------------------------------------------------------------------------*/ -/** - * @brief set_surface_type: set surface type - * - * @param[in] shsurf shell surface - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -set_surface_type(struct shell_surface *shsurf) +shell_grab_end(struct shell_grab *grab) { - struct weston_surface *surface = shsurf->surface; - struct weston_surface *pes = shsurf->parent; - struct shell_surface *psh; + if (grab->shsurf) + wl_list_remove(&grab->shsurf_destroy_listener.link); + + weston_pointer_end_grab(grab->pointer); +} - uifw_trace("set_surface_type: [%08x] (%08x) type=%x", - (int)shsurf, (int)surface, (int)shsurf->next_type); +static void +center_on_output(struct weston_surface *surface, + struct weston_output *output); - reset_shell_surface_type(shsurf); +static enum weston_keyboard_modifier +get_modifier(char *modifier) +{ + if (!modifier) + return MODIFIER_SUPER; + + if (!strcmp("ctrl", modifier)) + return MODIFIER_CTRL; + else if (!strcmp("alt", modifier)) + return MODIFIER_ALT; + else if (!strcmp("super", modifier)) + return MODIFIER_SUPER; + else + return MODIFIER_SUPER; +} - shsurf->type = shsurf->next_type; - shsurf->next_type = SHELL_SURFACE_NONE; +static enum animation_type +get_animation_type(char *animation) +{ + if (!animation) + return ANIMATION_NONE; - switch (shsurf->type) { - case SHELL_SURFACE_TOPLEVEL: - break; - case SHELL_SURFACE_TRANSIENT: - psh = get_shell_surface(pes); - if (psh) { - shsurf->geometry_x = psh->geometry_x + shsurf->transient.x; - shsurf->geometry_y = psh->geometry_y + shsurf->transient.y; - } - else { - shsurf->geometry_x = pes->geometry.x + shsurf->transient.x; - shsurf->geometry_y = pes->geometry.y + shsurf->transient.y; - } - break; - default: - break; - } + if (!strcmp("zoom", animation)) + return ANIMATION_ZOOM; + else if (!strcmp("fade", animation)) + return ANIMATION_FADE; + else + return ANIMATION_NONE; } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_pong: recceive pong(ping reply) (NOP) - * - * @param[in] client wayland client - * @param[in] resource pong resource - * @param[in] serial event serial number - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_surface_pong(struct wl_client *client, struct wl_resource *resource, uint32_t serial) +shell_configuration(struct desktop_shell *shell) { - uifw_trace("shell_surface_pong: NOP[%08x]", (int)resource->data); + struct weston_config_section *section; + int duration; + char *s; + + section = weston_config_get_section(shell->compositor->config, + "screensaver", NULL, NULL); + weston_config_section_get_string(section, + "path", &shell->screensaver.path, NULL); + weston_config_section_get_int(section, "duration", &duration, 60); + shell->screensaver.duration = duration * 1000; + + section = weston_config_get_section(shell->compositor->config, + "shell", NULL, NULL); + weston_config_section_get_string(section, + "binding-modifier", &s, "super"); + shell->binding_modifier = get_modifier(s); + free(s); + weston_config_section_get_string(section, "animation", &s, "none"); + shell->win_animation_type = get_animation_type(s); + free(s); + weston_config_section_get_uint(section, "num-workspaces", + &shell->workspaces.num, + DEFAULT_NUM_WORKSPACES); + /* shell program path for ico-ivi */ + weston_config_section_get_string(section, "shell-exe", &shell_exe, + LIBEXECDIR "/weston-desktop-shell"); + weston_log("ws=%d exe=%s\n", shell->workspaces.num, shell_exe); + + /* get debug level for ivi debug */ + section = weston_config_get_section(shell->compositor->config, "ivi-debug", NULL, NULL); + if (section) { + weston_config_section_get_int(section, "log", &ico_debug_level, 3); + } } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_move: recceive move request (NOP) - * - * @param[in] client wayland client - * @param[in] resource move request resource - * @param[in] seat_resource seat resource - * @param[in] serial event serial number - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_surface_move(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *seat_resource, uint32_t serial) +focus_state_destroy(struct focus_state *state) { - uifw_trace("shell_surface_move: [%08x] NOP", (int)resource->data); + wl_list_remove(&state->seat_destroy_listener.link); + wl_list_remove(&state->surface_destroy_listener.link); + free(state); } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_resize: recceive resize request (NOP) - * - * @param[in] client wayland client - * @param[in] resource resize request resource - * @param[in] seat_resource seat resource - * @param[in] serial event serial number - * @param[in] edges resize position - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_surface_resize(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *seat_resource, uint32_t serial, - uint32_t edges) +focus_state_seat_destroy(struct wl_listener *listener, void *data) { - uifw_trace("shell_surface_resize: [%08x] NOP", (int)resource->data); + struct focus_state *state = container_of(listener, + struct focus_state, + seat_destroy_listener); + + wl_list_remove(&state->link); + focus_state_destroy(state); } -/*--------------------------------------------------------------------------*/ -/** - * @brief set_toplevel: set surface to TopLevel - * - * @param[in] shsurf shell surface - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -set_toplevel(struct shell_surface *shsurf) +focus_state_surface_destroy(struct wl_listener *listener, void *data) { - shsurf->next_type = SHELL_SURFACE_TOPLEVEL; + struct focus_state *state = container_of(listener, + struct focus_state, + surface_destroy_listener); + struct desktop_shell *shell; + struct weston_surface *main_surface; + struct weston_surface *surface, *next; + + main_surface = weston_surface_get_main_surface(state->keyboard_focus); + + next = NULL; + wl_list_for_each(surface, &state->ws->layer.surface_list, layer_link) { + if (surface == main_surface) + continue; + + next = surface; + break; + } + + /* if the focus was a sub-surface, activate its main surface */ + if (main_surface != state->keyboard_focus) + next = main_surface; + + if (next) { + shell = state->seat->compositor->shell_interface.shell; + activate(shell, next, state->seat); + } else { + wl_list_remove(&state->link); + focus_state_destroy(state); + } } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_set_toplevel: set surface to TopLevel(client interface) - * - * @param[in] client wayland client - * @param[in] resource set toplevel request resource - * @return none - */ -/*--------------------------------------------------------------------------*/ -static void -shell_surface_set_toplevel(struct wl_client *client, struct wl_resource *resource) +static struct focus_state * +focus_state_create(struct weston_seat *seat, struct workspace *ws) { - struct shell_surface *shsurf = resource->data; + struct focus_state *state; - uifw_trace("shell_surface_set_toplevel: Set TopLevel[%08x] surf=%08x", - (int)shsurf, (int)shsurf->surface); + state = malloc(sizeof *state); + if (state == NULL) + return NULL; - set_toplevel(shsurf); + state->ws = ws; + state->seat = seat; + wl_list_insert(&ws->focus_list, &state->link); + + state->seat_destroy_listener.notify = focus_state_seat_destroy; + state->surface_destroy_listener.notify = focus_state_surface_destroy; + wl_signal_add(&seat->destroy_signal, + &state->seat_destroy_listener); + wl_list_init(&state->surface_destroy_listener.link); + + return state; } -/*--------------------------------------------------------------------------*/ -/** - * @brief set_transient: set surface to child - * - * @param[in] shsurf shell surface - * @param[in] parent parent surface - * @param[in] x relative X position from a parent - * @param[in] y relative Y position from a parent - * @param[in] flags flag(unused) - * @return none - */ -/*--------------------------------------------------------------------------*/ -static void -set_transient(struct shell_surface *shsurf, - struct weston_surface *parent, int x, int y, uint32_t flags) +static struct focus_state * +ensure_focus_state(struct desktop_shell *shell, struct weston_seat *seat) { - /* assign to parents output */ - shsurf->parent = parent; - shsurf->transient.x = x; - shsurf->transient.y = y; - shsurf->transient.flags = flags; - shsurf->next_type = SHELL_SURFACE_TRANSIENT; + struct workspace *ws = get_current_workspace(shell); + struct focus_state *state; + + wl_list_for_each(state, &ws->focus_list, link) + if (state->seat == seat) + break; + + if (&state->link == &ws->focus_list) + state = focus_state_create(seat, ws); + + return state; } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_set_transient: set surface to child(client interface) - * - * @param[in] client wayland client - * @param[in] resource set transient request resource - * @param[in] parent_resource parent surface resource - * @param[in] x relative X position from a parent - * @param[in] y relative Y position from a parent - * @param[in] flags flag(unused) - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_surface_set_transient(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *parent_resource, - int x, int y, uint32_t flags) +restore_focus_state(struct desktop_shell *shell, struct workspace *ws) { - struct shell_surface *shsurf = resource->data; - struct weston_surface *parent = parent_resource->data; + struct focus_state *state, *next; + struct weston_surface *surface; - uifw_trace("shell_surface_set_transient: Set Transient[%08x] surf=%08x", - (int)shsurf, (int)shsurf->surface); - set_transient(shsurf, parent, x, y, flags); + wl_list_for_each_safe(state, next, &ws->focus_list, link) { + surface = state->keyboard_focus; + + weston_keyboard_set_focus(state->seat->keyboard, surface); + } } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_set_fullscreen: set surface to full screen(same as toplevel) - * - * @param[in] client wayland client - * @param[in] resource set fullscreen request resource - * @param[in] method method(unused) - * @param[in] framerate frame rate(unused) - * @param[in] output_resource output resource(unused) - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_surface_set_fullscreen(struct wl_client *client, struct wl_resource *resource, - uint32_t method, uint32_t framerate, - struct wl_resource *output_resource) +replace_focus_state(struct desktop_shell *shell, struct workspace *ws, + struct weston_seat *seat) { - struct shell_surface *shsurf = resource->data; - uifw_trace("shell_surface_set_fullscreen: " - "NOP(same as set_toplevel)[%08x]", (int)shsurf); - shsurf->next_type = SHELL_SURFACE_FULLSCREEN; + struct focus_state *state; + struct weston_surface *surface; + + wl_list_for_each(state, &ws->focus_list, link) { + if (state->seat == seat) { + surface = seat->keyboard->focus; + state->keyboard_focus = surface; + return; + } + } } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_set_popup: set surface to popup(same as toplevel) - * - * @param[in] client wayland client - * @param[in] resource set popup request resource - * @param[in] seat_resource seat resource(unused) - * @param[in] serial event serial number(unused) - * @param[in] parent_resource parent resource(unused) - * @param[in] x relative X position from a parent(unused) - * @param[in] y relative Y position from a parent(unused) - * @param[in] flags flag(unused) - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_surface_set_popup(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *seat_resource, uint32_t serial, - struct wl_resource *parent_resource, - int32_t x, int32_t y, uint32_t flags) +drop_focus_state(struct desktop_shell *shell, struct workspace *ws, + struct weston_surface *surface) { - struct shell_surface *shsurf = resource->data; - uifw_trace("shell_surface_set_popup: NOP(same as set_toplevel)[%08x]", (int)shsurf); - shsurf->next_type = SHELL_SURFACE_POPUP; + struct focus_state *state; + + wl_list_for_each(state, &ws->focus_list, link) + if (state->keyboard_focus == surface) + state->keyboard_focus = NULL; } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_set_maximized: set surface to maximized(same as toplevel) - * - * @param[in] client wayland client - * @param[in] resource set maximized request resource - * @param[in] output_resource output resource(unused) - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_surface_set_maximized(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *output_resource ) +workspace_destroy(struct workspace *ws) { - struct shell_surface *shsurf = resource->data; - uifw_trace("shell_surface_set_maximized: NOP(same as set_toplevel)[%08x]", (int)shsurf); - shsurf->next_type = SHELL_SURFACE_MAXIMIZED; + struct focus_state *state, *next; + + wl_list_for_each_safe(state, next, &ws->focus_list, link) + focus_state_destroy(state); + + free(ws); } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_set_title: set surface title - * - * @param[in] client wayland client - * @param[in] resource set title request resource - * @param[in] title surface title - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_surface_set_title(struct wl_client *client, - struct wl_resource *resource, const char *title) +seat_destroyed(struct wl_listener *listener, void *data) +{ + struct weston_seat *seat = data; + struct focus_state *state, *next; + struct workspace *ws = container_of(listener, + struct workspace, + seat_destroyed_listener); + + wl_list_for_each_safe(state, next, &ws->focus_list, link) + if (state->seat == seat) + wl_list_remove(&state->link); +} + +static struct workspace * +workspace_create(void) { - struct shell_surface *shsurf = resource->data; + struct workspace *ws = malloc(sizeof *ws); + if (ws == NULL) + return NULL; - uifw_trace("shell_surface_set_title: [%08x] %s", (int)shsurf, title); + weston_layer_init(&ws->layer, NULL); - if (shsurf->title) { - free(shsurf->title); - } - shsurf->title = strdup(title); + wl_list_init(&ws->focus_list); + wl_list_init(&ws->seat_destroyed_listener.link); + ws->seat_destroyed_listener.notify = seat_destroyed; + + return ws; } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_set_class: set surface class name - * - * @param[in] client wayland client - * @param[in] resource set class request resource - * @param[in] class surface class name - * @return none - */ -/*--------------------------------------------------------------------------*/ -static void -shell_surface_set_class(struct wl_client *client, - struct wl_resource *resource, const char *class) +static int +workspace_is_empty(struct workspace *ws) { - struct shell_surface *shsurf = resource->data; + return wl_list_empty(&ws->layer.surface_list); +} - uifw_trace("shell_surface_set_class: [%08x] %s", (int)shsurf, class); +static struct workspace * +get_workspace(struct desktop_shell *shell, unsigned int index) +{ + struct workspace **pws = shell->workspaces.array.data; + assert(index < shell->workspaces.num); + pws += index; + return *pws; +} - if (shsurf->class) { - free(shsurf->class); - } - shsurf->class = strdup(class); +static struct workspace * +get_current_workspace(struct desktop_shell *shell) +{ + return get_workspace(shell, shell->workspaces.current); } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_raise: raise surface - * - * @param[in] client wayland client - * @param[in] resource set class request resource - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_surface_raise(struct wl_client *client, struct wl_resource *resource) +activate_workspace(struct desktop_shell *shell, unsigned int index) { - struct shell_surface *shsurf = resource->data; + struct workspace *ws; - uifw_trace("shell_surface_raise: [%08x]", (int)shsurf); + ws = get_workspace(shell, index); + wl_list_insert(&shell->panel_layer.link, &ws->layer.link); - ivi_shell_set_raise(shsurf, 1); + shell->workspaces.current = index; } -static const struct wl_shell_surface_interface shell_surface_implementation = { - shell_surface_pong, - shell_surface_move, - shell_surface_resize, - shell_surface_set_toplevel, - shell_surface_set_transient, - shell_surface_set_fullscreen, - shell_surface_set_popup, - shell_surface_set_maximized, - shell_surface_set_title, - shell_surface_set_class, - shell_surface_raise -}; - -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_get_shell: get ico_ivi_shell static table - * - * @param[in] shsurf shell surface(if NULL, return default) - * @return ico_ivi_shell static table address - */ -/*--------------------------------------------------------------------------*/ -static struct ivi_shell * -shell_surface_get_shell(struct shell_surface *shsurf) +static unsigned int +get_output_height(struct weston_output *output) { - if (shsurf) { - return shsurf->shell; - } - return default_shell; + return abs(output->region.extents.y1 - output->region.extents.y2); } -/*--------------------------------------------------------------------------*/ -/** - * @brief destroy_shell_surface: destroy surface - * - * @param[in] shsurf shell surface - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -destroy_shell_surface(struct shell_surface *shsurf) +surface_translate(struct weston_surface *surface, double d) { - uifw_trace("destroy_shell_surface: Enter[%08x]", (int)shsurf); + struct shell_surface *shsurf = get_shell_surface(surface); + struct weston_transform *transform; - if (shsurf->visible != FALSE) { - shsurf->visible = FALSE; - ivi_shell_restack_ivi_layer(shell_surface_get_shell(shsurf), shsurf); - } + transform = &shsurf->workspace_transform; + if (wl_list_empty(&transform->link)) + wl_list_insert(surface->geometry.transformation_list.prev, + &shsurf->workspace_transform.link); + + weston_matrix_init(&shsurf->workspace_transform.matrix); + weston_matrix_translate(&shsurf->workspace_transform.matrix, + 0.0, d, 0.0); + weston_surface_geometry_dirty(surface); +} + +static void +workspace_translate_out(struct workspace *ws, double fraction) +{ + struct weston_surface *surface; + unsigned int height; + double d; - wl_list_remove(&shsurf->ivi_layer); + wl_list_for_each(surface, &ws->layer.surface_list, layer_link) { + height = get_output_height(surface->output); + d = height * fraction; - if (shell_hook_destroy) { - /* call sufrace destory hook routine */ - uifw_trace("destroy_shell_surface: call ivi_shell_hook_destroy(%08x)", - (int)shsurf->surface); - (void) (*shell_hook_destroy) (shsurf->surface); - uifw_trace("destroy_shell_surface: ret"); + surface_translate(surface, d); } +} - wl_list_remove(&shsurf->surface_destroy_listener.link); - shsurf->surface->configure = NULL; +static void +workspace_translate_in(struct workspace *ws, double fraction) +{ + struct weston_surface *surface; + unsigned int height; + double d; - wl_list_remove(&shsurf->link); - free(shsurf); + wl_list_for_each(surface, &ws->layer.surface_list, layer_link) { + height = get_output_height(surface->output); + + if (fraction > 0) + d = -(height - height * fraction); + else + d = height + height * fraction; - uifw_trace("destroy_shell_surface: Leave"); + surface_translate(surface, d); + } } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_destroy_shell_surface: destroy surface(client interface) - * - * @param[in] resource destroy request resource - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_destroy_shell_surface(struct wl_resource *resource) +broadcast_current_workspace_state(struct desktop_shell *shell) { - struct shell_surface *shsurf = resource->data; + struct wl_list *link; + + for (link = shell->workspaces.client_list.next; + link != &shell->workspaces.client_list; + link = link->next) { + workspace_manager_send_state(wl_resource_from_link(link), + shell->workspaces.current, + shell->workspaces.num); + } +} - uifw_trace("shell_destroy_shell_surface: Enter [%08x]", (int)shsurf); +static void +reverse_workspace_change_animation(struct desktop_shell *shell, + unsigned int index, + struct workspace *from, + struct workspace *to) +{ + shell->workspaces.current = index; - destroy_shell_surface(shsurf); + shell->workspaces.anim_to = to; + shell->workspaces.anim_from = from; + shell->workspaces.anim_dir = -1 * shell->workspaces.anim_dir; + shell->workspaces.anim_timestamp = 0; - uifw_trace("shell_destroy_shell_surface: Leave"); + weston_compositor_schedule_repaint(shell->compositor); } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_handle_surface_destroy: destroy surface(listener interface) - * - * @param[in] listener listener - * @param[in] data user data(unused) - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_handle_surface_destroy(struct wl_listener *listener, void *data) +workspace_deactivate_transforms(struct workspace *ws) { - struct shell_surface *shsurf = container_of(listener, struct shell_surface, - surface_destroy_listener); - - uifw_trace("shell_handle_surface_destroy: Enter [%08x] data=%08x", - (int)shsurf, (int)data); + struct weston_surface *surface; + struct shell_surface *shsurf; - if (shsurf->resource.client) { - wl_resource_destroy(&shsurf->resource); - } else { - wl_signal_emit(&shsurf->resource.destroy_signal, &shsurf->resource); - destroy_shell_surface(shsurf); + wl_list_for_each(surface, &ws->layer.surface_list, layer_link) { + shsurf = get_shell_surface(surface); + if (!wl_list_empty(&shsurf->workspace_transform.link)) { + wl_list_remove(&shsurf->workspace_transform.link); + wl_list_init(&shsurf->workspace_transform.link); + } + weston_surface_geometry_dirty(surface); } - uifw_trace("shell_handle_surface_destroy: Leave"); } static void -shell_surface_configure(struct weston_surface *, int32_t, int32_t); - -/*--------------------------------------------------------------------------*/ -/** - * @brief get_shell_surface: get shell surface - * - * @param[in] surface weston surface - * @return shell surface address - */ -/*--------------------------------------------------------------------------*/ -static struct shell_surface * -get_shell_surface(struct weston_surface *surface) +finish_workspace_change_animation(struct desktop_shell *shell, + struct workspace *from, + struct workspace *to) { - if (surface->configure == shell_surface_configure) - return surface->private; - else - return NULL; + weston_compositor_schedule_repaint(shell->compositor); + + wl_list_remove(&shell->workspaces.animation.link); + workspace_deactivate_transforms(from); + workspace_deactivate_transforms(to); + shell->workspaces.anim_to = NULL; + + wl_list_remove(&shell->workspaces.anim_from->layer.link); } -/*--------------------------------------------------------------------------*/ -/** - * @brief create_shell_surface: create shell surface - * - * @param[in] surface weston surface - * @param[in] client client - * @return created shell surface address - */ -/*--------------------------------------------------------------------------*/ -static struct shell_surface * -create_shell_surface(void *shell, struct weston_surface *surface, - const struct weston_shell_client *client) +static void +animate_workspace_change_frame(struct weston_animation *animation, + struct weston_output *output, uint32_t msecs) { - struct shell_surface *shsurf; + struct desktop_shell *shell = + container_of(animation, struct desktop_shell, + workspaces.animation); + struct workspace *from = shell->workspaces.anim_from; + struct workspace *to = shell->workspaces.anim_to; + uint32_t t; + double x, y; + + if (workspace_is_empty(from) && workspace_is_empty(to)) { + finish_workspace_change_animation(shell, from, to); + return; + } - if (surface->configure) { - uifw_warn("create_shell_surface: surface->configure already set"); - return NULL; + if (shell->workspaces.anim_timestamp == 0) { + if (shell->workspaces.anim_current == 0.0) + shell->workspaces.anim_timestamp = msecs; + else + shell->workspaces.anim_timestamp = + msecs - + /* Invers of movement function 'y' below. */ + (asin(1.0 - shell->workspaces.anim_current) * + DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH * + M_2_PI); } - shsurf = calloc(1, sizeof *shsurf); - if (!shsurf) { - uifw_error("create_shell_surface: no memory to allocate shell surface"); - return NULL; + t = msecs - shell->workspaces.anim_timestamp; + + /* + * x = [0, π/2] + * y(x) = sin(x) + */ + x = t * (1.0/DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH) * M_PI_2; + y = sin(x); + + if (t < DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH) { + weston_compositor_schedule_repaint(shell->compositor); + + workspace_translate_out(from, shell->workspaces.anim_dir * y); + workspace_translate_in(to, shell->workspaces.anim_dir * y); + shell->workspaces.anim_current = y; + + weston_compositor_schedule_repaint(shell->compositor); } + else + finish_workspace_change_animation(shell, from, to); +} - uifw_trace("create_shell_surface: (%08x) [%08x] client=%08x (visible=%d)", - (int)surface, (int)shsurf, (int)client, - ((struct ivi_shell *)shell)->win_visible_on_create); +static void +animate_workspace_change(struct desktop_shell *shell, + unsigned int index, + struct workspace *from, + struct workspace *to) +{ + struct weston_output *output; - surface->configure = shell_surface_configure; - surface->private = shsurf; + int dir; - shsurf->shell = (struct ivi_shell *) shell; - shsurf->surface = surface; - shsurf->visible = shsurf->shell->win_visible_on_create; + if (index > shell->workspaces.current) + dir = -1; + else + dir = 1; - /* set default color and shader */ - weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1); + shell->workspaces.current = index; - wl_signal_init(&shsurf->resource.destroy_signal); - shsurf->surface_destroy_listener.notify = shell_handle_surface_destroy; - wl_signal_add(&surface->surface.resource.destroy_signal, - &shsurf->surface_destroy_listener); + shell->workspaces.anim_dir = dir; + shell->workspaces.anim_from = from; + shell->workspaces.anim_to = to; + shell->workspaces.anim_current = 0.0; + shell->workspaces.anim_timestamp = 0; - /* init link so its safe to always remove it in destroy_shell_surface */ - wl_list_init(&shsurf->link); + output = container_of(shell->compositor->output_list.next, + struct weston_output, link); + wl_list_insert(&output->animation_list, + &shell->workspaces.animation.link); - /* empty when not in use */ - wl_list_init(&shsurf->rotation.transform.link); - weston_matrix_init(&shsurf->rotation.rotation); + wl_list_insert(from->layer.link.prev, &to->layer.link); - shsurf->type = SHELL_SURFACE_NONE; - shsurf->next_type = SHELL_SURFACE_NONE; + workspace_translate_in(to, 0); - shsurf->client = client; + restore_focus_state(shell, to); - wl_list_init(&shsurf->ivi_layer); + weston_compositor_schedule_repaint(shell->compositor); +} - return shsurf; +static void +update_workspace(struct desktop_shell *shell, unsigned int index, + struct workspace *from, struct workspace *to) +{ + shell->workspaces.current = index; + wl_list_insert(&from->layer.link, &to->layer.link); + wl_list_remove(&from->layer.link); } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_get_shell_surface: create shell surface(client interface) - * - * @param[in] client client - * @param[in] resource get shell surface request resource - * @param[in] id created shell surface object id in the client - * @param[in] surface_resource weston surface resource - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_get_shell_surface(struct wl_client *client, struct wl_resource *resource, - uint32_t id, struct wl_resource *surface_resource) +change_workspace(struct desktop_shell *shell, unsigned int index) { - struct weston_surface *surface = surface_resource->data; - struct ivi_shell *shell = resource->data; - struct shell_surface *shsurf; + struct workspace *from; + struct workspace *to; - if (get_shell_surface(surface)) { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "ivi_shell::get_shell_surface already requested"); + if (index == shell->workspaces.current) return; - } - uifw_trace("shell_get_shell_surface: Enter (%08x) client=%08x", - (int)surface, (int)client); + /* Don't change workspace when there is any fullscreen surfaces. */ + if (!wl_list_empty(&shell->fullscreen_layer.surface_list)) + return; - shsurf = create_shell_surface(shell, surface, &shell_client); - if (!shsurf) { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "surface->configure already set"); + from = get_current_workspace(shell); + to = get_workspace(shell, index); + + if (shell->workspaces.anim_from == to && + shell->workspaces.anim_to == from) { + restore_focus_state(shell, to); + reverse_workspace_change_animation(shell, index, from, to); + broadcast_current_workspace_state(shell); return; } - shsurf->wclient = client; - shsurf->resource.destroy = shell_destroy_shell_surface; - shsurf->resource.object.id = id; - shsurf->resource.object.interface = &wl_shell_surface_interface; - shsurf->resource.object.implementation = - (void (**)(void)) &shell_surface_implementation; - shsurf->resource.data = shsurf; + if (shell->workspaces.anim_to != NULL) + finish_workspace_change_animation(shell, + shell->workspaces.anim_from, + shell->workspaces.anim_to); - wl_client_add_resource(client, &shsurf->resource); + restore_focus_state(shell, to); - wl_list_init(&shsurf->ivi_layer); - uifw_trace("shell_get_shell_surface: Init shsurf(%08x) weston_surf=%08x", - (int)shsurf, (int)surface); + if (workspace_is_empty(to) && workspace_is_empty(from)) + update_workspace(shell, index, from, to); + else + animate_workspace_change(shell, index, from, to); - if (shell_hook_create) { - /* call surface create hook routine */ - uifw_trace("shell_get_shell_surface: call ivi_shell_hook_create(%08x,,%08x,%08x)", - (int)client, (int)surface, (int)shsurf); - (void) (*shell_hook_create)(client, resource, surface, shsurf); - uifw_trace("shell_get_shell_surface: ret ivi_shell_hook_create"); - } - uifw_trace("shell_get_shell_surface: Leave"); + broadcast_current_workspace_state(shell); } -static const struct wl_shell_interface shell_implementation = { - shell_get_shell_surface -}; - -/*--------------------------------------------------------------------------*/ -/** - * @brief weston_surface_set_initial_position: set surface initial position - * - * @param[in] surface weston surface - * @param[in] shell ico_ivi_shell static table address - * @return none - */ -/*--------------------------------------------------------------------------*/ -static void -weston_surface_set_initial_position(struct weston_surface *surface, struct ivi_shell *shell) +static bool +workspace_has_only(struct workspace *ws, struct weston_surface *surface) { - struct weston_output *output, *target_output; + struct wl_list *list = &ws->layer.surface_list; + struct wl_list *e; - if (shell->win_visible_on_create) { - wl_list_for_each (output, &shell->compositor->output_list, link) { - target_output = output; - break; - } - if (! target_output) { - weston_surface_set_position(surface, (float)(10 + random() % 400), - (float)(10 + random() % 400)); - } - else { - int range_x = target_output->width - surface->geometry.width; - int range_y = target_output->height - surface->geometry.height; - if (range_x < 0) range_x = 400; - if (range_y < 0) range_y = 400; - weston_surface_set_position(surface, (float)(random() % range_x), - (float)(random() % range_y)); - } - } - else { - weston_surface_set_position(surface, (float)0.0, (float)0.0); - } + if (wl_list_empty(list)) + return false; + + e = list->next; + + if (e->next != list) + return false; + + return container_of(e, struct weston_surface, layer_link) == surface; } -/*--------------------------------------------------------------------------*/ -/** - * @brief map: surface initial mapping to screen - * - * @param[in] shell ico_ivi_shell static table address - * @param[in] surface weston surface - * @param[in] width surface width - * @param[in] height surface height - * @param[in] sx surface upper-left X position on screen - * @param[in] sy surface upper-left Y position on screen - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -map(struct ivi_shell *shell, struct weston_surface *surface, - int32_t width, int32_t height, int32_t sx, int32_t sy) +move_surface_to_workspace(struct desktop_shell *shell, + struct weston_surface *surface, + uint32_t workspace) { - struct shell_surface *shsurf = get_shell_surface(surface); - enum shell_surface_type surface_type = shsurf->type; - struct weston_surface *parent; + struct workspace *from; + struct workspace *to; + struct weston_seat *seat; + struct weston_surface *focus; - uifw_trace("map: Enter(%08x) sx/sy=%d/%d, w/h=%d/%d", - (int)surface, ((int)sx)/256, ((int)sy)/256, width, height); + assert(weston_surface_get_main_surface(surface) == surface); - shsurf->mapped = 1; - surface->geometry.width = width; - surface->geometry.height = height; - shsurf->geometry_x = sx; - shsurf->geometry_y = sy; - shsurf->geometry_width = width; - shsurf->geometry_height = height; - surface->geometry.dirty = 1; + if (workspace == shell->workspaces.current) + return; - /* initial positioning, see also configure() */ - switch (surface_type) { - case SHELL_SURFACE_TOPLEVEL: - weston_surface_set_initial_position(surface, shell); - uifw_trace("map: TopLevel x/y=%d/%d w/h=%d/%d", - (int)surface->geometry.x, (int)surface->geometry.y, - (int)surface->geometry.width, (int)surface->geometry.height); - shsurf->geometry_x = surface->geometry.x; - shsurf->geometry_x = surface->geometry.y; - break; - case SHELL_SURFACE_NONE: - weston_surface_set_position(surface, (float)(surface->geometry.x + sx), - (float)(surface->geometry.y + sy)); - break; - default: - ; - } - if ((ico_option_flag() & ICO_OPTION_FLAG_UNVISIBLE) && (shsurf->visible == FALSE)) { - surface->geometry.x = (float)(ICO_IVI_MAX_COORDINATE+1); - surface->geometry.y = (float)(ICO_IVI_MAX_COORDINATE+1); - surface->geometry.dirty = 1; - } + if (workspace >= shell->workspaces.num) + workspace = shell->workspaces.num - 1; - switch (surface_type) { - case SHELL_SURFACE_TRANSIENT: - parent = shsurf->parent; - wl_list_insert(parent->layer_link.prev, &surface->layer_link); - break; - case SHELL_SURFACE_NONE: - break; - default: - if (! shsurf->layer_list) { - ivi_shell_set_layer(shsurf, ICO_IVI_DEFAULT_LAYER); - } - break; - } + from = get_current_workspace(shell); + to = get_workspace(shell, workspace); - if (surface_type != SHELL_SURFACE_NONE) { - weston_surface_update_transform(surface); - ivi_shell_restack_ivi_layer(shell, shsurf); - } + wl_list_remove(&surface->layer_link); + wl_list_insert(&to->layer.surface_list, &surface->layer_link); - if (shell_hook_map) { - /* Surface map hook routine */ - uifw_trace("map: call ivi_shell_hook_map(%08x, x/y=%d/%d, w/h=%d/%d)", - (int)surface, sx, sy, width, height); - (void) (*shell_hook_map) (surface, &width, &height, &sx, &sy); - uifw_trace("map: ret ivi_shell_hook_map(%08x, x/y=%d/%d, w/h=%d/%d)", - (int)surface, sx, sy, width, height); - } + drop_focus_state(shell, from, surface); + wl_list_for_each(seat, &shell->compositor->seat_list, link) { + if (!seat->keyboard) + continue; - if (shell_hook_change) { - /* Surface change hook routine */ - uifw_trace("map: call ivi_shell_hook_change(%08x)", (int)surface); - (void) (*shell_hook_change)(surface, -1, 1); /* Send to Manager */ - uifw_trace("map: ret ivi_shell_hook_change") + focus = weston_surface_get_main_surface(seat->keyboard->focus); + if (focus == surface) + weston_keyboard_set_focus(seat->keyboard, NULL); } - uifw_trace("map: Leave"); + + weston_surface_damage_below(surface); +} + +static void +take_surface_to_workspace_by_seat(struct desktop_shell *shell, + struct weston_seat *seat, + unsigned int index) +{ + struct weston_surface *surface; + struct shell_surface *shsurf; + struct workspace *from; + struct workspace *to; + struct focus_state *state; + + surface = weston_surface_get_main_surface(seat->keyboard->focus); + if (surface == NULL || + index == shell->workspaces.current) + return; + + from = get_current_workspace(shell); + to = get_workspace(shell, index); + + wl_list_remove(&surface->layer_link); + wl_list_insert(&to->layer.surface_list, &surface->layer_link); + + replace_focus_state(shell, to, seat); + drop_focus_state(shell, from, surface); + + if (shell->workspaces.anim_from == to && + shell->workspaces.anim_to == from) { + wl_list_remove(&to->layer.link); + wl_list_insert(from->layer.link.prev, &to->layer.link); + + reverse_workspace_change_animation(shell, index, from, to); + broadcast_current_workspace_state(shell); + + return; + } + + if (shell->workspaces.anim_to != NULL) + finish_workspace_change_animation(shell, + shell->workspaces.anim_from, + shell->workspaces.anim_to); + + if (workspace_is_empty(from) && + workspace_has_only(to, surface)) + update_workspace(shell, index, from, to); + else { + shsurf = get_shell_surface(surface); + if (wl_list_empty(&shsurf->workspace_transform.link)) + wl_list_insert(&shell->workspaces.anim_sticky_list, + &shsurf->workspace_transform.link); + + animate_workspace_change(shell, index, from, to); + } + + broadcast_current_workspace_state(shell); + + state = ensure_focus_state(shell, seat); + if (state != NULL) + state->keyboard_focus = surface; +} + +static void +workspace_manager_move_surface(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface_resource, + uint32_t workspace) +{ + struct desktop_shell *shell = wl_resource_get_user_data(resource); + struct weston_surface *surface = + wl_resource_get_user_data(surface_resource); + struct weston_surface *main_surface; + + main_surface = weston_surface_get_main_surface(surface); + move_surface_to_workspace(shell, main_surface, workspace); +} + +static const struct workspace_manager_interface workspace_manager_implementation = { + workspace_manager_move_surface, +}; + +static void +unbind_resource(struct wl_resource *resource) +{ + wl_list_remove(wl_resource_get_link(resource)); +} + +static void +bind_workspace_manager(struct wl_client *client, + void *data, uint32_t version, uint32_t id) +{ + struct desktop_shell *shell = data; + struct wl_resource *resource; + + resource = wl_resource_create(client, + &workspace_manager_interface, 1, id); + + if (resource == NULL) { + weston_log("couldn't add workspace manager object"); + return; + } + + wl_resource_set_implementation(resource, + &workspace_manager_implementation, + shell, unbind_resource); + wl_list_insert(&shell->workspaces.client_list, + wl_resource_get_link(resource)); + + workspace_manager_send_state(resource, + shell->workspaces.current, + shell->workspaces.num); +} + +static void +noop_grab_focus(struct weston_pointer_grab *grab) +{ +} + +static void +move_grab_motion(struct weston_pointer_grab *grab, uint32_t time) +{ + struct weston_move_grab *move = (struct weston_move_grab *) grab; + struct weston_pointer *pointer = grab->pointer; + struct shell_surface *shsurf = move->base.shsurf; + struct weston_surface *es; + int dx = wl_fixed_to_int(pointer->x + move->dx); + int dy = wl_fixed_to_int(pointer->y + move->dy); + + if (!shsurf) + return; + + es = shsurf->surface; + + uifw_trace("move_grab_motion: configure %08x x/y=%d/%d w/h=%d/%d", + (int)es, (int)dx, (int)dy, es->geometry.width, es->geometry.height); + + /* ico-ivi-shell hook move */ + if (shell_hook_move) { + (*shell_hook_move)(shsurf->surface, &dx, &dy); + } + weston_surface_configure(es, dx, dy, + es->geometry.width, es->geometry.height); + + weston_compositor_schedule_repaint(es->compositor); +} + +static void +move_grab_button(struct weston_pointer_grab *grab, + uint32_t time, uint32_t button, uint32_t state_w) +{ + struct shell_grab *shell_grab = container_of(grab, struct shell_grab, + grab); + struct weston_pointer *pointer = grab->pointer; + enum wl_pointer_button_state state = state_w; + + if (pointer->button_count == 0 && + state == WL_POINTER_BUTTON_STATE_RELEASED) { + shell_grab_end(shell_grab); + free(grab); + } +} + +static const struct weston_pointer_grab_interface move_grab_interface = { + noop_grab_focus, + move_grab_motion, + move_grab_button, +}; + +static int +surface_move(struct shell_surface *shsurf, struct weston_seat *seat) +{ + struct weston_move_grab *move; + + if (!shsurf) + return -1; + + if (shsurf->type == SHELL_SURFACE_FULLSCREEN) + return 0; + + move = malloc(sizeof *move); + if (!move) + return -1; + + move->dx = wl_fixed_from_double(shsurf->surface->geometry.x) - + seat->pointer->grab_x; + move->dy = wl_fixed_from_double(shsurf->surface->geometry.y) - + seat->pointer->grab_y; + + shell_grab_start(&move->base, &move_grab_interface, shsurf, + seat->pointer, DESKTOP_SHELL_CURSOR_MOVE); + + return 0; +} + +static void +shell_surface_move(struct wl_client *client, struct wl_resource *resource, + struct wl_resource *seat_resource, uint32_t serial) +{ + struct weston_seat *seat = wl_resource_get_user_data(seat_resource); + struct shell_surface *shsurf = wl_resource_get_user_data(resource); + struct weston_surface *surface; + + surface = weston_surface_get_main_surface(seat->pointer->focus); + if (seat->pointer->button_count == 0 || + seat->pointer->grab_serial != serial || + surface != shsurf->surface) + return; + + if (surface_move(shsurf, seat) < 0) + wl_resource_post_no_memory(resource); +} + +struct weston_resize_grab { + struct shell_grab base; + uint32_t edges; + int32_t width, height; +}; + +static void +resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time) +{ + struct weston_resize_grab *resize = (struct weston_resize_grab *) grab; + struct weston_pointer *pointer = grab->pointer; + struct shell_surface *shsurf = resize->base.shsurf; + int32_t width, height; + wl_fixed_t from_x, from_y; + wl_fixed_t to_x, to_y; + + if (!shsurf) + return; + + weston_surface_from_global_fixed(shsurf->surface, + pointer->grab_x, pointer->grab_y, + &from_x, &from_y); + weston_surface_from_global_fixed(shsurf->surface, + pointer->x, pointer->y, &to_x, &to_y); + + width = resize->width; + if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) { + width += wl_fixed_to_int(from_x - to_x); + } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) { + width += wl_fixed_to_int(to_x - from_x); + } + + height = resize->height; + if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) { + height += wl_fixed_to_int(from_y - to_y); + } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) { + height += wl_fixed_to_int(to_y - from_y); + } + + uifw_trace("resize_grab_motion: send configure %08x %x w/h=%d/%d", + (int)shsurf->surface, resize->edges, width, height); + shsurf->client->send_configure(shsurf->surface, + resize->edges, width, height); +} + +static void +send_configure(struct weston_surface *surface, + uint32_t edges, int32_t width, int32_t height) +{ + struct shell_surface *shsurf = get_shell_surface(surface); + + uifw_trace("send_configure: send %08x %x w/h=%d/%d", + (int)shsurf->surface, edges, width, height); + wl_shell_surface_send_configure(shsurf->resource, + edges, width, height); +} + +static const struct weston_shell_client shell_client = { + send_configure +}; + +static void +resize_grab_button(struct weston_pointer_grab *grab, + uint32_t time, uint32_t button, uint32_t state_w) +{ + struct weston_resize_grab *resize = (struct weston_resize_grab *) grab; + struct weston_pointer *pointer = grab->pointer; + enum wl_pointer_button_state state = state_w; + + if (pointer->button_count == 0 && + state == WL_POINTER_BUTTON_STATE_RELEASED) { + shell_grab_end(&resize->base); + free(grab); + } +} + +static const struct weston_pointer_grab_interface resize_grab_interface = { + noop_grab_focus, + resize_grab_motion, + resize_grab_button, +}; + +/* + * Returns the bounding box of a surface and all its sub-surfaces, + * in the surface coordinates system. */ +static void +surface_subsurfaces_boundingbox(struct weston_surface *surface, int32_t *x, + int32_t *y, int32_t *w, int32_t *h) { + pixman_region32_t region; + pixman_box32_t *box; + struct weston_subsurface *subsurface; + + pixman_region32_init_rect(®ion, 0, 0, + surface->geometry.width, + surface->geometry.height); + + wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) { + pixman_region32_union_rect(®ion, ®ion, + subsurface->position.x, + subsurface->position.y, + subsurface->surface->geometry.width, + subsurface->surface->geometry.height); + } + + box = pixman_region32_extents(®ion); + if (x) + *x = box->x1; + if (y) + *y = box->y1; + if (w) + *w = box->x2 - box->x1; + if (h) + *h = box->y2 - box->y1; + + pixman_region32_fini(®ion); +} + +static int +surface_resize(struct shell_surface *shsurf, + struct weston_seat *seat, uint32_t edges) +{ + struct weston_resize_grab *resize; + + if (shsurf->type == SHELL_SURFACE_FULLSCREEN || + shsurf->type == SHELL_SURFACE_MAXIMIZED) + return 0; + + if (edges == 0 || edges > 15 || + (edges & 3) == 3 || (edges & 12) == 12) + return 0; + + resize = malloc(sizeof *resize); + if (!resize) + return -1; + + resize->edges = edges; + surface_subsurfaces_boundingbox(shsurf->surface, NULL, NULL, + &resize->width, &resize->height); + + shell_grab_start(&resize->base, &resize_grab_interface, shsurf, + seat->pointer, edges); + + return 0; +} + +static void +shell_surface_resize(struct wl_client *client, struct wl_resource *resource, + struct wl_resource *seat_resource, uint32_t serial, + uint32_t edges) +{ + struct weston_seat *seat = wl_resource_get_user_data(seat_resource); + struct shell_surface *shsurf = wl_resource_get_user_data(resource); + struct weston_surface *surface; + + if (shsurf->type == SHELL_SURFACE_FULLSCREEN) + return; + + surface = weston_surface_get_main_surface(seat->pointer->focus); + if (seat->pointer->button_count == 0 || + seat->pointer->grab_serial != serial || + surface != shsurf->surface) + return; + + if (surface_resize(shsurf, seat, edges) < 0) + wl_resource_post_no_memory(resource); +} + +static void +end_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer); + +static void +busy_cursor_grab_focus(struct weston_pointer_grab *base) +{ + struct shell_grab *grab = (struct shell_grab *) base; + struct weston_pointer *pointer = base->pointer; + struct weston_surface *surface; + wl_fixed_t sx, sy; + + surface = weston_compositor_pick_surface(pointer->seat->compositor, + pointer->x, pointer->y, + &sx, &sy); + + if (!grab->shsurf || grab->shsurf->surface != surface) + end_busy_cursor(grab->shsurf, pointer); +} + +static void +busy_cursor_grab_motion(struct weston_pointer_grab *grab, uint32_t time) +{ +} + +static void +busy_cursor_grab_button(struct weston_pointer_grab *base, + uint32_t time, uint32_t button, uint32_t state) +{ + struct shell_grab *grab = (struct shell_grab *) base; + struct shell_surface *shsurf = grab->shsurf; + struct weston_seat *seat = grab->grab.pointer->seat; + + if (shsurf && button == BTN_LEFT && state) { + activate(shsurf->shell, shsurf->surface, seat); + surface_move(shsurf, seat); + } else if (shsurf && button == BTN_RIGHT && state) { + activate(shsurf->shell, shsurf->surface, seat); + surface_rotate(shsurf, seat); + } +} + +static const struct weston_pointer_grab_interface busy_cursor_grab_interface = { + busy_cursor_grab_focus, + busy_cursor_grab_motion, + busy_cursor_grab_button, +}; + +static void +set_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer) +{ + struct shell_grab *grab; + + grab = malloc(sizeof *grab); + if (!grab) + return; + + shell_grab_start(grab, &busy_cursor_grab_interface, shsurf, pointer, + DESKTOP_SHELL_CURSOR_BUSY); +} + +static void +end_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer) +{ + struct shell_grab *grab = (struct shell_grab *) pointer->grab; + + if (grab->grab.interface == &busy_cursor_grab_interface && + grab->shsurf == shsurf) { + shell_grab_end(grab); + free(grab); + } +} + +static void +ping_timer_destroy(struct shell_surface *shsurf) +{ + if (!shsurf || !shsurf->ping_timer) + return; + + if (shsurf->ping_timer->source) + wl_event_source_remove(shsurf->ping_timer->source); + + free(shsurf->ping_timer); + shsurf->ping_timer = NULL; +} + +static int +ping_timeout_handler(void *data) +{ + struct shell_surface *shsurf = data; + struct weston_seat *seat; + + /* Client is not responding */ + shsurf->unresponsive = 1; + + wl_list_for_each(seat, &shsurf->surface->compositor->seat_list, link) + if (seat->pointer->focus == shsurf->surface) + set_busy_cursor(shsurf, seat->pointer); + + return 1; +} + +static void +ping_handler(struct weston_surface *surface, uint32_t serial) +{ + struct shell_surface *shsurf = get_shell_surface(surface); + struct wl_event_loop *loop; + int ping_timeout = 200; + + if (!shsurf) + return; + if (!shsurf->resource) + return; + + if (shsurf->surface == shsurf->shell->grab_surface) + return; + + if (!shsurf->ping_timer) { + shsurf->ping_timer = malloc(sizeof *shsurf->ping_timer); + if (!shsurf->ping_timer) + return; + + shsurf->ping_timer->serial = serial; + loop = wl_display_get_event_loop(surface->compositor->wl_display); + shsurf->ping_timer->source = + wl_event_loop_add_timer(loop, ping_timeout_handler, shsurf); + wl_event_source_timer_update(shsurf->ping_timer->source, ping_timeout); + + wl_shell_surface_send_ping(shsurf->resource, serial); + } +} + +static void +handle_pointer_focus(struct wl_listener *listener, void *data) +{ + struct weston_pointer *pointer = data; + struct weston_surface *surface = pointer->focus; + struct weston_compositor *compositor; + struct shell_surface *shsurf; + uint32_t serial; + + if (!surface) + return; + + compositor = surface->compositor; + shsurf = get_shell_surface(surface); + + if (shsurf && shsurf->unresponsive) { + set_busy_cursor(shsurf, pointer); + } else { + serial = wl_display_next_serial(compositor->wl_display); + ping_handler(surface, serial); + } +} + +static void +create_pointer_focus_listener(struct weston_seat *seat) +{ + struct wl_listener *listener; + + if (!seat->pointer) + return; + + listener = malloc(sizeof *listener); + listener->notify = handle_pointer_focus; + wl_signal_add(&seat->pointer->focus_signal, listener); +} + +static void +shell_surface_pong(struct wl_client *client, struct wl_resource *resource, + uint32_t serial) +{ + struct shell_surface *shsurf = wl_resource_get_user_data(resource); + struct weston_seat *seat; + struct weston_compositor *ec = shsurf->surface->compositor; + + if (shsurf->ping_timer == NULL) + /* Just ignore unsolicited pong. */ + return; + + if (shsurf->ping_timer->serial == serial) { + shsurf->unresponsive = 0; + wl_list_for_each(seat, &ec->seat_list, link) { + if(seat->pointer) + end_busy_cursor(shsurf, seat->pointer); + } + ping_timer_destroy(shsurf); + } +} + +static void +shell_surface_set_title(struct wl_client *client, + struct wl_resource *resource, const char *title) +{ + struct shell_surface *shsurf = wl_resource_get_user_data(resource); + + free(shsurf->title); + shsurf->title = strdup(title); + + /* if ico_window_mgr hook, call hook routine */ + if (shell_hook_title) { + (*shell_hook_title)(shsurf->surface, shsurf->title); + } +} + +static void +shell_surface_set_class(struct wl_client *client, + struct wl_resource *resource, const char *class) +{ + struct shell_surface *shsurf = wl_resource_get_user_data(resource); + + free(shsurf->class); + shsurf->class = strdup(class); +} + +static struct weston_output * +get_default_output(struct weston_compositor *compositor) +{ + return container_of(compositor->output_list.next, + struct weston_output, link); +} + +static void +restore_output_mode(struct weston_output *output) +{ + if (output->current != output->origin || + (int32_t)output->scale != output->origin_scale) + weston_output_switch_mode(output, + output->origin, + output->origin_scale); +} + +static void +restore_all_output_modes(struct weston_compositor *compositor) +{ + struct weston_output *output; + + wl_list_for_each(output, &compositor->output_list, link) + restore_output_mode(output); +} + +static void +shell_unset_fullscreen(struct shell_surface *shsurf) +{ + struct workspace *ws; + /* undo all fullscreen things here */ + if (shsurf->fullscreen.type == WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER && + shell_surface_is_top_fullscreen(shsurf)) { + restore_output_mode(shsurf->fullscreen_output); + } + shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT; + shsurf->fullscreen.framerate = 0; + wl_list_remove(&shsurf->fullscreen.transform.link); + wl_list_init(&shsurf->fullscreen.transform.link); + if (shsurf->fullscreen.black_surface) + weston_surface_destroy(shsurf->fullscreen.black_surface); + shsurf->fullscreen.black_surface = NULL; + shsurf->fullscreen_output = NULL; + weston_surface_set_position(shsurf->surface, + shsurf->saved_x, shsurf->saved_y); + if (shsurf->saved_rotation_valid) { + wl_list_insert(&shsurf->surface->geometry.transformation_list, + &shsurf->rotation.transform.link); + shsurf->saved_rotation_valid = false; + } + + ws = get_current_workspace(shsurf->shell); + wl_list_remove(&shsurf->surface->layer_link); + wl_list_insert(&ws->layer.surface_list, &shsurf->surface->layer_link); +} + +static void +shell_unset_maximized(struct shell_surface *shsurf) +{ + struct workspace *ws; + /* undo all maximized things here */ + shsurf->output = get_default_output(shsurf->surface->compositor); + weston_surface_set_position(shsurf->surface, + shsurf->saved_x, + shsurf->saved_y); + + if (shsurf->saved_rotation_valid) { + wl_list_insert(&shsurf->surface->geometry.transformation_list, + &shsurf->rotation.transform.link); + shsurf->saved_rotation_valid = false; + } + + ws = get_current_workspace(shsurf->shell); + wl_list_remove(&shsurf->surface->layer_link); + wl_list_insert(&ws->layer.surface_list, &shsurf->surface->layer_link); +} + +static int +reset_shell_surface_type(struct shell_surface *surface) +{ + switch (surface->type) { + case SHELL_SURFACE_FULLSCREEN: + shell_unset_fullscreen(surface); + break; + case SHELL_SURFACE_MAXIMIZED: + shell_unset_maximized(surface); + break; + case SHELL_SURFACE_NONE: + case SHELL_SURFACE_TOPLEVEL: + case SHELL_SURFACE_TRANSIENT: + case SHELL_SURFACE_POPUP: + case SHELL_SURFACE_XWAYLAND: + break; + } + + surface->type = SHELL_SURFACE_NONE; + return 0; +} + +static void +set_surface_type(struct shell_surface *shsurf) +{ + struct weston_surface *surface = shsurf->surface; + struct weston_surface *pes = shsurf->parent; + + reset_shell_surface_type(shsurf); + + shsurf->type = shsurf->next_type; + shsurf->next_type = SHELL_SURFACE_NONE; + + switch (shsurf->type) { + case SHELL_SURFACE_TOPLEVEL: + break; + case SHELL_SURFACE_TRANSIENT: + weston_surface_set_position(surface, + pes->geometry.x + shsurf->transient.x, + pes->geometry.y + shsurf->transient.y); + break; + + case SHELL_SURFACE_MAXIMIZED: + case SHELL_SURFACE_FULLSCREEN: + shsurf->saved_x = surface->geometry.x; + shsurf->saved_y = surface->geometry.y; + shsurf->saved_position_valid = true; + + if (!wl_list_empty(&shsurf->rotation.transform.link)) { + wl_list_remove(&shsurf->rotation.transform.link); + wl_list_init(&shsurf->rotation.transform.link); + weston_surface_geometry_dirty(shsurf->surface); + shsurf->saved_rotation_valid = true; + } + break; + + case SHELL_SURFACE_XWAYLAND: + weston_surface_set_position(surface, shsurf->transient.x, + shsurf->transient.y); + break; + + default: + break; + } +} + +static void +set_toplevel(struct shell_surface *shsurf) +{ + shsurf->next_type = SHELL_SURFACE_TOPLEVEL; +} + +static void +shell_surface_set_toplevel(struct wl_client *client, + struct wl_resource *resource) +{ + struct shell_surface *surface = wl_resource_get_user_data(resource); + + set_toplevel(surface); +} + +static void +set_transient(struct shell_surface *shsurf, + struct weston_surface *parent, int x, int y, uint32_t flags) +{ + /* assign to parents output */ + shsurf->parent = parent; + shsurf->transient.x = x; + shsurf->transient.y = y; + shsurf->transient.flags = flags; + shsurf->next_type = SHELL_SURFACE_TRANSIENT; +} + +static void +shell_surface_set_transient(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *parent_resource, + int x, int y, uint32_t flags) +{ + struct shell_surface *shsurf = wl_resource_get_user_data(resource); + struct weston_surface *parent = + wl_resource_get_user_data(parent_resource); + + set_transient(shsurf, parent, x, y, flags); +} + +static struct desktop_shell * +shell_surface_get_shell(struct shell_surface *shsurf) +{ + return shsurf->shell; +} + +static int +get_output_panel_height(struct desktop_shell *shell, + struct weston_output *output) +{ + struct weston_surface *surface; + int panel_height = 0; + + if (!output) + return 0; + + wl_list_for_each(surface, &shell->panel_layer.surface_list, layer_link) { + if (surface->output == output) { + panel_height = surface->geometry.height; + break; + } + } + + return panel_height; +} + +static void +shell_surface_set_maximized(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output_resource ) +{ + struct shell_surface *shsurf = wl_resource_get_user_data(resource); + struct weston_surface *es = shsurf->surface; + struct desktop_shell *shell = NULL; + uint32_t edges = 0, panel_height = 0; + + /* get the default output, if the client set it as NULL + check whether the ouput is available */ + if (output_resource) + shsurf->output = wl_resource_get_user_data(output_resource); + else if (es->output) + shsurf->output = es->output; + else + shsurf->output = get_default_output(es->compositor); + + shell = shell_surface_get_shell(shsurf); + panel_height = get_output_panel_height(shell, shsurf->output); + edges = WL_SHELL_SURFACE_RESIZE_TOP|WL_SHELL_SURFACE_RESIZE_LEFT; + + uifw_trace("shell_surface_set_maximized: send %08x %x w/h=%d/%d", + (int)shsurf->surface, edges, shsurf->output->width, + shsurf->output->height - panel_height); + shsurf->client->send_configure(shsurf->surface, edges, + shsurf->output->width, + shsurf->output->height - panel_height); + + shsurf->next_type = SHELL_SURFACE_MAXIMIZED; +} + +static void +black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height); + +static struct weston_surface * +create_black_surface(struct weston_compositor *ec, + struct weston_surface *fs_surface, + float x, float y, int w, int h) +{ + struct weston_surface *surface = NULL; + + surface = weston_surface_create(ec); + if (surface == NULL) { + weston_log("no memory\n"); + return NULL; + } + + surface->configure = black_surface_configure; + surface->configure_private = fs_surface; + uifw_trace("create_black_surface: configure %08x x/y=%d/%d w/h=%d/%d", + (int)surface, (int)x, (int)y, w, h); + weston_surface_configure(surface, x, y, w, h); + weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1); + pixman_region32_fini(&surface->opaque); + pixman_region32_init_rect(&surface->opaque, 0, 0, w, h); + pixman_region32_fini(&surface->input); + pixman_region32_init_rect(&surface->input, 0, 0, w, h); + + return surface; +} + +/* Create black surface and append it to the associated fullscreen surface. + * Handle size dismatch and positioning according to the method. */ +static void +shell_configure_fullscreen(struct shell_surface *shsurf) +{ + struct weston_output *output = shsurf->fullscreen_output; + struct weston_surface *surface = shsurf->surface; + struct weston_matrix *matrix; + float scale, output_aspect, surface_aspect, x, y; + int32_t surf_x, surf_y, surf_width, surf_height; + + if (shsurf->fullscreen.type != WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER) + restore_output_mode(output); + + if (!shsurf->fullscreen.black_surface) + shsurf->fullscreen.black_surface = + create_black_surface(surface->compositor, + surface, + output->x, output->y, + output->width, + output->height); + + wl_list_remove(&shsurf->fullscreen.black_surface->layer_link); + wl_list_insert(&surface->layer_link, + &shsurf->fullscreen.black_surface->layer_link); + shsurf->fullscreen.black_surface->output = output; + + surface_subsurfaces_boundingbox(surface, &surf_x, &surf_y, + &surf_width, &surf_height); + + switch (shsurf->fullscreen.type) { + case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT: + if (surface->buffer_ref.buffer) + center_on_output(surface, shsurf->fullscreen_output); + break; + case WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE: + /* 1:1 mapping between surface and output dimensions */ + if (output->width == surf_width && + output->height == surf_height) { + weston_surface_set_position(surface, output->x - surf_x, + output->y - surf_y); + break; + } + + matrix = &shsurf->fullscreen.transform.matrix; + weston_matrix_init(matrix); + + output_aspect = (float) output->width / + (float) output->height; + surface_aspect = (float) surface->geometry.width / + (float) surface->geometry.height; + if (output_aspect < surface_aspect) + scale = (float) output->width / + (float) surf_width; + else + scale = (float) output->height / + (float) surf_height; + + weston_matrix_scale(matrix, scale, scale, 1); + wl_list_remove(&shsurf->fullscreen.transform.link); + wl_list_insert(&surface->geometry.transformation_list, + &shsurf->fullscreen.transform.link); + x = output->x + (output->width - surf_width * scale) / 2 - surf_x; + y = output->y + (output->height - surf_height * scale) / 2 - surf_y; + weston_surface_set_position(surface, x, y); + + break; + case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER: + if (shell_surface_is_top_fullscreen(shsurf)) { + struct weston_mode mode = {0, + surf_width * surface->buffer_scale, + surf_height * surface->buffer_scale, + shsurf->fullscreen.framerate}; + + if (weston_output_switch_mode(output, &mode, surface->buffer_scale) == 0) { + weston_surface_set_position(surface, + output->x - surf_x, + output->y - surf_y); + uifw_trace("shell_configure_fullscreen: configure %08x x/y=%d/%d w/h=%d/%d", + (int)shsurf->fullscreen.black_surface, (int)(output->x - surf_x), + (int)(output->y - surf_y), output->width, output->height); + weston_surface_configure(shsurf->fullscreen.black_surface, + output->x - surf_x, + output->y - surf_y, + output->width, + output->height); + break; + } else { + restore_output_mode(output); + center_on_output(surface, output); + } + } + break; + case WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL: + center_on_output(surface, output); + break; + default: + break; + } +} + +/* make the fullscreen and black surface at the top */ +static void +shell_stack_fullscreen(struct shell_surface *shsurf) +{ + struct weston_output *output = shsurf->fullscreen_output; + struct weston_surface *surface = shsurf->surface; + struct desktop_shell *shell = shell_surface_get_shell(shsurf); + + wl_list_remove(&surface->layer_link); + wl_list_insert(&shell->fullscreen_layer.surface_list, + &surface->layer_link); + weston_surface_damage(surface); + + if (!shsurf->fullscreen.black_surface) + shsurf->fullscreen.black_surface = + create_black_surface(surface->compositor, + surface, + output->x, output->y, + output->width, + output->height); + + wl_list_remove(&shsurf->fullscreen.black_surface->layer_link); + wl_list_insert(&surface->layer_link, + &shsurf->fullscreen.black_surface->layer_link); + weston_surface_damage(shsurf->fullscreen.black_surface); +} + +static void +shell_map_fullscreen(struct shell_surface *shsurf) +{ + shell_stack_fullscreen(shsurf); + shell_configure_fullscreen(shsurf); +} + +static void +set_fullscreen(struct shell_surface *shsurf, + uint32_t method, + uint32_t framerate, + struct weston_output *output) +{ + struct weston_surface *es = shsurf->surface; + + if (output) + shsurf->output = output; + else if (es->output) + shsurf->output = es->output; + else + shsurf->output = get_default_output(es->compositor); + + shsurf->fullscreen_output = shsurf->output; + shsurf->fullscreen.type = method; + shsurf->fullscreen.framerate = framerate; + shsurf->next_type = SHELL_SURFACE_FULLSCREEN; + + uifw_trace("set_fullscreen: send %08x 0 w/h=%d/%d", + (int)shsurf->surface, shsurf->output->width, shsurf->output->height); + shsurf->client->send_configure(shsurf->surface, 0, + shsurf->output->width, + shsurf->output->height); +} + +static void +shell_surface_set_fullscreen(struct wl_client *client, + struct wl_resource *resource, + uint32_t method, + uint32_t framerate, + struct wl_resource *output_resource) +{ + struct shell_surface *shsurf = wl_resource_get_user_data(resource); + struct weston_output *output; + + if (output_resource) + output = wl_resource_get_user_data(output_resource); + else + output = NULL; + + set_fullscreen(shsurf, method, framerate, output); +} + +static void +set_xwayland(struct shell_surface *shsurf, int x, int y, uint32_t flags) +{ + /* XXX: using the same fields for transient type */ + shsurf->transient.x = x; + shsurf->transient.y = y; + shsurf->transient.flags = flags; + shsurf->next_type = SHELL_SURFACE_XWAYLAND; +} + +static const struct weston_pointer_grab_interface popup_grab_interface; + +static void +destroy_shell_seat(struct wl_listener *listener, void *data) +{ + struct shell_seat *shseat = + container_of(listener, + struct shell_seat, seat_destroy_listener); + struct shell_surface *shsurf, *prev = NULL; + + if (shseat->popup_grab.grab.interface == &popup_grab_interface) { + weston_pointer_end_grab(shseat->popup_grab.grab.pointer); + shseat->popup_grab.client = NULL; + + wl_list_for_each(shsurf, &shseat->popup_grab.surfaces_list, popup.grab_link) { + shsurf->popup.shseat = NULL; + if (prev) { + wl_list_init(&prev->popup.grab_link); + } + prev = shsurf; + } + wl_list_init(&prev->popup.grab_link); + } + + wl_list_remove(&shseat->seat_destroy_listener.link); + free(shseat); +} + +static struct shell_seat * +create_shell_seat(struct weston_seat *seat) +{ + struct shell_seat *shseat; + + shseat = calloc(1, sizeof *shseat); + if (!shseat) { + weston_log("no memory to allocate shell seat\n"); + return NULL; + } + + shseat->seat = seat; + wl_list_init(&shseat->popup_grab.surfaces_list); + + shseat->seat_destroy_listener.notify = destroy_shell_seat; + wl_signal_add(&seat->destroy_signal, + &shseat->seat_destroy_listener); + + return shseat; +} + +static struct shell_seat * +get_shell_seat(struct weston_seat *seat) +{ + struct wl_listener *listener; + + listener = wl_signal_get(&seat->destroy_signal, destroy_shell_seat); + if (listener == NULL) + return create_shell_seat(seat); + + return container_of(listener, + struct shell_seat, seat_destroy_listener); +} + +static void +popup_grab_focus(struct weston_pointer_grab *grab) +{ + struct weston_pointer *pointer = grab->pointer; + struct weston_surface *surface; + struct shell_seat *shseat = + container_of(grab, struct shell_seat, popup_grab.grab); + struct wl_client *client = shseat->popup_grab.client; + wl_fixed_t sx, sy; + + surface = weston_compositor_pick_surface(pointer->seat->compositor, + pointer->x, pointer->y, + &sx, &sy); + + if (surface && wl_resource_get_client(surface->resource) == client) { + weston_pointer_set_focus(pointer, surface, sx, sy); + } else { + weston_pointer_set_focus(pointer, NULL, + wl_fixed_from_int(0), + wl_fixed_from_int(0)); + } +} + +static void +popup_grab_motion(struct weston_pointer_grab *grab, uint32_t time) +{ + struct weston_pointer *pointer = grab->pointer; + wl_fixed_t sx, sy; + + if (pointer->focus_resource) { + weston_surface_from_global_fixed(pointer->focus, + pointer->x, pointer->y, + &sx, &sy); + wl_pointer_send_motion(pointer->focus_resource, time, sx, sy); + } +} + +static void +popup_grab_button(struct weston_pointer_grab *grab, + uint32_t time, uint32_t button, uint32_t state_w) +{ + struct wl_resource *resource; + struct shell_seat *shseat = + container_of(grab, struct shell_seat, popup_grab.grab); + struct wl_display *display; + enum wl_pointer_button_state state = state_w; + uint32_t serial; + + resource = grab->pointer->focus_resource; + if (resource) { + display = wl_client_get_display(wl_resource_get_client(resource)); + serial = wl_display_get_serial(display); + wl_pointer_send_button(resource, serial, time, button, state); + } else if (state == WL_POINTER_BUTTON_STATE_RELEASED && + (shseat->popup_grab.initial_up || + time - shseat->seat->pointer->grab_time > 500)) { + popup_grab_end(grab->pointer); + } + + if (state == WL_POINTER_BUTTON_STATE_RELEASED) + shseat->popup_grab.initial_up = 1; +} + +static const struct weston_pointer_grab_interface popup_grab_interface = { + popup_grab_focus, + popup_grab_motion, + popup_grab_button, +}; + +static void +popup_grab_end(struct weston_pointer *pointer) +{ + struct weston_pointer_grab *grab = pointer->grab; + struct shell_seat *shseat = + container_of(grab, struct shell_seat, popup_grab.grab); + struct shell_surface *shsurf; + struct shell_surface *prev = NULL; + + if (pointer->grab->interface == &popup_grab_interface) { + weston_pointer_end_grab(grab->pointer); + shseat->popup_grab.client = NULL; + shseat->popup_grab.grab.interface = NULL; + assert(!wl_list_empty(&shseat->popup_grab.surfaces_list)); + /* Send the popup_done event to all the popups open */ + wl_list_for_each(shsurf, &shseat->popup_grab.surfaces_list, popup.grab_link) { + wl_shell_surface_send_popup_done(shsurf->resource); + shsurf->popup.shseat = NULL; + if (prev) { + wl_list_init(&prev->popup.grab_link); + } + prev = shsurf; + } + wl_list_init(&prev->popup.grab_link); + wl_list_init(&shseat->popup_grab.surfaces_list); + } +} + +static void +add_popup_grab(struct shell_surface *shsurf, struct shell_seat *shseat) +{ + struct weston_seat *seat = shseat->seat; + + if (wl_list_empty(&shseat->popup_grab.surfaces_list)) { + shseat->popup_grab.client = wl_resource_get_client(shsurf->resource); + shseat->popup_grab.grab.interface = &popup_grab_interface; + /* We must make sure here that this popup was opened after + * a mouse press, and not just by moving around with other + * popups already open. */ + if (shseat->seat->pointer->button_count > 0) + shseat->popup_grab.initial_up = 0; + + wl_list_insert(&shseat->popup_grab.surfaces_list, &shsurf->popup.grab_link); + weston_pointer_start_grab(seat->pointer, &shseat->popup_grab.grab); + } else { + wl_list_insert(&shseat->popup_grab.surfaces_list, &shsurf->popup.grab_link); + } +} + +static void +remove_popup_grab(struct shell_surface *shsurf) +{ + struct shell_seat *shseat = shsurf->popup.shseat; + + wl_list_remove(&shsurf->popup.grab_link); + wl_list_init(&shsurf->popup.grab_link); + if (wl_list_empty(&shseat->popup_grab.surfaces_list)) { + weston_pointer_end_grab(shseat->popup_grab.grab.pointer); + shseat->popup_grab.grab.interface = NULL; + } +} + +static void +shell_map_popup(struct shell_surface *shsurf) +{ + struct shell_seat *shseat = shsurf->popup.shseat; + struct weston_surface *es = shsurf->surface; + struct weston_surface *parent = shsurf->parent; + + es->output = parent->output; + + weston_surface_set_transform_parent(es, parent); + weston_surface_set_position(es, shsurf->popup.x, shsurf->popup.y); + weston_surface_update_transform(es); + + if (shseat->seat->pointer->grab_serial == shsurf->popup.serial) { + add_popup_grab(shsurf, shseat); + } else { + wl_shell_surface_send_popup_done(shsurf->resource); + shseat->popup_grab.client = NULL; + } +} + +static void +shell_surface_set_popup(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial, + struct wl_resource *parent_resource, + int32_t x, int32_t y, uint32_t flags) +{ + struct shell_surface *shsurf = wl_resource_get_user_data(resource); + + shsurf->type = SHELL_SURFACE_POPUP; + shsurf->parent = wl_resource_get_user_data(parent_resource); + shsurf->popup.shseat = get_shell_seat(wl_resource_get_user_data(seat_resource)); + shsurf->popup.serial = serial; + shsurf->popup.x = x; + shsurf->popup.y = y; +} + +static const struct wl_shell_surface_interface shell_surface_implementation = { + shell_surface_pong, + shell_surface_move, + shell_surface_resize, + shell_surface_set_toplevel, + shell_surface_set_transient, + shell_surface_set_fullscreen, + shell_surface_set_popup, + shell_surface_set_maximized, + shell_surface_set_title, + shell_surface_set_class +}; + +static void +destroy_shell_surface(struct shell_surface *shsurf) +{ + wl_signal_emit(&shsurf->destroy_signal, shsurf); + + /* if ico_window_mgr hook, call hook routine */ + if (shell_hook_destroy) { + (*shell_hook_destroy)(shsurf->surface); + } + + if (!wl_list_empty(&shsurf->popup.grab_link)) { + remove_popup_grab(shsurf); + } + + if (shsurf->fullscreen.type == WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER && + shell_surface_is_top_fullscreen(shsurf)) + restore_output_mode (shsurf->fullscreen_output); + + if (shsurf->fullscreen.black_surface) + weston_surface_destroy(shsurf->fullscreen.black_surface); + + /* As destroy_resource() use wl_list_for_each_safe(), + * we can always remove the listener. + */ + wl_list_remove(&shsurf->surface_destroy_listener.link); + shsurf->surface->configure = NULL; + ping_timer_destroy(shsurf); + free(shsurf->title); + + wl_list_remove(&shsurf->link); + free(shsurf); +} + +static void +shell_destroy_shell_surface(struct wl_resource *resource) +{ + struct shell_surface *shsurf = wl_resource_get_user_data(resource); + + destroy_shell_surface(shsurf); +} + +static void +shell_handle_surface_destroy(struct wl_listener *listener, void *data) +{ + struct shell_surface *shsurf = container_of(listener, + struct shell_surface, + surface_destroy_listener); + + if (shsurf->resource) + wl_resource_destroy(shsurf->resource); + else + destroy_shell_surface(shsurf); +} + +static void +shell_surface_configure(struct weston_surface *, int32_t, int32_t, int32_t, int32_t); + +static struct shell_surface * +get_shell_surface(struct weston_surface *surface) +{ + if (surface->configure == shell_surface_configure) + return surface->configure_private; + else + return NULL; +} + +static struct shell_surface * +create_shell_surface(void *shell, struct weston_surface *surface, + const struct weston_shell_client *client) +{ + struct shell_surface *shsurf; + + if (surface->configure) { + weston_log("surface->configure already set\n"); + return NULL; + } + + shsurf = calloc(1, sizeof *shsurf); + if (!shsurf) { + weston_log("no memory to allocate shell surface\n"); + return NULL; + } + + surface->configure = shell_surface_configure; + surface->configure_private = shsurf; + + shsurf->shell = (struct desktop_shell *) shell; + shsurf->unresponsive = 0; + shsurf->saved_position_valid = false; + shsurf->saved_rotation_valid = false; + shsurf->surface = surface; + shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT; + shsurf->fullscreen.framerate = 0; + shsurf->fullscreen.black_surface = NULL; + shsurf->ping_timer = NULL; + wl_list_init(&shsurf->fullscreen.transform.link); + + wl_signal_init(&shsurf->destroy_signal); + shsurf->surface_destroy_listener.notify = shell_handle_surface_destroy; + wl_signal_add(&surface->destroy_signal, + &shsurf->surface_destroy_listener); + + /* init link so its safe to always remove it in destroy_shell_surface */ + wl_list_init(&shsurf->link); + wl_list_init(&shsurf->popup.grab_link); + + /* empty when not in use */ + wl_list_init(&shsurf->rotation.transform.link); + weston_matrix_init(&shsurf->rotation.rotation); + + wl_list_init(&shsurf->workspace_transform.link); + + shsurf->type = SHELL_SURFACE_NONE; + shsurf->next_type = SHELL_SURFACE_NONE; + + shsurf->client = client; + + return shsurf; +} + +static void +shell_get_shell_surface(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + struct weston_surface *surface = + wl_resource_get_user_data(surface_resource); + struct desktop_shell *shell = wl_resource_get_user_data(resource); + struct shell_surface *shsurf; + + if (get_shell_surface(surface)) { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "desktop_shell::get_shell_surface already requested"); + return; + } + + shsurf = create_shell_surface(shell, surface, &shell_client); + if (!shsurf) { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "surface->configure already set"); + return; + } + + shsurf->resource = + wl_resource_create(client, + &wl_shell_surface_interface, 1, id); + wl_resource_set_implementation(shsurf->resource, + &shell_surface_implementation, + shsurf, shell_destroy_shell_surface); + + /* if ico_window_mgr hook, call hook routine */ + if (shell_hook_create) { + (*shell_hook_create)(client, resource, surface, shsurf); + } +} + +static const struct wl_shell_interface shell_implementation = { + shell_get_shell_surface +}; + +static void +shell_fade(struct desktop_shell *shell, enum fade_type type); + +static int +screensaver_timeout(void *data) +{ + struct desktop_shell *shell = data; + + shell_fade(shell, FADE_OUT); + + return 1; +} + +static void +handle_screensaver_sigchld(struct weston_process *proc, int status) +{ + struct desktop_shell *shell = + container_of(proc, struct desktop_shell, screensaver.process); + + proc->pid = 0; + + if (shell->locked) + weston_compositor_sleep(shell->compositor); +} + +static void +launch_screensaver(struct desktop_shell *shell) +{ + if (shell->screensaver.binding) + return; + + if (!shell->screensaver.path) { + weston_compositor_sleep(shell->compositor); + return; + } + + if (shell->screensaver.process.pid != 0) { + weston_log("old screensaver still running\n"); + return; + } + + weston_client_launch(shell->compositor, + &shell->screensaver.process, + shell->screensaver.path, + handle_screensaver_sigchld); +} + +static void +terminate_screensaver(struct desktop_shell *shell) +{ + if (shell->screensaver.process.pid == 0) + return; + + kill(shell->screensaver.process.pid, SIGTERM); +} + +static void +configure_static_surface(struct weston_surface *es, struct weston_layer *layer, int32_t width, int32_t height) +{ + struct weston_surface *s, *next; + + if (width == 0) + return; + + wl_list_for_each_safe(s, next, &layer->surface_list, layer_link) { + if (s->output == es->output && s != es) { + weston_surface_unmap(s); + s->configure = NULL; + } + } + + uifw_trace("configure_static_surface: configure %08x x/y=%d/%d w/h=%d/%d", + (int)es, (int)es->output->x, (int)es->output->y, width, height); + weston_surface_configure(es, es->output->x, es->output->y, width, height); + + if (wl_list_empty(&es->layer_link)) { + wl_list_insert(&layer->surface_list, &es->layer_link); + weston_compositor_schedule_repaint(es->compositor); + } +} + +static void +background_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height) +{ + struct desktop_shell *shell = es->configure_private; + + configure_static_surface(es, &shell->background_layer, width, height); +} + +static void +desktop_shell_set_background(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output_resource, + struct wl_resource *surface_resource) +{ + struct desktop_shell *shell = wl_resource_get_user_data(resource); + struct weston_surface *surface = + wl_resource_get_user_data(surface_resource); + + if (surface->configure) { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "surface role already assigned"); + return; + } + + surface->configure = background_configure; + surface->configure_private = shell; + surface->output = wl_resource_get_user_data(output_resource); + uifw_trace("desktop_shell_set_background: send %08x 0 w/h=%d/%d", + (int)surface, surface->output->width, surface->output->height); + desktop_shell_send_configure(resource, 0, + surface_resource, + surface->output->width, + surface->output->height); +} + +static void +panel_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height) +{ + struct desktop_shell *shell = es->configure_private; + + configure_static_surface(es, &shell->panel_layer, width, height); +} + +static void +desktop_shell_set_panel(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output_resource, + struct wl_resource *surface_resource) +{ + struct desktop_shell *shell = wl_resource_get_user_data(resource); + struct weston_surface *surface = + wl_resource_get_user_data(surface_resource); + + if (surface->configure) { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "surface role already assigned"); + return; + } + + surface->configure = panel_configure; + surface->configure_private = shell; + surface->output = wl_resource_get_user_data(output_resource); + uifw_trace("desktop_shell_set_panel: send %08x 0 w/h=%d/%d", + (int)surface, surface->output->width, surface->output->height); + desktop_shell_send_configure(resource, 0, + surface_resource, + surface->output->width, + surface->output->height); +} + +static void +lock_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height) +{ + struct desktop_shell *shell = surface->configure_private; + + if (width == 0) + return; + + uifw_trace("lock_surface_configure: change %08x w/h=%d/%d", (int)surface, width, height); + surface->geometry.width = width; + surface->geometry.height = height; + center_on_output(surface, get_default_output(shell->compositor)); + + if (!weston_surface_is_mapped(surface)) { + wl_list_insert(&shell->lock_layer.surface_list, + &surface->layer_link); + weston_surface_update_transform(surface); + shell_fade(shell, FADE_IN); + } +} + +static void +handle_lock_surface_destroy(struct wl_listener *listener, void *data) +{ + struct desktop_shell *shell = + container_of(listener, struct desktop_shell, lock_surface_listener); + + weston_log("lock surface gone\n"); + shell->lock_surface = NULL; +} + +static void +desktop_shell_set_lock_surface(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct desktop_shell *shell = wl_resource_get_user_data(resource); + struct weston_surface *surface = + wl_resource_get_user_data(surface_resource); + + shell->prepare_event_sent = false; + + if (!shell->locked) + return; + + shell->lock_surface = surface; + + shell->lock_surface_listener.notify = handle_lock_surface_destroy; + wl_signal_add(&surface->destroy_signal, + &shell->lock_surface_listener); + + surface->configure = lock_surface_configure; + surface->configure_private = shell; +} + +static void +resume_desktop(struct desktop_shell *shell) +{ + struct workspace *ws = get_current_workspace(shell); + + terminate_screensaver(shell); + + wl_list_remove(&shell->lock_layer.link); + wl_list_insert(&shell->compositor->cursor_layer.link, + &shell->fullscreen_layer.link); + wl_list_insert(&shell->fullscreen_layer.link, + &shell->panel_layer.link); + if (shell->showing_input_panels) { + wl_list_insert(&shell->panel_layer.link, + &shell->input_panel_layer.link); + wl_list_insert(&shell->input_panel_layer.link, + &ws->layer.link); + } else { + wl_list_insert(&shell->panel_layer.link, &ws->layer.link); + } + + restore_focus_state(shell, get_current_workspace(shell)); + + shell->locked = false; + shell_fade(shell, FADE_IN); + weston_compositor_damage_all(shell->compositor); +} + +static void +desktop_shell_unlock(struct wl_client *client, + struct wl_resource *resource) +{ + struct desktop_shell *shell = wl_resource_get_user_data(resource); + + shell->prepare_event_sent = false; + + if (shell->locked) + resume_desktop(shell); +} + +static void +desktop_shell_set_grab_surface(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct desktop_shell *shell = wl_resource_get_user_data(resource); + + shell->grab_surface = wl_resource_get_user_data(surface_resource); +} + +static void +desktop_shell_desktop_ready(struct wl_client *client, + struct wl_resource *resource) +{ + struct desktop_shell *shell = wl_resource_get_user_data(resource); + + shell_fade_startup(shell); +} + +static const struct desktop_shell_interface desktop_shell_implementation = { + desktop_shell_set_background, + desktop_shell_set_panel, + desktop_shell_set_lock_surface, + desktop_shell_unlock, + desktop_shell_set_grab_surface, + desktop_shell_desktop_ready +}; + +static enum shell_surface_type +get_shell_surface_type(struct weston_surface *surface) +{ + struct shell_surface *shsurf; + + shsurf = get_shell_surface(surface); + if (!shsurf) + return SHELL_SURFACE_NONE; + return shsurf->type; +} + +static void +move_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data) +{ + struct weston_surface *focus = + (struct weston_surface *) seat->pointer->focus; + struct weston_surface *surface; + struct shell_surface *shsurf; + + surface = weston_surface_get_main_surface(focus); + if (surface == NULL) + return; + + shsurf = get_shell_surface(surface); + if (shsurf == NULL || shsurf->type == SHELL_SURFACE_FULLSCREEN || + shsurf->type == SHELL_SURFACE_MAXIMIZED) + return; + + surface_move(shsurf, (struct weston_seat *) seat); +} + +static void +resize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data) +{ + struct weston_surface *focus = + (struct weston_surface *) seat->pointer->focus; + struct weston_surface *surface; + uint32_t edges = 0; + int32_t x, y; + struct shell_surface *shsurf; + + surface = weston_surface_get_main_surface(focus); + if (surface == NULL) + return; + + shsurf = get_shell_surface(surface); + if (!shsurf || shsurf->type == SHELL_SURFACE_FULLSCREEN || + shsurf->type == SHELL_SURFACE_MAXIMIZED) + return; + + weston_surface_from_global(surface, + wl_fixed_to_int(seat->pointer->grab_x), + wl_fixed_to_int(seat->pointer->grab_y), + &x, &y); + + if (x < surface->geometry.width / 3) + edges |= WL_SHELL_SURFACE_RESIZE_LEFT; + else if (x < 2 * surface->geometry.width / 3) + edges |= 0; + else + edges |= WL_SHELL_SURFACE_RESIZE_RIGHT; + + if (y < surface->geometry.height / 3) + edges |= WL_SHELL_SURFACE_RESIZE_TOP; + else if (y < 2 * surface->geometry.height / 3) + edges |= 0; + else + edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM; + + surface_resize(shsurf, (struct weston_seat *) seat, edges); +} + +static void +surface_opacity_binding(struct weston_seat *seat, uint32_t time, uint32_t axis, + wl_fixed_t value, void *data) +{ + float step = 0.005; + struct shell_surface *shsurf; + struct weston_surface *focus = + (struct weston_surface *) seat->pointer->focus; + struct weston_surface *surface; + + /* XXX: broken for windows containing sub-surfaces */ + surface = weston_surface_get_main_surface(focus); + if (surface == NULL) + return; + + shsurf = get_shell_surface(surface); + if (!shsurf) + return; + + surface->alpha -= wl_fixed_to_double(value) * step; + + if (surface->alpha > 1.0) + surface->alpha = 1.0; + if (surface->alpha < step) + surface->alpha = step; + + weston_surface_geometry_dirty(surface); + weston_surface_damage(surface); +} + +static void +do_zoom(struct weston_seat *seat, uint32_t time, uint32_t key, uint32_t axis, + wl_fixed_t value) +{ + struct weston_seat *ws = (struct weston_seat *) seat; + struct weston_compositor *compositor = ws->compositor; + struct weston_output *output; + float increment; + + wl_list_for_each(output, &compositor->output_list, link) { + if (pixman_region32_contains_point(&output->region, + wl_fixed_to_double(seat->pointer->x), + wl_fixed_to_double(seat->pointer->y), + NULL)) { + if (key == KEY_PAGEUP) + increment = output->zoom.increment; + else if (key == KEY_PAGEDOWN) + increment = -output->zoom.increment; + else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) + /* For every pixel zoom 20th of a step */ + increment = output->zoom.increment * + -wl_fixed_to_double(value) / 20.0; + else + increment = 0; + + output->zoom.level += increment; + + if (output->zoom.level < 0.0) + output->zoom.level = 0.0; + else if (output->zoom.level > output->zoom.max_level) + output->zoom.level = output->zoom.max_level; + else if (!output->zoom.active) { + output->zoom.active = 1; + output->disable_planes++; + } + + output->zoom.spring_z.target = output->zoom.level; + + weston_output_update_zoom(output, output->zoom.type); + } + } +} + +static void +zoom_axis_binding(struct weston_seat *seat, uint32_t time, uint32_t axis, + wl_fixed_t value, void *data) +{ + do_zoom(seat, time, 0, axis, value); +} + +static void +zoom_key_binding(struct weston_seat *seat, uint32_t time, uint32_t key, + void *data) +{ + do_zoom(seat, time, key, 0, 0); +} + +static void +terminate_binding(struct weston_seat *seat, uint32_t time, uint32_t key, + void *data) +{ + struct weston_compositor *compositor = data; + + wl_display_terminate(compositor->wl_display); +} + +static void +rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time) +{ + struct rotate_grab *rotate = + container_of(grab, struct rotate_grab, base.grab); + struct weston_pointer *pointer = grab->pointer; + struct shell_surface *shsurf = rotate->base.shsurf; + struct weston_surface *surface; + float cx, cy, dx, dy, cposx, cposy, dposx, dposy, r; + + if (!shsurf) + return; + + surface = shsurf->surface; + + cx = 0.5f * surface->geometry.width; + cy = 0.5f * surface->geometry.height; + + dx = wl_fixed_to_double(pointer->x) - rotate->center.x; + dy = wl_fixed_to_double(pointer->y) - rotate->center.y; + r = sqrtf(dx * dx + dy * dy); + + wl_list_remove(&shsurf->rotation.transform.link); + weston_surface_geometry_dirty(shsurf->surface); + + if (r > 20.0f) { + struct weston_matrix *matrix = + &shsurf->rotation.transform.matrix; + + weston_matrix_init(&rotate->rotation); + weston_matrix_rotate_xy(&rotate->rotation, dx / r, dy / r); + + weston_matrix_init(matrix); + weston_matrix_translate(matrix, -cx, -cy, 0.0f); + weston_matrix_multiply(matrix, &shsurf->rotation.rotation); + weston_matrix_multiply(matrix, &rotate->rotation); + weston_matrix_translate(matrix, cx, cy, 0.0f); + + wl_list_insert( + &shsurf->surface->geometry.transformation_list, + &shsurf->rotation.transform.link); + } else { + wl_list_init(&shsurf->rotation.transform.link); + weston_matrix_init(&shsurf->rotation.rotation); + weston_matrix_init(&rotate->rotation); + } + + /* We need to adjust the position of the surface + * in case it was resized in a rotated state before */ + cposx = surface->geometry.x + cx; + cposy = surface->geometry.y + cy; + dposx = rotate->center.x - cposx; + dposy = rotate->center.y - cposy; + if (dposx != 0.0f || dposy != 0.0f) { + weston_surface_set_position(surface, + surface->geometry.x + dposx, + surface->geometry.y + dposy); + } + + /* Repaint implies weston_surface_update_transform(), which + * lazily applies the damage due to rotation update. + */ + weston_compositor_schedule_repaint(shsurf->surface->compositor); +} + +static void +rotate_grab_button(struct weston_pointer_grab *grab, + uint32_t time, uint32_t button, uint32_t state_w) +{ + struct rotate_grab *rotate = + container_of(grab, struct rotate_grab, base.grab); + struct weston_pointer *pointer = grab->pointer; + struct shell_surface *shsurf = rotate->base.shsurf; + enum wl_pointer_button_state state = state_w; + + if (pointer->button_count == 0 && + state == WL_POINTER_BUTTON_STATE_RELEASED) { + if (shsurf) + weston_matrix_multiply(&shsurf->rotation.rotation, + &rotate->rotation); + shell_grab_end(&rotate->base); + free(rotate); + } +} + +static const struct weston_pointer_grab_interface rotate_grab_interface = { + noop_grab_focus, + rotate_grab_motion, + rotate_grab_button, +}; + +static void +surface_rotate(struct shell_surface *surface, struct weston_seat *seat) +{ + struct rotate_grab *rotate; + float dx, dy; + float r; + + rotate = malloc(sizeof *rotate); + if (!rotate) + return; + + weston_surface_to_global_float(surface->surface, + surface->surface->geometry.width * 0.5f, + surface->surface->geometry.height * 0.5f, + &rotate->center.x, &rotate->center.y); + + dx = wl_fixed_to_double(seat->pointer->x) - rotate->center.x; + dy = wl_fixed_to_double(seat->pointer->y) - rotate->center.y; + r = sqrtf(dx * dx + dy * dy); + if (r > 20.0f) { + struct weston_matrix inverse; + + weston_matrix_init(&inverse); + weston_matrix_rotate_xy(&inverse, dx / r, -dy / r); + weston_matrix_multiply(&surface->rotation.rotation, &inverse); + + weston_matrix_init(&rotate->rotation); + weston_matrix_rotate_xy(&rotate->rotation, dx / r, dy / r); + } else { + weston_matrix_init(&surface->rotation.rotation); + weston_matrix_init(&rotate->rotation); + } + + shell_grab_start(&rotate->base, &rotate_grab_interface, surface, + seat->pointer, DESKTOP_SHELL_CURSOR_ARROW); +} + +static void +rotate_binding(struct weston_seat *seat, uint32_t time, uint32_t button, + void *data) +{ + struct weston_surface *focus = + (struct weston_surface *) seat->pointer->focus; + struct weston_surface *base_surface; + struct shell_surface *surface; + + base_surface = weston_surface_get_main_surface(focus); + if (base_surface == NULL) + return; + + surface = get_shell_surface(base_surface); + if (!surface || surface->type == SHELL_SURFACE_FULLSCREEN || + surface->type == SHELL_SURFACE_MAXIMIZED) + return; + + surface_rotate(surface, seat); +} + +static void +lower_fullscreen_layer(struct desktop_shell *shell) +{ + struct workspace *ws; + struct weston_surface *surface, *prev; + + ws = get_current_workspace(shell); + wl_list_for_each_reverse_safe(surface, prev, + &shell->fullscreen_layer.surface_list, + layer_link) + weston_surface_restack(surface, &ws->layer.surface_list); +} + +static void +activate(struct desktop_shell *shell, struct weston_surface *es, + struct weston_seat *seat) +{ + struct weston_surface *main_surface; + struct focus_state *state; + struct workspace *ws; + + main_surface = weston_surface_get_main_surface(es); + + weston_surface_activate(es, seat); + + state = ensure_focus_state(shell, seat); + if (state == NULL) + return; + + state->keyboard_focus = es; + wl_list_remove(&state->surface_destroy_listener.link); + wl_signal_add(&es->destroy_signal, &state->surface_destroy_listener); + + switch (get_shell_surface_type(main_surface)) { + case SHELL_SURFACE_FULLSCREEN: + /* should on top of panels */ + shell_stack_fullscreen(get_shell_surface(main_surface)); + shell_configure_fullscreen(get_shell_surface(main_surface)); + break; + default: + restore_all_output_modes(shell->compositor); + ws = get_current_workspace(shell); + weston_surface_restack(main_surface, &ws->layer.surface_list); + break; + } +} + +/* no-op func for checking black surface */ +static void +black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height) +{ +} + +static bool +is_black_surface (struct weston_surface *es, struct weston_surface **fs_surface) +{ + if (es->configure == black_surface_configure) { + if (fs_surface) + *fs_surface = (struct weston_surface *)es->configure_private; + return true; + } + return false; +} + +static void +click_to_activate_binding(struct weston_seat *seat, uint32_t time, uint32_t button, + void *data) +{ + struct weston_seat *ws = (struct weston_seat *) seat; + struct desktop_shell *shell = data; + struct weston_surface *focus; + struct weston_surface *main_surface; + + focus = (struct weston_surface *) seat->pointer->focus; + if (!focus) + return; + + if (is_black_surface(focus, &main_surface)) + focus = main_surface; + + main_surface = weston_surface_get_main_surface(focus); + if (get_shell_surface_type(main_surface) == SHELL_SURFACE_NONE) + return; + + if (seat->pointer->grab == &seat->pointer->default_grab) + activate(shell, focus, ws); + + /* if ico_window_mgr hook, call hook routine */ + if (shell_hook_select) { + (*shell_hook_select)(focus); + } +} + +static void +lock(struct desktop_shell *shell) +{ + struct workspace *ws = get_current_workspace(shell); + + if (shell->locked) { + weston_compositor_sleep(shell->compositor); + return; + } + + shell->locked = true; + + /* Hide all surfaces by removing the fullscreen, panel and + * toplevel layers. This way nothing else can show or receive + * input events while we are locked. */ + + wl_list_remove(&shell->panel_layer.link); + wl_list_remove(&shell->fullscreen_layer.link); + if (shell->showing_input_panels) + wl_list_remove(&shell->input_panel_layer.link); + wl_list_remove(&ws->layer.link); + wl_list_insert(&shell->compositor->cursor_layer.link, + &shell->lock_layer.link); + + launch_screensaver(shell); + + /* TODO: disable bindings that should not work while locked. */ + + /* All this must be undone in resume_desktop(). */ +} + +static void +unlock(struct desktop_shell *shell) +{ + if (!shell->locked || shell->lock_surface) { + shell_fade(shell, FADE_IN); + return; + } + + /* If desktop-shell client has gone away, unlock immediately. */ + if (!shell->child.desktop_shell) { + resume_desktop(shell); + return; + } + + if (shell->prepare_event_sent) + return; + + desktop_shell_send_prepare_lock_surface(shell->child.desktop_shell); + shell->prepare_event_sent = true; +} + +static void +shell_fade_done(struct weston_surface_animation *animation, void *data) +{ + struct desktop_shell *shell = data; + + shell->fade.animation = NULL; + + switch (shell->fade.type) { + case FADE_IN: + weston_surface_destroy(shell->fade.surface); + shell->fade.surface = NULL; + break; + case FADE_OUT: + lock(shell); + break; + } +} + +static struct weston_surface * +shell_fade_create_surface(struct desktop_shell *shell) +{ + struct weston_compositor *compositor = shell->compositor; + struct weston_surface *surface; + + surface = weston_surface_create(compositor); + if (!surface) + return NULL; + + uifw_trace("shell_fade_create_surface: configure %08x x/y=%d/%d w/h=%d/%d", + (int)surface, 0, 0, 8192, 8192); + weston_surface_configure(surface, 0, 0, 8192, 8192); + weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0); + wl_list_insert(&compositor->fade_layer.surface_list, + &surface->layer_link); + pixman_region32_init(&surface->input); + + return surface; +} + +static void +shell_fade(struct desktop_shell *shell, enum fade_type type) +{ + float tint; + + switch (type) { + case FADE_IN: + tint = 0.0; + break; + case FADE_OUT: + tint = 1.0; + break; + default: + weston_log("shell: invalid fade type\n"); + return; + } + + shell->fade.type = type; + + if (shell->fade.surface == NULL) { + shell->fade.surface = shell_fade_create_surface(shell); + if (!shell->fade.surface) + return; + + shell->fade.surface->alpha = 1.0 - tint; + weston_surface_update_transform(shell->fade.surface); + } + + if (shell->fade.animation) + weston_fade_update(shell->fade.animation, tint); + else + shell->fade.animation = + weston_fade_run(shell->fade.surface, + 1.0 - tint, tint, 300.0, + shell_fade_done, shell); +} + +static void +do_shell_fade_startup(void *data) +{ + struct desktop_shell *shell = data; + + shell_fade(shell, FADE_IN); +} + +static void +shell_fade_startup(struct desktop_shell *shell) +{ + struct wl_event_loop *loop; + + if (!shell->fade.startup_timer) + return; + + wl_event_source_remove(shell->fade.startup_timer); + shell->fade.startup_timer = NULL; + + loop = wl_display_get_event_loop(shell->compositor->wl_display); + wl_event_loop_add_idle(loop, do_shell_fade_startup, shell); +} + +static int +fade_startup_timeout(void *data) +{ + struct desktop_shell *shell = data; + + shell_fade_startup(shell); + return 0; +} + +static void +shell_fade_init(struct desktop_shell *shell) +{ + /* Make compositor output all black, and wait for the desktop-shell + * client to signal it is ready, then fade in. The timer triggers a + * fade-in, in case the desktop-shell client takes too long. + */ + + struct wl_event_loop *loop; + + if (shell->fade.surface != NULL) { + weston_log("%s: warning: fade surface already exists\n", + __func__); + return; + } + + shell->fade.surface = shell_fade_create_surface(shell); + if (!shell->fade.surface) + return; + + weston_surface_update_transform(shell->fade.surface); + weston_surface_damage(shell->fade.surface); + + loop = wl_display_get_event_loop(shell->compositor->wl_display); + shell->fade.startup_timer = + wl_event_loop_add_timer(loop, fade_startup_timeout, shell); + wl_event_source_timer_update(shell->fade.startup_timer, 15000); +} + +static void +idle_handler(struct wl_listener *listener, void *data) +{ + struct desktop_shell *shell = + container_of(listener, struct desktop_shell, idle_listener); + + shell_fade(shell, FADE_OUT); + /* lock() is called from shell_fade_done() */ +} + +static void +wake_handler(struct wl_listener *listener, void *data) +{ + struct desktop_shell *shell = + container_of(listener, struct desktop_shell, wake_listener); + + unlock(shell); +} + +static void +show_input_panels(struct wl_listener *listener, void *data) +{ + struct desktop_shell *shell = + container_of(listener, struct desktop_shell, + show_input_panel_listener); + struct input_panel_surface *surface, *next; + struct weston_surface *ws; + + shell->text_input.surface = (struct weston_surface*)data; + + if (shell->showing_input_panels) + return; + + shell->showing_input_panels = true; + + if (!shell->locked) + wl_list_insert(&shell->panel_layer.link, + &shell->input_panel_layer.link); + + wl_list_for_each_safe(surface, next, + &shell->input_panel.surfaces, link) { + ws = surface->surface; + if (!ws->buffer_ref.buffer) + continue; + wl_list_insert(&shell->input_panel_layer.surface_list, + &ws->layer_link); + weston_surface_geometry_dirty(ws); + weston_surface_update_transform(ws); + weston_surface_damage(ws); + weston_slide_run(ws, ws->geometry.height, 0, NULL, NULL); + } +} + +static void +hide_input_panels(struct wl_listener *listener, void *data) +{ + struct desktop_shell *shell = + container_of(listener, struct desktop_shell, + hide_input_panel_listener); + struct weston_surface *surface, *next; + + if (!shell->showing_input_panels) + return; + + shell->showing_input_panels = false; + + if (!shell->locked) + wl_list_remove(&shell->input_panel_layer.link); + + wl_list_for_each_safe(surface, next, + &shell->input_panel_layer.surface_list, layer_link) + weston_surface_unmap(surface); +} + +static void +update_input_panels(struct wl_listener *listener, void *data) +{ + struct desktop_shell *shell = + container_of(listener, struct desktop_shell, + update_input_panel_listener); + + memcpy(&shell->text_input.cursor_rectangle, data, sizeof(pixman_box32_t)); +} + +static void +center_on_output(struct weston_surface *surface, struct weston_output *output) +{ + int32_t surf_x, surf_y, width, height; + float x, y; + + surface_subsurfaces_boundingbox(surface, &surf_x, &surf_y, &width, &height); + + x = output->x + (output->width - width) / 2 - surf_x / 2; + y = output->y + (output->height - height) / 2 - surf_y / 2; + + uifw_trace("center_on_output: %08x x/y=%d/%d w/h=%d/%d", + (int)output, (int)x, (int)y, width, height); + weston_surface_configure(surface, x, y, width, height); +} + +static void +weston_surface_set_initial_position (struct weston_surface *surface, + struct desktop_shell *shell) +{ + struct weston_compositor *compositor = shell->compositor; + int ix = 0, iy = 0; + int range_x, range_y; + int dx, dy, x, y, panel_height; + struct weston_output *output, *target_output = NULL; + struct weston_seat *seat; + + /* As a heuristic place the new window on the same output as the + * pointer. Falling back to the output containing 0, 0. + * + * TODO: Do something clever for touch too? + */ + wl_list_for_each(seat, &compositor->seat_list, link) { + if (seat->pointer) { + ix = wl_fixed_to_int(seat->pointer->x); + iy = wl_fixed_to_int(seat->pointer->y); + break; + } + } + + wl_list_for_each(output, &compositor->output_list, link) { + if (pixman_region32_contains_point(&output->region, ix, iy, NULL)) { + target_output = output; + break; + } + } + + if (!target_output) { + weston_surface_set_position(surface, 10 + random() % 400, + 10 + random() % 400); + return; + } + + /* Valid range within output where the surface will still be onscreen. + * If this is negative it means that the surface is bigger than + * output. + */ + panel_height = get_output_panel_height(shell, target_output); + range_x = target_output->width - surface->geometry.width; + range_y = (target_output->height - panel_height) - + surface->geometry.height; + + if (range_x > 0) + dx = random() % range_x; + else + dx = 0; + + if (range_y > 0) + dy = panel_height + random() % range_y; + else + dy = panel_height; + + x = target_output->x + dx; + y = target_output->y + dy; + + weston_surface_set_position (surface, x, y); +} + +static void +map(struct desktop_shell *shell, struct weston_surface *surface, + int32_t width, int32_t height, int32_t sx, int32_t sy) +{ + struct weston_compositor *compositor = shell->compositor; + struct shell_surface *shsurf = get_shell_surface(surface); + enum shell_surface_type surface_type = shsurf->type; + struct weston_surface *parent; + struct weston_seat *seat; + struct workspace *ws; + int panel_height = 0; + int32_t surf_x, surf_y; + + uifw_trace("map: %08x sx/sy=%d/%d w/h=%d/%d", (int)surface, sx, sy, width, height); + surface->geometry.width = width; + surface->geometry.height = height; + weston_surface_geometry_dirty(surface); + + /* initial positioning, see also configure() */ + switch (surface_type) { + case SHELL_SURFACE_TOPLEVEL: + weston_surface_set_initial_position(surface, shell); + break; + case SHELL_SURFACE_FULLSCREEN: + center_on_output(surface, shsurf->fullscreen_output); + shell_map_fullscreen(shsurf); + break; + case SHELL_SURFACE_MAXIMIZED: + /* use surface configure to set the geometry */ + panel_height = get_output_panel_height(shell,surface->output); + surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y, + NULL, NULL); + weston_surface_set_position(surface, shsurf->output->x - surf_x, + shsurf->output->y + panel_height - surf_y); + break; + case SHELL_SURFACE_POPUP: + shell_map_popup(shsurf); + break; + case SHELL_SURFACE_NONE: + weston_surface_set_position(surface, + surface->geometry.x + sx, + surface->geometry.y + sy); + break; + default: + ; + } + + /* surface stacking order, see also activate() */ + switch (surface_type) { + case SHELL_SURFACE_POPUP: + case SHELL_SURFACE_TRANSIENT: + parent = shsurf->parent; + wl_list_insert(parent->layer_link.prev, &surface->layer_link); + break; + case SHELL_SURFACE_FULLSCREEN: + case SHELL_SURFACE_NONE: + break; + case SHELL_SURFACE_XWAYLAND: + default: + ws = get_current_workspace(shell); + wl_list_insert(&ws->layer.surface_list, &surface->layer_link); + break; + } + + if (surface_type != SHELL_SURFACE_NONE) { + weston_surface_update_transform(surface); + if (surface_type == SHELL_SURFACE_MAXIMIZED) + surface->output = shsurf->output; + } + + switch (surface_type) { + /* XXX: xwayland's using the same fields for transient type */ + case SHELL_SURFACE_XWAYLAND: + case SHELL_SURFACE_TRANSIENT: + if (shsurf->transient.flags == + WL_SHELL_SURFACE_TRANSIENT_INACTIVE) + break; + case SHELL_SURFACE_TOPLEVEL: + case SHELL_SURFACE_FULLSCREEN: + case SHELL_SURFACE_MAXIMIZED: + if (!shell->locked) { + wl_list_for_each(seat, &compositor->seat_list, link) + activate(shell, surface, seat); + } + break; + default: + break; + } + + if (surface_type == SHELL_SURFACE_TOPLEVEL) + { + switch (shell->win_animation_type) { + case ANIMATION_FADE: + weston_fade_run(surface, 0.0, 1.0, 300.0, NULL, NULL); + break; + case ANIMATION_ZOOM: + weston_zoom_run(surface, 0.5, 1.0, NULL, NULL); + break; + default: + break; + } + } + + /* if ico_window_mgr hook, call hook routine */ + if (shell_hook_map) { + (*shell_hook_map)(surface, &width, &height, &sx, &sy); + } + if (shell_hook_change) { + (*shell_hook_change)(surface, -1, 0); /* send event to manager */ + } +} + +static void +configure(struct desktop_shell *shell, struct weston_surface *surface, + float x, float y, int32_t width, int32_t height) +{ + enum shell_surface_type surface_type = SHELL_SURFACE_NONE; + struct shell_surface *shsurf; + int32_t surf_x, surf_y; + + shsurf = get_shell_surface(surface); + if (shsurf) + surface_type = shsurf->type; + + uifw_trace("configure: %08x x/y=%d/%d w/h=%d/%d", + (int)surface, (int)x, (int)y, width, height); + weston_surface_configure(surface, x, y, width, height); + + switch (surface_type) { + case SHELL_SURFACE_FULLSCREEN: + shell_stack_fullscreen(shsurf); + shell_configure_fullscreen(shsurf); + break; + case SHELL_SURFACE_MAXIMIZED: + /* setting x, y and using configure to change that geometry */ + surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y, + NULL, NULL); + surface->geometry.x = surface->output->x - surf_x; + surface->geometry.y = surface->output->y + + get_output_panel_height(shell,surface->output) - surf_y; + break; + case SHELL_SURFACE_TOPLEVEL: + break; + default: + break; + } + + /* XXX: would a fullscreen surface need the same handling? */ + if (surface->output) { + weston_surface_update_transform(surface); + + if (surface_type == SHELL_SURFACE_MAXIMIZED) + surface->output = shsurf->output; + } + + /* if ico_window_mgr hook, call hook routine */ + if (shell_hook_change) { + (*shell_hook_change)(surface, -1, 0); + } +} + +static void +shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height) +{ + struct shell_surface *shsurf = get_shell_surface(es); + struct desktop_shell *shell = shsurf->shell; + + int type_changed = 0; + + if (!weston_surface_is_mapped(es) && + !wl_list_empty(&shsurf->popup.grab_link)) { + remove_popup_grab(shsurf); + } + + if (width == 0) + return; + + if (shsurf->next_type != SHELL_SURFACE_NONE && + shsurf->type != shsurf->next_type) { + set_surface_type(shsurf); + type_changed = 1; + } + + if (!weston_surface_is_mapped(es)) { + map(shell, es, width, height, sx, sy); + } else if (type_changed || sx != 0 || sy != 0 || + es->geometry.width != width || + es->geometry.height != height) { + float from_x, from_y; + float to_x, to_y; + + weston_surface_to_global_float(es, 0, 0, &from_x, &from_y); + weston_surface_to_global_float(es, sx, sy, &to_x, &to_y); + uifw_trace("shell_surface_configure: configure %08x x/y=%d/%d w/h=%d/%d", + (int)es, (int)(es->geometry.x + to_x - from_x), + (int)(es->geometry.y + to_y - from_y), width, height); + configure(shell, es, + es->geometry.x + to_x - from_x, + es->geometry.y + to_y - from_y, + width, height); + } +} + +static void launch_desktop_shell_process(void *data); + +static void +desktop_shell_sigchld(struct weston_process *process, int status) +{ + uint32_t time; + struct desktop_shell *shell = + container_of(process, struct desktop_shell, child.process); + + shell->child.process.pid = 0; + shell->child.client = NULL; /* already destroyed by wayland */ + + /* if desktop-shell dies more than 5 times in 30 seconds, give up */ + time = weston_compositor_get_time(); + if (time - shell->child.deathstamp > 30000) { + shell->child.deathstamp = time; + shell->child.deathcount = 0; + } + + shell->child.deathcount++; + if (shell->child.deathcount > 5) { + weston_log("%s, giving up.\n", shell_exe); + return; + } + + weston_log("%s died, respawning...\n", shell_exe); + launch_desktop_shell_process(shell); + shell_fade_startup(shell); +} + +static void +launch_desktop_shell_process(void *data) +{ + struct desktop_shell *shell = data; + /* shell program path configurable for ico-ivi */ + /* const char *shell_exe = LIBEXECDIR "/weston-desktop-shell"; */ + + if ((shell_exe[0] == 0) || (shell_exe[0] == ' ')) { + weston_log("no shell program\n"); + } + else { + shell->child.client = weston_client_launch(shell->compositor, + &shell->child.process, + shell_exe, + desktop_shell_sigchld); + + if (!shell->child.client) + weston_log("not able to start %s\n", shell_exe); + else + weston_log("shell %s started\n", shell_exe); + } +} + +static void +bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + struct desktop_shell *shell = data; + struct wl_resource *resource; + + resource = wl_resource_create(client, &wl_shell_interface, 1, id); + if (resource) + wl_resource_set_implementation(resource, &shell_implementation, + shell, NULL); + + /* if ico_window_mgr hook, call hook routine */ + if (shell_hook_bind) { + (*shell_hook_bind)(client, data); + } +} + +static void +unbind_desktop_shell(struct wl_resource *resource) +{ + struct desktop_shell *shell = wl_resource_get_user_data(resource); + + /* if ico_window_mgr hook, call hook routine */ + if (shell_hook_unbind) { + (*shell_hook_unbind)(resource->client); + } + + if (shell->locked) + resume_desktop(shell); + + shell->child.desktop_shell = NULL; + shell->prepare_event_sent = false; +} + +static void +bind_desktop_shell(struct wl_client *client, + void *data, uint32_t version, uint32_t id) +{ + struct desktop_shell *shell = data; + struct wl_resource *resource; + + resource = wl_resource_create(client, &desktop_shell_interface, + MIN(version, 2), id); + + if (client == shell->child.client) { + wl_resource_set_implementation(resource, + &desktop_shell_implementation, + shell, unbind_desktop_shell); + shell->child.desktop_shell = resource; + + if (version < 2) + shell_fade_startup(shell); + + return; + } + + wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "permission to bind desktop_shell denied"); + wl_resource_destroy(resource); +} + +static void +screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height) +{ + struct desktop_shell *shell = surface->configure_private; + + if (width == 0) + return; + + /* XXX: starting weston-screensaver beforehand does not work */ + if (!shell->locked) + return; + + center_on_output(surface, surface->output); + + if (wl_list_empty(&surface->layer_link)) { + wl_list_insert(shell->lock_layer.surface_list.prev, + &surface->layer_link); + weston_surface_update_transform(surface); + wl_event_source_timer_update(shell->screensaver.timer, + shell->screensaver.duration); + shell_fade(shell, FADE_IN); + } +} + +static void +screensaver_set_surface(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface_resource, + struct wl_resource *output_resource) +{ + struct desktop_shell *shell = wl_resource_get_user_data(resource); + struct weston_surface *surface = + wl_resource_get_user_data(surface_resource); + struct weston_output *output = wl_resource_get_user_data(output_resource); + + surface->configure = screensaver_configure; + surface->configure_private = shell; + surface->output = output; +} + +static const struct screensaver_interface screensaver_implementation = { + screensaver_set_surface +}; + +static void +unbind_screensaver(struct wl_resource *resource) +{ + struct desktop_shell *shell = wl_resource_get_user_data(resource); + + shell->screensaver.binding = NULL; +} + +static void +bind_screensaver(struct wl_client *client, + void *data, uint32_t version, uint32_t id) +{ + struct desktop_shell *shell = data; + struct wl_resource *resource; + + resource = wl_resource_create(client, &screensaver_interface, 1, id); + + if (shell->screensaver.binding == NULL) { + wl_resource_set_implementation(resource, + &screensaver_implementation, + shell, unbind_screensaver); + shell->screensaver.binding = resource; + return; + } + + wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "interface object already bound"); + wl_resource_destroy(resource); } -/*--------------------------------------------------------------------------*/ -/** - * @brief configure: surface change - * - * @param[in] shell ico_ivi_shell static table address - * @param[in] surface weston surface - * @param[in] x surface upper-left X position on screen - * @param[in] y surface upper-left Y position on screen - * @param[in] width surface width - * @param[in] height surface height - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -configure(struct ivi_shell *shell, struct weston_surface *surface, - GLfloat x, GLfloat y, int32_t width, int32_t height) +input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height) { - enum shell_surface_type surface_type = SHELL_SURFACE_NONE; - struct shell_surface *shsurf; + struct input_panel_surface *ip_surface = surface->configure_private; + struct desktop_shell *shell = ip_surface->shell; + float x, y; + uint32_t show_surface = 0; - shsurf = get_shell_surface(surface); + if (width == 0) + return; - uifw_trace("configure: Enter(%08x) [%08x] x/y=%d/%d, w/h=%d/%d", - (int)surface, (int)shsurf, (int)x, (int)y, width, height); + if (!weston_surface_is_mapped(surface)) { + if (!shell->showing_input_panels) + return; - if (shsurf) { - surface_type = shsurf->type; - shsurf->geometry_x = (int)x; - shsurf->geometry_y = (int)y; - shsurf->geometry_width = width; - shsurf->geometry_height = height; - ivi_shell_surface_configure(shsurf, x, y, width, height); + show_surface = 1; } - else { - weston_surface_configure(surface, x, y, width, height); + + fprintf(stderr, "%s panel: %d, output: %p\n", __FUNCTION__, ip_surface->panel, ip_surface->output); + + if (ip_surface->panel) { + x = shell->text_input.surface->geometry.x + shell->text_input.cursor_rectangle.x2; + y = shell->text_input.surface->geometry.y + shell->text_input.cursor_rectangle.y2; + } else { + x = ip_surface->output->x + (ip_surface->output->width - width) / 2; + y = ip_surface->output->y + ip_surface->output->height - height; } - if (surface->output) { + uifw_trace("input_panel_configure: configure %08x x/y=%d/%d w/h=%d/%d", + (int)surface, (int)x, (int)y, width, height); + weston_surface_configure(surface, + x, y, + width, height); + + if (show_surface) { + wl_list_insert(&shell->input_panel_layer.surface_list, + &surface->layer_link); weston_surface_update_transform(surface); + weston_surface_damage(surface); + weston_slide_run(surface, surface->geometry.height, 0, NULL, NULL); } - - uifw_trace("configure: Leave"); } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_surface_configure: shell surface change - * - * @param[in] es weston surface - * @param[in] sx surface upper-left X position on screen - * @param[in] sy surface upper-left Y position on screen - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy) +destroy_input_panel_surface(struct input_panel_surface *input_panel_surface) { - struct shell_surface *shsurf = get_shell_surface(es); - struct ivi_shell *shell = shsurf->shell; - int type_changed = 0; - int num_mgr; - int dx, dy, dw, dh; + wl_signal_emit(&input_panel_surface->destroy_signal, input_panel_surface); - uifw_trace("shell_surface_configure: Enter(surf=%08x out=%08x buf=%08x)", - (int)es, (int)es->output, (int)es->buffer); + wl_list_remove(&input_panel_surface->surface_destroy_listener.link); + wl_list_remove(&input_panel_surface->link); - if (! es->buffer) { - uifw_trace("shell_surface_configure: Leave(no buffer)"); - return; - } - if (shsurf->restrain) { - uifw_trace("shell_surface_configure: Leave(restrain)"); - return; - } + input_panel_surface->surface->configure = NULL; - if (shsurf->next_type != SHELL_SURFACE_NONE && - shsurf->type != shsurf->next_type) { - set_surface_type(shsurf); - type_changed = 1; + free(input_panel_surface); +} + +static struct input_panel_surface * +get_input_panel_surface(struct weston_surface *surface) +{ + if (surface->configure == input_panel_configure) { + return surface->configure_private; + } else { + return NULL; } +} - if (! weston_surface_is_mapped(es)) { - if ((es->geometry.width > 0) && (es->geometry.height >0)) { - uifw_trace("shell_surface_configure: map Surface size(sx/sy=%d/%d w/h=%d/%d)", - sx, sy, es->buffer->width, es->buffer->height); - map(shell, es, es->geometry.width, es->geometry.height, sx, sy); - } - else { - uifw_trace("shell_surface_configure: map Buffer size(sx/sy=%d/%d w/h=%d/%d)", - sx, sy, es->buffer->width, es->buffer->height); - map(shell, es, es->buffer->width, es->buffer->height, sx, sy); - } +static void +input_panel_handle_surface_destroy(struct wl_listener *listener, void *data) +{ + struct input_panel_surface *ipsurface = container_of(listener, + struct input_panel_surface, + surface_destroy_listener); + + if (ipsurface->resource) { + wl_resource_destroy(ipsurface->resource); + } else { + destroy_input_panel_surface(ipsurface); } - else { - if (shsurf->mapped == 0) { - if ((es->geometry.width > 0) && (es->geometry.height >0)) { - uifw_trace("shell_surface_configure: map Surface size(sx/sy=%d/%d w/h=%d/%d)", - sx, sy, es->buffer->width, es->buffer->height); - map(shell, es, es->geometry.width, es->geometry.height, sx, sy); - } - else { - uifw_trace("shell_surface_configure: map Buffer size(sx/sy=%d/%d w/h=%d/%d)", - sx, sy, es->buffer->width, es->buffer->height); - map(shell, es, es->buffer->width, es->buffer->height, sx, sy); - } - } +} + +static struct input_panel_surface * +create_input_panel_surface(struct desktop_shell *shell, + struct weston_surface *surface) +{ + struct input_panel_surface *input_panel_surface; - GLfloat from_x, from_y; - GLfloat to_x, to_y; + input_panel_surface = calloc(1, sizeof *input_panel_surface); + if (!input_panel_surface) + return NULL; - weston_surface_to_global_float(es, 0, 0, &from_x, &from_y); - weston_surface_to_global_float(es, sx, sy, &to_x, &to_y); + surface->configure = input_panel_configure; + surface->configure_private = input_panel_surface; - if ((es->geometry.width <= 0) || (es->geometry.height <= 0)) { - num_mgr = 0; - } - else { - /* Surface change request from App */ - uifw_trace("shell_surface_configure: App request change(sx/sy=%d/%d w/h=%d/%d)", - sx, sy, es->buffer->width, es->buffer->height); - dx = shsurf->geometry_x; - dy = shsurf->geometry_y; - dw = shsurf->geometry_width; - dh = shsurf->geometry_height; - if (dw > es->buffer->width) { - dw = es->buffer->width; - dx = shsurf->geometry_x + (shsurf->geometry_width - dw)/2; - } - if (dh > es->buffer->height) { - dh = es->buffer->height; - dy = shsurf->geometry_y + (shsurf->geometry_height - dh)/2; - } - weston_surface_configure(es, dx, dy, dw, dh); - ivi_shell_surface_configure(shsurf, es->geometry.x, es->geometry.y, - es->geometry.width, es->geometry.height); - uifw_trace("shell_surface_configure: w/h=%d/%d->%d/%d x/y=%d/%d->%d/%d", - shsurf->geometry_width, shsurf->geometry_height, - es->geometry.width, es->geometry.height, - shsurf->geometry_x, shsurf->geometry_y, - (int)es->geometry.x, (int)es->geometry.y); - num_mgr = ico_ivi_send_surface_change(es, - shsurf->geometry_x + to_x -from_x, - shsurf->geometry_y + to_y - from_y, - es->buffer->width, es->buffer->height); - uifw_trace("shell_surface_configure: ret ivi_shell_hook_change(%d)", num_mgr) - } - if (num_mgr <= 0) { - /* manager not exist, change surface */ - uifw_trace("shell_surface_configure: configure to Buffer size(no Manager) " - "x=%d+%d-%d y=%d+%d-%d", - (int)es->geometry.x, (int)to_x, (int)from_x, - (int)es->geometry.y, (int)to_y, (int)from_y); - if ((es->geometry.x > ICO_IVI_MAX_COORDINATE) && - (es->geometry.y > ICO_IVI_MAX_COORDINATE) && - (shsurf->visible)) { - es->geometry.x = 0; - es->geometry.y = 0; - es->geometry.dirty = 1; - } - configure(shell, es, - es->geometry.x + to_x - from_x, - es->geometry.y + to_y - from_y, - es->buffer->width, es->buffer->height); - } - } - uifw_trace("shell_surface_configure: Leave(surf=%08x out=%08x buf=%08x)", - (int)es, (int)es->output, (int)es->buffer); + input_panel_surface->shell = shell; + + input_panel_surface->surface = surface; + + wl_signal_init(&input_panel_surface->destroy_signal); + input_panel_surface->surface_destroy_listener.notify = input_panel_handle_surface_destroy; + wl_signal_add(&surface->destroy_signal, + &input_panel_surface->surface_destroy_listener); + + wl_list_init(&input_panel_surface->link); + + return input_panel_surface; } -/*--------------------------------------------------------------------------*/ -/** - * @brief bind_shell: client bind shell - * - * @param[in] client client(ex.HomeScreen) - * @param[in] data user data(ico_ivi_shell static table address) - * @param[in] version interface version number(unused) - * @param[in] id client object id - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id) +input_panel_surface_set_toplevel(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output_resource, + uint32_t position) { - struct ivi_shell *shell = data; - struct wl_resource *resource; + struct input_panel_surface *input_panel_surface = + wl_resource_get_user_data(resource); + struct desktop_shell *shell = input_panel_surface->shell; + + wl_list_insert(&shell->input_panel.surfaces, + &input_panel_surface->link); - uifw_trace("bind_shell: client=%08x id=%d", (int)client, (int)id); + input_panel_surface->output = wl_resource_get_user_data(output_resource); + input_panel_surface->panel = 0; +} - resource = wl_client_add_object(client, &wl_shell_interface, - &shell_implementation, id, shell); +static void +input_panel_surface_set_overlay_panel(struct wl_client *client, + struct wl_resource *resource) +{ + struct input_panel_surface *input_panel_surface = + wl_resource_get_user_data(resource); + struct desktop_shell *shell = input_panel_surface->shell; - resource->destroy = unbind_shell; + wl_list_insert(&shell->input_panel.surfaces, + &input_panel_surface->link); - if (shell_hook_bind) { - (*shell_hook_bind)(client); - } + input_panel_surface->panel = 1; } -/*--------------------------------------------------------------------------*/ -/** - * @brief unbind_shell: client unbind shell - * - * @param[in] resource unbind request resource - * @return none - */ -/*--------------------------------------------------------------------------*/ +static const struct wl_input_panel_surface_interface input_panel_surface_implementation = { + input_panel_surface_set_toplevel, + input_panel_surface_set_overlay_panel +}; + static void -unbind_shell(struct wl_resource *resource) +destroy_input_panel_surface_resource(struct wl_resource *resource) { - uifw_trace("unbind_shell"); + struct input_panel_surface *ipsurf = + wl_resource_get_user_data(resource); - if (shell_hook_unbind) { - (*shell_hook_unbind)(resource->client); + destroy_input_panel_surface(ipsurf); +} + +static void +input_panel_get_input_panel_surface(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + struct weston_surface *surface = + wl_resource_get_user_data(surface_resource); + struct desktop_shell *shell = wl_resource_get_user_data(resource); + struct input_panel_surface *ipsurf; + + if (get_input_panel_surface(surface)) { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "wl_input_panel::get_input_panel_surface already requested"); + return; + } + + ipsurf = create_input_panel_surface(shell, surface); + if (!ipsurf) { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "surface->configure already set"); + return; } - free(resource); + + ipsurf->resource = + wl_resource_create(client, + &wl_input_panel_surface_interface, 1, id); + wl_resource_set_implementation(ipsurf->resource, + &input_panel_surface_implementation, + ipsurf, + destroy_input_panel_surface_resource); } -/*--------------------------------------------------------------------------*/ -/** - * @brief unbind_ivi_shell: client unbind ico_ivi_shell - * - * @param[in] resource unbind request resource - * @return none - */ -/*--------------------------------------------------------------------------*/ +static const struct wl_input_panel_interface input_panel_implementation = { + input_panel_get_input_panel_surface +}; + static void -unbind_ivi_shell(struct wl_resource *resource) +unbind_input_panel(struct wl_resource *resource) { - uifw_trace("unbind_ivi_shell"); - free(resource); + struct desktop_shell *shell = wl_resource_get_user_data(resource); + + shell->input_panel.binding = NULL; } -/*--------------------------------------------------------------------------*/ -/** - * @brief bind_ivi_shell: client bind ico_ivi_shell - * - * @param[in] client client(ex.HomeScreen) - * @param[in] data user data(ico_ivi_shell static table address) - * @param[in] version interface version number(unused) - * @param[in] id client object id - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -bind_ivi_shell(struct wl_client *client, - void *data, uint32_t version, uint32_t id) +bind_input_panel(struct wl_client *client, + void *data, uint32_t version, uint32_t id) { - struct ivi_shell *shell = data; + struct desktop_shell *shell = data; struct wl_resource *resource; - resource = wl_client_add_object(client, &ico_ivi_shell_interface, - NULL, id, shell); + resource = wl_resource_create(client, + &wl_input_panel_interface, 1, id); - uifw_trace("bind_ivi_shell: client=%08x id=%d", (int)client, (int)id); + if (shell->input_panel.binding == NULL) { + wl_resource_set_implementation(resource, + &input_panel_implementation, + shell, unbind_input_panel); + shell->input_panel.binding = resource; + return; + } - resource->destroy = unbind_ivi_shell; + wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "interface object already bound"); + wl_resource_destroy(resource); } -/*--------------------------------------------------------------------------*/ -/** - * @brief shell_destroy: destroy ico_ivi_shell - * - * @param[in] listener shell destroy listener - * @param[in] data user data(unused) - * @return none - */ -/*--------------------------------------------------------------------------*/ +struct switcher { + struct desktop_shell *shell; + struct weston_surface *current; + struct wl_listener listener; + struct weston_keyboard_grab grab; +}; + static void -shell_destroy(struct wl_listener *listener, void *data) +switcher_next(struct switcher *switcher) { - struct ivi_shell *shell = - container_of(listener, struct ivi_shell, destroy_listener); + struct weston_surface *surface; + struct weston_surface *first = NULL, *prev = NULL, *next = NULL; + struct shell_surface *shsurf; + struct workspace *ws = get_current_workspace(switcher->shell); + + wl_list_for_each(surface, &ws->layer.surface_list, layer_link) { + switch (get_shell_surface_type(surface)) { + case SHELL_SURFACE_TOPLEVEL: + case SHELL_SURFACE_FULLSCREEN: + case SHELL_SURFACE_MAXIMIZED: + if (first == NULL) + first = surface; + if (prev == switcher->current) + next = surface; + prev = surface; + surface->alpha = 0.25; + weston_surface_geometry_dirty(surface); + weston_surface_damage(surface); + break; + default: + break; + } + + if (is_black_surface(surface, NULL)) { + surface->alpha = 0.25; + weston_surface_geometry_dirty(surface); + weston_surface_damage(surface); + } + } - uifw_trace("shell_destroy"); + if (next == NULL) + next = first; - free(shell); + if (next == NULL) + return; + + wl_list_remove(&switcher->listener.link); + wl_signal_add(&next->destroy_signal, &switcher->listener); + + switcher->current = next; + next->alpha = 1.0; + + shsurf = get_shell_surface(switcher->current); + if (shsurf && shsurf->type ==SHELL_SURFACE_FULLSCREEN) + shsurf->fullscreen.black_surface->alpha = 1.0; } -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_restack_ivi_layer: rebuild compositor surface list - * - * @param[in] shell ico_ivi_shell static table address - * @param[in] shsurf target shell surface(if NULL, no need change surface) - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -ivi_shell_restack_ivi_layer(struct ivi_shell *shell, struct shell_surface *shsurf) -{ - struct shell_surface *es; - struct ivi_layer_list *el; - float new_x, new_y; - - uifw_trace("ivi_shell_restack_ivi_layer: Enter[%08x]", (int)shsurf); - - /* make compositor surface list */ - wl_list_init(&shell->surface.surface_list); - wl_list_for_each (el, &shell->ivi_layer.link, link) { - if (ico_option_flag() & ICO_OPTION_FLAG_UNVISIBLE) { - wl_list_for_each (es, &el->surface_list, ivi_layer) { - if (es->surface != NULL) { - if ((el->visible == FALSE) || (es->visible == FALSE)) { - new_x = (float)(ICO_IVI_MAX_COORDINATE+1); - new_y = (float)(ICO_IVI_MAX_COORDINATE+1); - } - else if (es->surface->buffer) { - if (es->geometry_width > es->surface->buffer->width) { - new_x = (float)(es->geometry_x + - (es->geometry_width - es->surface->geometry.width)/2); - } - else { - new_x = (float)es->geometry_x; - } - if (es->geometry_height > es->surface->buffer->height) { - new_y = (float) (es->geometry_y + - (es->geometry_height - es->surface->geometry.height)/2); - } - else { - new_y = (float)es->geometry_y; - } - } - else { - new_x = (float)(ICO_IVI_MAX_COORDINATE+1); - new_y = (float)(ICO_IVI_MAX_COORDINATE+1); - } - wl_list_insert(shell->surface.surface_list.prev, - &es->surface->layer_link); - if ((new_x != es->surface->geometry.x) || - (new_y != es->surface->geometry.y)) { - weston_surface_damage_below(es->surface); - es->surface->geometry.x = new_x; - es->surface->geometry.y = new_y; - es->surface->geometry.dirty = 1; - weston_surface_damage_below(es->surface); - } - } - } - } - else { - if (el->visible != FALSE) { - wl_list_for_each (es, &el->surface_list, ivi_layer) { - if ((es->visible != FALSE) && (es->surface) && - (es->surface->output != NULL) && - (es->surface->shader != NULL)) { - wl_list_insert(shell->surface.surface_list.prev, - &es->surface->layer_link); - } - } - } - } - } +switcher_handle_surface_destroy(struct wl_listener *listener, void *data) +{ + struct switcher *switcher = + container_of(listener, struct switcher, listener); + + switcher_next(switcher); +} + +static void +switcher_destroy(struct switcher *switcher) +{ + struct weston_surface *surface; + struct weston_keyboard *keyboard = switcher->grab.keyboard; + struct workspace *ws = get_current_workspace(switcher->shell); - /* damage(redraw) target surfacem if target exist */ - if (shsurf) { - weston_surface_damage_below(shsurf->surface); + wl_list_for_each(surface, &ws->layer.surface_list, layer_link) { + surface->alpha = 1.0; + weston_surface_damage(surface); } - /* composit and draw screen(plane) */ - weston_compositor_schedule_repaint(shell->compositor); + if (switcher->current) + activate(switcher->shell, switcher->current, + (struct weston_seat *) keyboard->seat); + wl_list_remove(&switcher->listener.link); + weston_keyboard_end_grab(keyboard); + if (keyboard->input_method_resource) + keyboard->grab = &keyboard->input_method_grab; + free(switcher); +} + +static void +switcher_key(struct weston_keyboard_grab *grab, + uint32_t time, uint32_t key, uint32_t state_w) +{ + struct switcher *switcher = container_of(grab, struct switcher, grab); + enum wl_keyboard_key_state state = state_w; - uifw_trace("ivi_shell_restack_ivi_layer: Leave"); + if (key == KEY_TAB && state == WL_KEYBOARD_KEY_STATE_PRESSED) + switcher_next(switcher); } -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_set_active: surface active control - * - * @param[in] shsurf shell surface(if NULL, no active surface) - * @param[in] target target device - * @return none - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ivi_shell_set_active(struct shell_surface *shsurf, const int target) +static void +switcher_modifier(struct weston_keyboard_grab *grab, uint32_t serial, + uint32_t mods_depressed, uint32_t mods_latched, + uint32_t mods_locked, uint32_t group) { - struct ivi_shell *shell; - struct weston_seat *seat; - struct weston_surface *surface; - int object = target; - wl_fixed_t sx, sy; + struct switcher *switcher = container_of(grab, struct switcher, grab); + struct weston_seat *seat = (struct weston_seat *) grab->keyboard->seat; - uifw_trace("ivi_shell_set_active: Enter(%08x,%x)", (int)shsurf, target); + if ((seat->modifier_state & switcher->shell->binding_modifier) == 0) + switcher_destroy(switcher); +} - if (shsurf) { - shell = shell_surface_get_shell(shsurf); - surface = shsurf->surface; - if (object == 0) { - surface = NULL; - if (shell->active_pointer_shsurf == shsurf) { - object |= ICO_IVI_SHELL_ACTIVE_POINTER; - } - if (shell->active_keyboard_shsurf == shsurf) { - object |= ICO_IVI_SHELL_ACTIVE_KEYBOARD; - } - } - else { - if (object & ICO_IVI_SHELL_ACTIVE_POINTER) { - shell->active_pointer_shsurf = shsurf; - } - if (object & ICO_IVI_SHELL_ACTIVE_KEYBOARD) { - shell->active_keyboard_shsurf = shsurf; - } +static const struct weston_keyboard_grab_interface switcher_grab = { + switcher_key, + switcher_modifier, +}; + +static void +switcher_binding(struct weston_seat *seat, uint32_t time, uint32_t key, + void *data) +{ + struct desktop_shell *shell = data; + struct switcher *switcher; + + switcher = malloc(sizeof *switcher); + switcher->shell = shell; + switcher->current = NULL; + switcher->listener.notify = switcher_handle_surface_destroy; + wl_list_init(&switcher->listener.link); + + restore_all_output_modes(shell->compositor); + lower_fullscreen_layer(switcher->shell); + switcher->grab.interface = &switcher_grab; + weston_keyboard_start_grab(seat->keyboard, &switcher->grab); + weston_keyboard_set_focus(seat->keyboard, NULL); + switcher_next(switcher); +} + +static void +backlight_binding(struct weston_seat *seat, uint32_t time, uint32_t key, + void *data) +{ + struct weston_compositor *compositor = data; + struct weston_output *output; + long backlight_new = 0; + + /* TODO: we're limiting to simple use cases, where we assume just + * control on the primary display. We'd have to extend later if we + * ever get support for setting backlights on random desktop LCD + * panels though */ + output = get_default_output(compositor); + if (!output) + return; + + if (!output->set_backlight) + return; + + if (key == KEY_F9 || key == KEY_BRIGHTNESSDOWN) + backlight_new = output->backlight_current - 25; + else if (key == KEY_F10 || key == KEY_BRIGHTNESSUP) + backlight_new = output->backlight_current + 25; + + if (backlight_new < 5) + backlight_new = 5; + if (backlight_new > 255) + backlight_new = 255; + + output->backlight_current = backlight_new; + output->set_backlight(output, output->backlight_current); +} + +struct debug_binding_grab { + struct weston_keyboard_grab grab; + struct weston_seat *seat; + uint32_t key[2]; + int key_released[2]; +}; + +static void +debug_binding_key(struct weston_keyboard_grab *grab, uint32_t time, + uint32_t key, uint32_t state) +{ + struct debug_binding_grab *db = (struct debug_binding_grab *) grab; + struct wl_resource *resource; + struct wl_display *display; + uint32_t serial; + int send = 0, terminate = 0; + int check_binding = 1; + int i; + + if (state == WL_KEYBOARD_KEY_STATE_RELEASED) { + /* Do not run bindings on key releases */ + check_binding = 0; + + for (i = 0; i < 2; i++) + if (key == db->key[i]) + db->key_released[i] = 1; + + if (db->key_released[0] && db->key_released[1]) { + /* All key releases been swalled so end the grab */ + terminate = 1; + } else if (key != db->key[0] && key != db->key[1]) { + /* Should not swallow release of other keys */ + send = 1; } + } else if (key == db->key[0] && !db->key_released[0]) { + /* Do not check bindings for the first press of the binding + * key. This allows it to be used as a debug shortcut. + * We still need to swallow this event. */ + check_binding = 0; + } else if (db->key[1]) { + /* If we already ran a binding don't process another one since + * we can't keep track of all the binding keys that were + * pressed in order to swallow the release events. */ + send = 1; + check_binding = 0; } - else { - shell = default_shell; - surface = NULL; - if (target == 0) { - object = ICO_IVI_SHELL_ACTIVE_POINTER|ICO_IVI_SHELL_ACTIVE_KEYBOARD; - } - if (object & ICO_IVI_SHELL_ACTIVE_POINTER) { - shell->active_pointer_shsurf = NULL; - } - if (object & ICO_IVI_SHELL_ACTIVE_KEYBOARD) { - shell->active_keyboard_shsurf = NULL; + + if (check_binding) { + struct weston_compositor *ec = db->seat->compositor; + + if (weston_compositor_run_debug_binding(ec, db->seat, time, + key, state)) { + /* We ran a binding so swallow the press and keep the + * grab to swallow the released too. */ + send = 0; + terminate = 0; + db->key[1] = key; + } else { + /* Terminate the grab since the key pressed is not a + * debug binding key. */ + send = 1; + terminate = 1; } } - wl_list_for_each(seat, &shell->compositor->seat_list, link) { - if ((object & ICO_IVI_SHELL_ACTIVE_POINTER) && (seat->seat.pointer)) { - if (surface) { - uifw_trace("ivi_shell_set_active: pointer set surface(%08x=>%08x)", - (int)seat->seat.pointer->focus, (int)&surface->surface); - if (seat->seat.pointer->focus != &surface->surface) { - weston_surface_from_global_fixed(surface, - seat->seat.pointer->x, - seat->seat.pointer->y, - &sx, &sy); - wl_pointer_set_focus(seat->seat.pointer, &surface->surface, sx, sy); - } - } - else { - uifw_trace("ivi_shell_set_active: pointer reset surface(%08x)", - (int)seat->seat.pointer->focus); - wl_pointer_set_focus(seat->seat.pointer, NULL, - wl_fixed_from_int(0), wl_fixed_from_int(0)); - } - } - if ((object & ICO_IVI_SHELL_ACTIVE_KEYBOARD) && (seat->has_keyboard)) { - if (surface) { - uifw_trace("ivi_shell_set_active: keyboard set surface(%08x=>%08x)", - (int)seat->seat.keyboard->focus, (int)&surface->surface); - if (seat->seat.keyboard->focus != &surface->surface) { - wl_keyboard_set_focus(seat->seat.keyboard, &surface->surface); - } - } - else { - uifw_trace("ivi_shell_set_active: keyboard reset surface(%08x)", - (int)seat->seat.keyboard); - wl_keyboard_set_focus(seat->seat.keyboard, NULL); - } - } - else { - uifw_trace("ivi_shell_set_active: seat[%08x] has no keyboard", (int)seat); + if (send) { + resource = grab->keyboard->focus_resource; + + if (resource) { + display = wl_client_get_display(wl_resource_get_client(resource)); + serial = wl_display_next_serial(display); + wl_keyboard_send_key(resource, serial, time, key, state); } } - uifw_trace("ivi_shell_set_active: Leave(%08x)", (int)shsurf); -} -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_set_client_attr : set client ttribute - * - * @param[in] client target client - * @param[in] attr attribute - * @param[in] value attribute value - * @return none - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ivi_shell_set_client_attr(struct wl_client *client, const int attr, const int value) -{ - struct shell_surface *es; - struct ivi_layer_list *el; - - uifw_trace("ivi_shell_set_client_attr: Enter(%08x,%d,%d)", (int)client, attr, value); - - wl_list_for_each (el, &default_shell->ivi_layer.link, link) { - wl_list_for_each (es, &el->surface_list, ivi_layer) { - if (es->wclient == client) { - switch(attr) { - case ICO_CLEINT_ATTR_NOCONFIGURE: - es->noconfigure = value; - uifw_trace("ivi_shell_set_client_attr: set surface %08x", (int)es); - break; - default: - break; - } - } - } + if (terminate) { + weston_keyboard_end_grab(grab->keyboard); + if (grab->keyboard->input_method_resource) + grab->keyboard->grab = &grab->keyboard->input_method_grab; + free(db); } - uifw_trace("ivi_shell_set_client_attr: Leave"); } -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_set_active: surface active control - * - * @param[in] shsurf shell surface(if NULL, no active surface) - * @param[in] restrain restrain(1)/not restrain(0) - * @return none - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ivi_shell_restrain_configure(struct shell_surface *shsurf, const int restrain) +static void +debug_binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial, + uint32_t mods_depressed, uint32_t mods_latched, + uint32_t mods_locked, uint32_t group) +{ + struct wl_resource *resource; + + resource = grab->keyboard->focus_resource; + if (!resource) + return; + + wl_keyboard_send_modifiers(resource, serial, mods_depressed, + mods_latched, mods_locked, group); +} + +struct weston_keyboard_grab_interface debug_binding_keyboard_grab = { + debug_binding_key, + debug_binding_modifiers +}; + +static void +debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data) +{ + struct debug_binding_grab *grab; + + grab = calloc(1, sizeof *grab); + if (!grab) + return; + + grab->seat = (struct weston_seat *) seat; + grab->key[0] = key; + grab->grab.interface = &debug_binding_keyboard_grab; + weston_keyboard_start_grab(seat->keyboard, &grab->grab); +} + +static void +force_kill_binding(struct weston_seat *seat, uint32_t time, uint32_t key, + void *data) +{ + struct weston_surface *focus_surface; + struct wl_client *client; + struct desktop_shell *shell = data; + struct weston_compositor *compositor = shell->compositor; + pid_t pid; + + focus_surface = seat->keyboard->focus; + if (!focus_surface) + return; + + wl_signal_emit(&compositor->kill_signal, focus_surface); + + client = wl_resource_get_client(focus_surface->resource); + wl_client_get_credentials(client, &pid, NULL, NULL); + + /* Skip clients that we launched ourselves (the credentials of + * the socketpair is ours) */ + if (pid == getpid()) + return; + + kill(pid, SIGKILL); +} + +static void +workspace_up_binding(struct weston_seat *seat, uint32_t time, + uint32_t key, void *data) +{ + struct desktop_shell *shell = data; + unsigned int new_index = shell->workspaces.current; + + if (shell->locked) + return; + if (new_index != 0) + new_index--; + + change_workspace(shell, new_index); +} + +static void +workspace_down_binding(struct weston_seat *seat, uint32_t time, + uint32_t key, void *data) { - uifw_trace("ivi_shell_restrain_configure: set %08x to %d", - (int)shsurf, restrain); - shsurf->restrain = restrain; + struct desktop_shell *shell = data; + unsigned int new_index = shell->workspaces.current; - if (restrain == 0) { - shell_surface_configure(shsurf->surface, shsurf->geometry_x, shsurf->geometry_y); - ivi_shell_restack_ivi_layer(shell_surface_get_shell(shsurf), shsurf); - } + if (shell->locked) + return; + if (new_index < shell->workspaces.num - 1) + new_index++; + + change_workspace(shell, new_index); } -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_is_restrain: check surface restrain - * - * @param[in] shsurf shell surface(if NULL, no active surface) - * @return restrain - * @retval =1 surface currently restrain - * @retval =0 not restrain - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT int -ivi_shell_is_restrain(struct shell_surface *shsurf) +static void +workspace_f_binding(struct weston_seat *seat, uint32_t time, + uint32_t key, void *data) { - return shsurf->restrain; + struct desktop_shell *shell = data; + unsigned int new_index; + + if (shell->locked) + return; + new_index = key - KEY_F1; + if (new_index >= shell->workspaces.num) + new_index = shell->workspaces.num - 1; + + change_workspace(shell, new_index); } -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_default_animation: window default animation - * - * @param[out] msec animation time(ms) - * @param[out] fps animation frame rate(fps) - * @return default animation name - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT const char * -ivi_shell_default_animation(int *msec, int *fps) +static void +workspace_move_surface_up_binding(struct weston_seat *seat, uint32_t time, + uint32_t key, void *data) { - if (msec) { - *msec = default_shell->win_animation_time; - } - if (fps) { - *fps = default_shell->win_animation_fps; - } - return default_shell->win_animation; + struct desktop_shell *shell = data; + unsigned int new_index = shell->workspaces.current; + + if (shell->locked) + return; + + if (new_index != 0) + new_index--; + + take_surface_to_workspace_by_seat(shell, seat, new_index); } -/*--------------------------------------------------------------------------*/ -/** - * @brief click_to_activate_binding: clieck and select surface - * - * @param[in] seat clicked target seat - * @param[in] button click button(unused) - * @param[in] data user data(ico_ivi_shell static table address) - * @return none - */ -/*--------------------------------------------------------------------------*/ static void -click_to_activate_binding(struct wl_seat *seat, uint32_t time, uint32_t button, void *data) +workspace_move_surface_down_binding(struct weston_seat *seat, uint32_t time, + uint32_t key, void *data) { - struct ivi_shell *shell = data; - struct shell_surface *shsurf; - struct weston_surface *surface; + struct desktop_shell *shell = data; + unsigned int new_index = shell->workspaces.current; - if ((! seat) || (! seat->pointer) || (! seat->pointer->focus)) { - uifw_trace("click_to_activate_binding: Surface dose not exist"); - } - else { - surface = (struct weston_surface *) seat->pointer->focus; - shsurf = get_shell_surface(surface); - if (! shsurf) { - uifw_trace("click_to_activate_binding: Shell surface dose not exist"); - } - else if ((shsurf->type == SHELL_SURFACE_NONE) || - (shsurf->visible == 0)) { - uifw_trace("click_to_activate_binding: Surface[%08x] is not visible", - (int)shsurf); - } - else if (shell->active_pointer_shsurf != shsurf) { - if (shell_hook_select) { - /* surface select hook routine */ - uifw_trace("click_to_activate_binding: call ivi_shell_hook_select[%08x]", - (int)shsurf); - (void) (*shell_hook_select)(surface); - uifw_trace("click_to_activate_binding: ret ivi_shell_hook_select") - } - else { - ivi_shell_set_active(shsurf, - ICO_IVI_SHELL_ACTIVE_POINTER | - ICO_IVI_SHELL_ACTIVE_KEYBOARD); - uifw_trace("click_to_activate_binding: no hook[%08x]", (int)shsurf); - } - } - else { - uifw_trace("click_to_activate_binding: ShellSurface[%08x] already active", - (int)shsurf); - } - } + if (shell->locked) + return; + + if (new_index < shell->workspaces.num - 1) + new_index++; + + take_surface_to_workspace_by_seat(shell, seat, new_index); } -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_set_visible: surface visible control - * - * @param[in] shsurf shell surface - * @param[in] visible visibility(1=visible/0=unvisible/-1=system default) - * @return none - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ivi_shell_set_visible(struct shell_surface *shsurf, const int visible) +static void +shell_destroy(struct wl_listener *listener, void *data) { - struct ivi_shell *shell = shell_surface_get_shell(shsurf); - int next; + struct desktop_shell *shell = + container_of(listener, struct desktop_shell, destroy_listener); + struct workspace **ws; - uifw_trace("ivi_shell_set_visible: [%08x] (%08x) visible=%d", - (int)shsurf, (int)shsurf->surface, (int)visible); + if (shell->child.client) + wl_client_destroy(shell->child.client); - if (visible < 0) { - next = shell->win_visible_on_create; - } - else { - next = visible; - } + wl_list_remove(&shell->idle_listener.link); + wl_list_remove(&shell->wake_listener.link); + wl_list_remove(&shell->show_input_panel_listener.link); + wl_list_remove(&shell->hide_input_panel_listener.link); - if ((shsurf->visible != FALSE) && (next == 0)) { - /* change show ==> hide */ - shsurf->visible = FALSE; - ivi_shell_restack_ivi_layer(shell, shsurf); - } - else if ((shsurf->visible == FALSE) && (next != 0)) { - /* change hide ==> show */ - shsurf->visible = TRUE; - ivi_shell_restack_ivi_layer(shell, shsurf); - } - else { - /* other case, no change */ - uifw_trace("ivi_shell_set_visible: No change"); - } + wl_array_for_each(ws, &shell->workspaces.array) + workspace_destroy(*ws); + wl_array_release(&shell->workspaces.array); + + free(shell->screensaver.path); + free(shell); } -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_is_visible: get surface visibility - * - * @param[in] shsurf shell surface - * @return visibility - * @retval true visible - * @retval false unvisible - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT bool -ivi_shell_is_visible(struct shell_surface *shsurf) +static void +shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell) { - return(shsurf->visible); + uint32_t mod; + int i, num_workspace_bindings; + + /* fixed bindings */ + weston_compositor_add_key_binding(ec, KEY_BACKSPACE, + MODIFIER_CTRL | MODIFIER_ALT, + terminate_binding, ec); + weston_compositor_add_button_binding(ec, BTN_LEFT, 0, + click_to_activate_binding, + shell); + weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL, + MODIFIER_SUPER | MODIFIER_ALT, + surface_opacity_binding, NULL); + weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL, + MODIFIER_SUPER, zoom_axis_binding, + NULL); + + /* configurable bindings */ + mod = shell->binding_modifier; + weston_compositor_add_key_binding(ec, KEY_PAGEUP, mod, + zoom_key_binding, NULL); + weston_compositor_add_key_binding(ec, KEY_PAGEDOWN, mod, + zoom_key_binding, NULL); + weston_compositor_add_button_binding(ec, BTN_LEFT, mod, move_binding, + shell); + weston_compositor_add_button_binding(ec, BTN_MIDDLE, mod, + resize_binding, shell); + + if (ec->capabilities & WESTON_CAP_ROTATION_ANY) + weston_compositor_add_button_binding(ec, BTN_RIGHT, mod, + rotate_binding, NULL); + + weston_compositor_add_key_binding(ec, KEY_TAB, mod, switcher_binding, + shell); + weston_compositor_add_key_binding(ec, KEY_F9, mod, backlight_binding, + ec); + weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSDOWN, 0, + backlight_binding, ec); + weston_compositor_add_key_binding(ec, KEY_F10, mod, backlight_binding, + ec); + weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSUP, 0, + backlight_binding, ec); + weston_compositor_add_key_binding(ec, KEY_K, mod, + force_kill_binding, shell); + weston_compositor_add_key_binding(ec, KEY_UP, mod, + workspace_up_binding, shell); + weston_compositor_add_key_binding(ec, KEY_DOWN, mod, + workspace_down_binding, shell); + weston_compositor_add_key_binding(ec, KEY_UP, mod | MODIFIER_SHIFT, + workspace_move_surface_up_binding, + shell); + weston_compositor_add_key_binding(ec, KEY_DOWN, mod | MODIFIER_SHIFT, + workspace_move_surface_down_binding, + shell); + + /* Add bindings for mod+F[1-6] for workspace 1 to 6. */ + if (shell->workspaces.num > 1) { + num_workspace_bindings = shell->workspaces.num; + if (num_workspace_bindings > 6) + num_workspace_bindings = 6; + for (i = 0; i < num_workspace_bindings; i++) + weston_compositor_add_key_binding(ec, KEY_F1 + i, mod, + workspace_f_binding, + shell); + } + + /* Debug bindings */ + weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_SHIFT, + debug_binding, shell); } -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_set_layer: set(or change) surface layer - * - * @param[in] shsurf shell surface - * @param[in] layer layer id - * @return none - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ivi_shell_set_layer(struct shell_surface *shsurf, const int layer) +WL_EXPORT int +module_init(struct weston_compositor *ec, + int *argc, char *argv[]) { - struct ivi_shell *shell; - struct ivi_layer_list *el; - struct ivi_layer_list *new_el; + struct weston_seat *seat; + struct desktop_shell *shell; + struct workspace **pws; + unsigned int i; + struct wl_event_loop *loop; + + shell = malloc(sizeof *shell); + if (shell == NULL) + return -1; - uifw_trace("ivi_shell_set_layer: Enter([%08x],%08x,%d)", - (int)shsurf, (int)shsurf->surface, layer); + /* save shell management table for other plugin */ + _ico_ivi_shell = shell; - shell = shell_surface_get_shell(shsurf); + memset(shell, 0, sizeof *shell); + shell->compositor = ec; - /* check if same layer */ - if ((shsurf->layer_list != NULL) && (shsurf->layer_list->layer == layer)) { - uifw_trace("ivi_shell_set_layer: Leave(Same Layer)"); - return; - } + shell->destroy_listener.notify = shell_destroy; + wl_signal_add(&ec->destroy_signal, &shell->destroy_listener); + shell->idle_listener.notify = idle_handler; + wl_signal_add(&ec->idle_signal, &shell->idle_listener); + shell->wake_listener.notify = wake_handler; + wl_signal_add(&ec->wake_signal, &shell->wake_listener); + shell->show_input_panel_listener.notify = show_input_panels; + wl_signal_add(&ec->show_input_panel_signal, &shell->show_input_panel_listener); + shell->hide_input_panel_listener.notify = hide_input_panels; + wl_signal_add(&ec->hide_input_panel_signal, &shell->hide_input_panel_listener); + shell->update_input_panel_listener.notify = update_input_panels; + wl_signal_add(&ec->update_input_panel_signal, &shell->update_input_panel_listener); + ec->ping_handler = ping_handler; + ec->shell_interface.shell = shell; + ec->shell_interface.create_shell_surface = create_shell_surface; + ec->shell_interface.set_toplevel = set_toplevel; + ec->shell_interface.set_transient = set_transient; + ec->shell_interface.set_fullscreen = set_fullscreen; + ec->shell_interface.set_xwayland = set_xwayland; + ec->shell_interface.move = surface_move; + ec->shell_interface.resize = surface_resize; - /* search existing layer */ - wl_list_for_each (el, &shell->ivi_layer.link, link) { - if (el->layer == layer) break; - } + wl_list_init(&shell->input_panel.surfaces); - if (&el->link == &shell->ivi_layer.link) { - /* layer not exist, create new layer */ - uifw_trace("ivi_shell_set_layer: New Layer %d", layer); - new_el = malloc(sizeof(struct ivi_layer_list)); - if (! new_el) { - uifw_trace("ivi_shell_set_layer: Leave(No Memory)"); - return; - } + weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link); + weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link); + weston_layer_init(&shell->background_layer, &shell->panel_layer.link); + weston_layer_init(&shell->lock_layer, NULL); + weston_layer_init(&shell->input_panel_layer, NULL); - memset(new_el, 0, sizeof(struct ivi_layer_list)); - new_el->layer = layer; - new_el->visible = TRUE; - wl_list_init(&new_el->surface_list); - wl_list_init(&new_el->link); + wl_array_init(&shell->workspaces.array); + wl_list_init(&shell->workspaces.client_list); - wl_list_remove(&shsurf->ivi_layer); - wl_list_insert(&new_el->surface_list, &shsurf->ivi_layer); - shsurf->layer_list = new_el; + shell_configuration(shell); - wl_list_for_each (el, &shell->ivi_layer.link, link) { - if (layer >= el->layer) break; - } - if (&el->link == &shell->ivi_layer.link) { - wl_list_insert(shell->ivi_layer.link.prev, &new_el->link); - } - else { - wl_list_insert(el->link.prev, &new_el->link); - } - } - else { - uifw_trace("ivi_shell_set_layer: Add surface to Layer %d", layer); - wl_list_remove(&shsurf->ivi_layer); - wl_list_insert(&el->surface_list, &shsurf->ivi_layer); - shsurf->layer_list = el; + for (i = 0; i < shell->workspaces.num; i++) { + pws = wl_array_add(&shell->workspaces.array, sizeof *pws); + if (pws == NULL) + return -1; + + *pws = workspace_create(); + if (*pws == NULL) + return -1; } + activate_workspace(shell, 0); - /* rebild compositor surface list */ - ivi_shell_restack_ivi_layer(shell, shsurf); + wl_list_init(&shell->workspaces.anim_sticky_list); + wl_list_init(&shell->workspaces.animation.link); + shell->workspaces.animation.frame = animate_workspace_change_frame; - uifw_trace("ivi_shell_set_layer: Leave"); -} + if (wl_global_create(ec->wl_display, &wl_shell_interface, 1, + shell, bind_shell) == NULL) + return -1; -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_set_raise: surface stack control - * - * @param[in] shsurf shell surface - * @param[in] raise raise/lower(1=raise/0=lower) - * @return none - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ivi_shell_set_raise(struct shell_surface *shsurf, const int raise) -{ - uifw_trace("ivi_shell_set_raise: Enter(%08x,%d) layer_list=%08x", - (int)shsurf->surface, raise, (int)shsurf->layer_list); + if (wl_global_create(ec->wl_display, + &desktop_shell_interface, 2, + shell, bind_desktop_shell) == NULL) + return -1; - wl_list_remove(&shsurf->ivi_layer); - if (raise) { - /* raise ... surface stack to top of layer */ - wl_list_insert(&shsurf->layer_list->surface_list, &shsurf->ivi_layer); - uifw_trace("ivi_shell_set_raise: Raise Link to Top"); - } - else { - /* Lower ... surface stack to bottom of layer */ - wl_list_insert(shsurf->layer_list->surface_list.prev, &shsurf->ivi_layer); - uifw_trace("ivi_shell_set_raise: Lower Link to Bottom"); - } + if (wl_global_create(ec->wl_display, &screensaver_interface, 1, + shell, bind_screensaver) == NULL) + return -1; - /* rebild compositor surface list */ - ivi_shell_restack_ivi_layer(shell_surface_get_shell(shsurf), shsurf); + if (wl_global_create(ec->wl_display, &wl_input_panel_interface, 1, + shell, bind_input_panel) == NULL) + return -1; - uifw_trace("ivi_shell_set_raise: Leave"); -} + if (wl_global_create(ec->wl_display, &workspace_manager_interface, 1, + shell, bind_workspace_manager) == NULL) + return -1; -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_set_toplevel: set surface type toplevel - * - * @param[in] shsurf shell surface - * @return none - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ivi_shell_set_toplevel(struct shell_surface *shsurf) -{ - uifw_trace("ivi_shell_set_toplevel: (%08x)", (int)shsurf->surface); - set_toplevel(shsurf); + shell->child.deathstamp = weston_compositor_get_time(); + + loop = wl_display_get_event_loop(ec->wl_display); + wl_event_loop_add_idle(loop, launch_desktop_shell_process, shell); + + shell->screensaver.timer = + wl_event_loop_add_timer(loop, screensaver_timeout, shell); + + wl_list_for_each(seat, &ec->seat_list, link) + create_pointer_focus_listener(seat); + + shell_add_bindings(ec, shell); + + shell_fade_init(shell); + + return 0; } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_set_surface_type: set surface type + * @brief ico_ivi_shell_current_layer: get current weston layer * - * @param[in] shsurf shell surface - * @return none + * @param none + * @return current weston layer + * @retval !=NULL success(current weston layer) + * @retval ==NULL error(no layer) */ /*--------------------------------------------------------------------------*/ -WL_EXPORT void -ivi_shell_set_surface_type(struct shell_surface *shsurf) +/* API for other plugin */ +WL_EXPORT struct weston_layer * +ico_ivi_shell_current_layer(void) { - uifw_trace("ivi_shell_set_surfacetype: (%08x)", (int)shsurf->surface); - set_surface_type(shsurf); + struct workspace *ws = get_current_workspace(_ico_ivi_shell); + + return (ws != NULL) ? &ws->layer : NULL; } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_send_configure: send surface resize event + * @brief ico_ivi_shell_set_toplevel: set surface to TopLevel * - * @param[in] shsurf shell surface - * @param[in] id client object id(unused) - * @param[in] edges surface resize position - * @param[in] width surface width - * @param[in] height surface height + * @param[in] shsurf shell surface * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ivi_shell_send_configure(struct shell_surface *shsurf, const int id, - const int edges, const int width, const int height) +ico_ivi_shell_set_toplevel(struct shell_surface *shsurf) { - /* send cgange event to manager */ - uifw_trace("ivi_shell_send_configure: (%08x) edges=%x w/h=%d/%d map=%d", - (int)shsurf->surface, edges, width, height, shsurf->mapped); - - shsurf->geometry_width = width; - shsurf->geometry_height = height; - - if ((shsurf->mapped == 0) || (shsurf->noconfigure != 0) || - (width == 0) || (height == 0)) { - return; - } - - /* send cgange event to application */ - uifw_trace("ivi_shell_send_configure: Send (%08x) w/h=%d/%d(old=%d/%d)", - (int)shsurf->surface, width, height, - shsurf->configure_app.width, shsurf->configure_app.height); - shsurf->configure_app.width = width; - shsurf->configure_app.height = height; - - wl_shell_surface_send_configure(&shsurf->resource, - WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, - width, height); + set_toplevel(shsurf); } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_get_positionsize: get surface position and size + * @brief ico_ivi_shell_set_surface_type: set surface type * * @param[in] shsurf shell surface - * @param[out] x surface upper-left X position on screen - * @param[out] y surface upper-left Y position on screen - * @param[out] width surface width - * @param[out] height surface height * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ivi_shell_get_positionsize(struct shell_surface *shsurf, - int *x, int *y, int *width, int *height) +ico_ivi_shell_set_surface_type(struct shell_surface *shsurf) { - *x = shsurf->geometry_x; - *y = shsurf->geometry_y; - *width = shsurf->geometry_width; - *height = shsurf->geometry_height; + set_surface_type(shsurf); } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_set_positionsize: set surface position and size + * @brief ico_ivi_shell_send_configure: send configure event to client application * - * @param[in] shsurf shell surface - * @param[in] x surface upper-left X position on screen - * @param[in] y surface upper-left Y position on screen + * @param[in] surface weston surface + * @param[in] edges surface resize position * @param[in] width surface width * @param[in] height surface height * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ivi_shell_set_positionsize(struct shell_surface *shsurf, - const int x, const int y, const int width, const int height) +ico_ivi_shell_send_configure(struct weston_surface *surface, + const uint32_t edges, const int width, const int height) { - shsurf->geometry_x = x; - shsurf->geometry_y = y; - shsurf->geometry_width = width; - shsurf->geometry_height = height; - - weston_compositor_schedule_repaint(shell_surface_get_shell(shsurf)->compositor); + send_configure(surface, edges, width, height); } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_set_layer_visible: layer visible control + * @brief ico_ivi_shell_startup: start shell surface fade * - * @param[in] layer layer id - * @param[in] visible visibility(1=visible/0=unvisible) + * @param[in] shell shell table address * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ivi_shell_set_layer_visible(const int layer, const int visible) +ico_ivi_shell_startup(void *shell) { - struct ivi_shell *shell; - struct ivi_layer_list *el; - struct ivi_layer_list *new_el; - struct shell_surface *es; - - uifw_trace("ivi_shell_set_layer_visible: Enter(layer=%d, visible=%d)", layer, visible); - - shell = shell_surface_get_shell(NULL); - - /* Search Layer */ - wl_list_for_each (el, &shell->ivi_layer.link, link) { - if (el->layer == layer) break; - } - - if (&el->link == &shell->ivi_layer.link) { - /* layer not exist, create new layer */ - uifw_trace("ivi_shell_set_layer_visible: New Layer %d", layer); - new_el = malloc(sizeof(struct ivi_layer_list)); - if (! new_el) { - uifw_trace("ivi_shell_set_layer_visible: Leave(No Memory)"); - return; - } - - memset(new_el, 0, sizeof(struct ivi_layer_list)); - new_el->layer = layer; - new_el->visible = TRUE; - wl_list_init(&new_el->surface_list); - wl_list_init(&new_el->link); - - wl_list_for_each (el, &shell->ivi_layer.link, link) { - if (layer >= el->layer) break; - } - if (&el->link == &shell->ivi_layer.link) { - wl_list_insert(shell->ivi_layer.link.prev, &new_el->link); - } - else { - wl_list_insert(el->link.prev, &new_el->link); - } - uifw_trace("ivi_shell_set_layer_visible: Leave(new layer)"); - return; - } - - /* control all surface in layer */ - if ((el->visible != FALSE) && (visible == 0)) { - /* layer change to NOT visible */ - uifw_trace("ivi_shell_set_layer_visible: change to not visible"); - el->visible = FALSE; - } - else if ((el->visible == FALSE) && (visible != 0)) { - /* layer change to visible */ - uifw_trace("ivi_shell_set_layer_visible: change to visible"); - el->visible = TRUE; - } - else { - /* no change */ - uifw_trace("ivi_shell_set_layer_visible: Leave(no Change %d=>%d)", - el->visible, visible); - return; - } - - /* set damege area */ - wl_list_for_each (es, &el->surface_list, ivi_layer) { - if ((es->visible != FALSE) && - (es->surface->output != NULL) && - (es->surface->shader != NULL)) { - /* Damage(redraw) target surface */ - weston_surface_damage_below(es->surface); - } - } - - /* rebild compositor surface list */ - ivi_shell_restack_ivi_layer(shell, NULL); - - uifw_trace("ivi_shell_set_layer_visible: Leave"); -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ivi_shell_surface_configure: surface change - * - * @param[in] shsurf shell surface - * @param[in] x surface upper-left X position on screen - * @param[in] y surface upper-left Y position on screen - * @param[in] width surface width - * @param[in] height surface height - * @return none - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ivi_shell_surface_configure(struct shell_surface *shsurf, const int x, - const int y, const int width, const int height) -{ - int set_unvisible = 0; - - if (ico_option_flag() & ICO_OPTION_FLAG_UNVISIBLE) { - if ((shsurf->surface != NULL) && (shsurf->surface->buffer != NULL) && - (shsurf->surface->output != NULL) && (shsurf->surface->shader != NULL)) { - if ((shsurf->visible == FALSE) || - ((shsurf->layer_list != NULL) && - (shsurf->layer_list->visible == FALSE))) { - set_unvisible = 1; - } - } - } - if (set_unvisible) { - uifw_trace("ivi_shell_surface_configure: %08x %d,%d(%d/%d) unvisible", - (int)shsurf, x, y, width, height); - weston_surface_configure(shsurf->surface, - ICO_IVI_MAX_COORDINATE+1, ICO_IVI_MAX_COORDINATE+1, - width, height); - } - else { - uifw_trace("ivi_shell_surface_configure: %08x %d,%d(%d/%d) visible", - (int)shsurf, x, y, width, height); - weston_surface_configure(shsurf->surface, x, y, width, height); - } + shell_fade_startup((struct desktop_shell *)shell); } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_hook_bind: regist hook function for shell bind + * @brief ico_ivi_shell_hook_bind: regist hook function for shell bind * * @param[in] hook_bind hook function(if NULL, reset hook function) * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ivi_shell_hook_bind(void (*hook_bind)(struct wl_client *client)) +ico_ivi_shell_hook_bind(void (*hook_bind)(struct wl_client *client, void *shell)) { - uifw_trace("ivi_shell_hook_bind: Hook %08x", (int)hook_bind); shell_hook_bind = hook_bind; } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_hook_unbind: regist hook function for shell unbind + * @brief ico_ivi_shell_hook_unbind: regist hook function for shell unbind * * @param[in] hook_unbind hook function(if NULL, reset hook function) * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ivi_shell_hook_unbind(void (*hook_unbind)(struct wl_client *client)) +ico_ivi_shell_hook_unbind(void (*hook_unbind)(struct wl_client *client)) { - uifw_trace("ivi_shell_hook_unbind: Hook %08x", (int)hook_unbind); shell_hook_unbind = hook_unbind; } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_hook_create: regist hook function for create shell surface + * @brief ico_ivi_shell_hook_create: regist hook function for create shell surface * * @param[in] hook_create hook function(if NULL, reset hook function) * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ivi_shell_hook_create(void (*hook_create)(struct wl_client *client, - struct wl_resource *resource, struct weston_surface *surface, - struct shell_surface *shsurf)) +ico_ivi_shell_hook_create(void (*hook_create)(struct wl_client *client, + struct wl_resource *resource, + struct weston_surface *surface, + struct shell_surface *shsurf)) { - uifw_trace("ivi_shell_hook_create: Hook %08x", (int)hook_create); shell_hook_create = hook_create; } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_hook_destroy: regist hook function for destroy shell surface + * @brief ico_ivi_shell_hook_destroy: regist hook function for destroy shell surface * * @param[in] hook_destroy hook function(if NULL, reset hook function) * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ivi_shell_hook_destroy(void (*hook_destroy)(struct weston_surface *surface)) +ico_ivi_shell_hook_destroy(void (*hook_destroy)(struct weston_surface *surface)) { - uifw_trace("ivi_shell_hook_destroy: Hook %08x", (int)hook_destroy); shell_hook_destroy = hook_destroy; } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_hook_map: regist hook function for map shell surface + * @brief ico_ivi_shell_hook_map: regist hook function for map shell surface * * @param[in] hook_map hook function(if NULL, reset hook function) * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ivi_shell_hook_map(void (*hook_map)(struct weston_surface *surface, - int32_t *width, int32_t *height, int32_t *sx, int32_t *sy)) +ico_ivi_shell_hook_map(void (*hook_map)(struct weston_surface *surface, + int32_t *width, int32_t *height, + int32_t *sx, int32_t *sy)) { - uifw_trace("ivi_shell_hook_map: Hook %08x", (int)hook_map); shell_hook_map = hook_map; } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_hook_change: regist hook function for change shell surface + * @brief ico_ivi_shell_hook_change: regist hook function for change shell surface * * @param[in] hook_change hook function(if NULL, reset hook function) * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ivi_shell_hook_change(void (*hook_change)(struct weston_surface *surface, - const int to, const int manager)) +ico_ivi_shell_hook_change(void (*hook_change)(struct weston_surface *surface, + const int to, const int manager)) { - uifw_trace("ivi_shell_hook_change: Hook %08x", (int)hook_change); shell_hook_change = hook_change; } /*--------------------------------------------------------------------------*/ /** - * @brief ivi_shell_hook_select: regist hook function for select(active) shell surface + * @brief ico_ivi_shell_hook_select: regist hook function for select(active) shell surface * * @param[in] hook_select hook function(if NULL, reset hook function) * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ivi_shell_hook_select(void (*hook_select)(struct weston_surface *surface)) +ico_ivi_shell_hook_select(void (*hook_select)(struct weston_surface *surface)) { - uifw_trace("ivi_shell_hook_select: Hook %08x", (int)hook_select); shell_hook_select = hook_select; } /*--------------------------------------------------------------------------*/ /** - * @brief module_init: initialize ico_ivi_shell - * this function called from ico_pluign_loader + * @brief ico_ivi_shell_hook_title: regist hook function for select(active) shell surface * - * @param[in] es weston compositor - * @return result - * @retval 0 sccess - * @retval -1 error + * @param[in] hook_title hook function(if NULL, reset hook function) + * @return none */ /*--------------------------------------------------------------------------*/ -WL_EXPORT int -module_init(struct weston_compositor *ec) +WL_EXPORT void +ico_ivi_shell_hook_title(void (*hook_title)(struct weston_surface *surface, + const char *title)) { - struct ivi_shell *shell; - - uifw_info("ico_ivi_shell: Enter(module_init)"); - - shell = malloc(sizeof *shell); - if (shell == NULL) return -1; - default_shell = shell; - - memset(shell, 0, sizeof *shell); - shell->compositor = ec; - - shell->destroy_listener.notify = shell_destroy; - wl_signal_add(&ec->destroy_signal, &shell->destroy_listener); - ec->shell_interface.shell = shell; - ec->shell_interface.create_shell_surface = create_shell_surface; - ec->shell_interface.set_toplevel = set_toplevel; - ec->shell_interface.set_transient = set_transient; - - wl_list_init(&shell->ivi_layer.link); - weston_layer_init(&shell->surface, &ec->cursor_layer.link); - - uifw_trace("ico_ivi_shell: shell(%08x) ivi_layer.link.%08x=%08x/%08x", - (int)shell, (int)&shell->ivi_layer.link, - (int)shell->ivi_layer.link.next, (int)shell->ivi_layer.link.prev); - - shell_configuration(shell); - - if (wl_display_add_global(ec->wl_display, &wl_shell_interface, shell, bind_shell) - == NULL) { - return -1; - } - if (wl_display_add_global(ec->wl_display, &ico_ivi_shell_interface, - shell, bind_ivi_shell) == NULL) { - return -1; - } - - weston_compositor_add_button_binding(ec, BTN_LEFT, 0, - click_to_activate_binding, shell); + shell_hook_title = hook_title; +} - uifw_info("ico_ivi_shell: Leave(module_init)"); - return 0; +/*--------------------------------------------------------------------------*/ +/** + * @brief ico_ivi_shell_hook_move: regist hook function for move grab + * + * @param[in] hook_move hook function(if NULL, reset hook function) + * @param[in/out] dx new X coordinate + * @param[in/out] dy new Y coordinate + * @return none + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT void +ico_ivi_shell_hook_move(void (*hook_move)(struct weston_surface *surface, int *dx, int *dy)) +{ + shell_hook_move = hook_move; } diff --git a/src/ico_ivi_shell.h b/src/ico_ivi_shell.h index de629fe..f4698b0 100644 --- a/src/ico_ivi_shell.h +++ b/src/ico_ivi_shell.h @@ -24,7 +24,7 @@ /** * @brief Public functions in ico_ivi_shell Weston plugin * - * @date Feb-08-2013 + * @date Jul-26-2013 */ #ifndef _ICO_IVI_SHELL_H_ @@ -32,55 +32,30 @@ struct shell_surface; -/* max length */ -#define ICO_WINDOW_ANIMATION_LEN 20 /* length of window animation name */ -/* option flag */ -#define ICO_OPTION_FLAG_UNVISIBLE 0x00000001 /* unvisible control */ -/* client attribute */ -#define ICO_CLEINT_ATTR_NOCONFIGURE 0 /* client no need configure event */ - /* Prototype for get/set function */ -void ivi_shell_set_layer(struct shell_surface *shsurf, const int layer); -bool ivi_shell_is_visible(struct shell_surface *shsurf); -void ivi_shell_set_visible(struct shell_surface *shsurf, const int visible); -void ivi_shell_set_raise(struct shell_surface *shsurf, const int raise); -void ivi_shell_set_toplevel(struct shell_surface *shsurf); -void ivi_shell_set_surface_type(struct shell_surface *shsurf); -void ivi_shell_send_configure(struct shell_surface *shsurf, const int id, - const int edges, const int width, const int height); -void ivi_shell_get_positionsize(struct shell_surface *shsurf, int *x, - int *y, int *width, int *height); -void ivi_shell_set_positionsize(struct shell_surface *shsurf, const int x, - const int y, const int width, const int height); -void ivi_shell_set_layer_visible(const int layer, const int visible); -void ivi_shell_surface_configure(struct shell_surface *shsurf, const int x, - const int y, const int width, const int height); -void ivi_shell_set_active(struct shell_surface *shsurf, const int target); -void ivi_shell_set_client_attr(struct wl_client *client, const int attr, const int value); -void ivi_shell_restrain_configure(struct shell_surface *shsurf, const int restrain); -int ivi_shell_is_restrain(struct shell_surface *shsurf); -const char *ivi_shell_default_animation(int *msec, int *fps); +struct weston_layer *ico_ivi_shell_current_layer(void); +void ico_ivi_shell_set_toplevel(struct shell_surface *shsurf); +void ico_ivi_shell_set_surface_type(struct shell_surface *shsurf); +void ico_ivi_shell_send_configure(struct weston_surface *surface, + const uint32_t edges, const int width, const int height); +void ico_ivi_shell_startup(void *shell); /* Prototypr for hook routine */ -void ivi_shell_hook_bind(void (*hook_bind)(struct wl_client *client)); -void ivi_shell_hook_unbind(void (*hook_unbind)(struct wl_client *client)); -void ivi_shell_hook_create(void (*hook_create)(struct wl_client *client, +void ico_ivi_shell_hook_bind(void (*hook_bind)(struct wl_client *client, void *shell)); +void ico_ivi_shell_hook_unbind(void (*hook_unbind)(struct wl_client *client)); +void ico_ivi_shell_hook_create(void (*hook_create)(struct wl_client *client, struct wl_resource *resource, struct weston_surface *surface, struct shell_surface *shsurf)); -void ivi_shell_hook_destroy(void (*hook_destroy)(struct weston_surface *surface)); -void ivi_shell_hook_map(void (*hook_map)(struct weston_surface *surface, +void ico_ivi_shell_hook_destroy(void (*hook_destroy)(struct weston_surface *surface)); +void ico_ivi_shell_hook_map(void (*hook_map)(struct weston_surface *surface, int32_t *width, int32_t *height, int32_t *sx, int32_t *sy)); -void ivi_shell_hook_change(void (*hook_change)(struct weston_surface *surface, +void ico_ivi_shell_hook_change(void (*hook_change)(struct weston_surface *surface, const int to, const int manager)); -void ivi_shell_hook_select(void (*hook_select)(struct weston_surface *surface)); - -/* Prototype for hook of Multi Input Manager */ -void ico_win_mgr_hook_set_user(void (*hook_set_user)(struct wl_client *client, - const char *appid)); -void ico_win_mgr_hook_create(void (*hook_create)(struct wl_client *client, - struct weston_surface *surface, - int surfaceId, - const char *appid)); -void ico_win_mgr_hook_destroy(void (*hook_destroy)(struct weston_surface *surface)); +void ico_ivi_shell_hook_select(void (*hook_select)(struct weston_surface *surface)); +void ico_ivi_shell_hook_title(void (*hook_title)(struct weston_surface *surface, + const char *title)); +void ico_ivi_shell_hook_move(void (*hook_move)(struct weston_surface *surface, + int *dx, int *dy)); #endif /*_ICO_IVI_SHELL_H_*/ + diff --git a/src/ico_plugin_loader.c b/src/ico_plugin_loader.c index 5f3ac61..e9ce14f 100644 --- a/src/ico_plugin_loader.c +++ b/src/ico_plugin_loader.c @@ -26,7 +26,7 @@ * @brief Load the Weston plugins, because plugin loader of main body of Weston * @brief cannot use other plugin functions by a other plugin. * - * @date Feb-08-2013 + * @date Jul-26-2013 */ #define _GNU_SOURCE @@ -41,37 +41,16 @@ #include #include +#include #include "ico_ivi_common.h" -/* This function is called from the main body of Weston and initializes this module.*/ -int module_init(struct weston_compositor *ec); - /* Internal function to load one plugin. */ -static void load_module(struct weston_compositor *ec, const char *path, const char *entry); +static void load_module(struct weston_compositor *ec, const char *path, const char *entry, + int *argc, char *argv[]); /* Static valiables */ -static char *moddir = NULL; /* Answer back from configuration */ -static char *modules = NULL; /* Answer back from configuration */ static int debug_level = 3; /* Debug Level */ -/* Configuration key */ -static const struct config_key plugin_config_keys[] = { - { "moddir", CONFIG_KEY_STRING, &moddir }, - { "modules", CONFIG_KEY_STRING, &modules }, - }; - -static const struct config_section conf_plugin[] = { - { "plugin", plugin_config_keys, ARRAY_LENGTH(plugin_config_keys) }, - }; - -static const struct config_key debug_config_keys[] = { - { "ivi_debug", CONFIG_KEY_INTEGER, &debug_level }, - }; - -static const struct config_section conf_debug[] = { - { "debug", debug_config_keys, ARRAY_LENGTH(debug_config_keys) }, - }; - /*--------------------------------------------------------------------------*/ /** @@ -81,8 +60,9 @@ static const struct config_section conf_debug[] = { * @return debug output level * @retval 0 No debug output * @retval 1 Only error output - * @retval 2 Error and information output - * @retval 3 All output with debug write + * @retval 2 Error and Warning output + * @retval 3 Error, Warning and information output + * @retval 4 All output with debug write */ /*--------------------------------------------------------------------------*/ int @@ -96,16 +76,19 @@ ico_ivi_debuglevel(void) * @brief load_module: load one plugin module. * * @param[in] ec weston compositor. (from weston) - * @param[in] path file path of plugin module. - * @param[in] entry entry function name of plugin module. + * @param[in] path file path of locading plugin module. + * @param[in] entry entry function name of locading plugin module. + * @param[in] argc number of arguments. + * @param[in] argv arguments list. * @return none */ /*--------------------------------------------------------------------------*/ static void -load_module(struct weston_compositor *ec, const char *path, const char *entry) +load_module(struct weston_compositor *ec, const char *path, const char *entry, + int *argc, char *argv[]) { void *module; /* module informations (dlopen) */ - int (*init)(struct weston_compositor *ec); + int (*init)(struct weston_compositor *ec, int *argc, char *argv[]); /* enter function of loaded plugin */ uifw_info("ico_plugin_loader: Load(path=%s entry=%s)", path, entry); @@ -141,7 +124,7 @@ load_module(struct weston_compositor *ec, const char *path, const char *entry) else { /* call initialize function */ uifw_trace("ico_plugin_loader: Call %s:%s(%08x)", path, entry, (int)init); - init(ec); + init(ec, argc, argv); uifw_info("ico_plugin_loader: %s Loaded", path); } } @@ -153,32 +136,48 @@ load_module(struct weston_compositor *ec, const char *path, const char *entry) * called from weston compositor. * * @param[in] ec weston compositor(from weston) + * @param[in] argc number of arguments(unused) + * @param[in] argv argument list(unused) * @return result * @retval 0 sccess * @retval -1 error */ /*--------------------------------------------------------------------------*/ WL_EXPORT int -module_init(struct weston_compositor *ec) +module_init(struct weston_compositor *ec, int *argc, char *argv[]) { - int config_fd; + struct weston_config_section *section; + char *moddir = NULL; /* Answer back from configuration */ + char *modules = NULL; /* Answer back from configuration */ char *p; char *end; char buffer[256]; uifw_info("ico_plugin_loader: Enter(module_init)"); + /* get ivi debug level */ + section = weston_config_get_section(ec->config, "ivi-debug", NULL, NULL); + if (section) { + weston_config_section_get_int(section, "log", &debug_level, 3); + } + /* get plugin module name from config file(weston_ivi_plugin.ini) */ - config_fd = open_config_file(ICO_IVI_PLUGIN_CONFIG); - parse_config_file(config_fd, conf_plugin, ARRAY_LENGTH(conf_plugin), NULL); - parse_config_file(config_fd, conf_debug, ARRAY_LENGTH(conf_debug), NULL); - close(config_fd); + section = weston_config_get_section(ec->config, "ivi-plugin", NULL, NULL); + if (section) { + weston_config_section_get_string(section, "moddir", &moddir, NULL); + weston_config_section_get_string(section, "modules", &modules, NULL); + } if (modules == NULL) { uifw_error("ico_plugin_loader: Leave(No Plugin in config)"); + if (moddir) free(moddir); return -1; } - moddir = getenv("WESTON_IVI_PLUGIN_DIR"); + p = getenv("WESTON_IVI_PLUGIN_DIR"); + if (p) { + if (moddir) free(moddir); + moddir = strdup(p); + } p = modules; while (*p) { @@ -192,13 +191,14 @@ module_init(struct weston_compositor *ec) else { snprintf(buffer, sizeof(buffer), "%s/%.*s", MODULEDIR, (int) (end - p), p); } - load_module(ec, buffer, "module_init"); + load_module(ec, buffer, "module_init", argc, argv); p = end; while (*p == ',') { p++; } } - + if (moddir) free(moddir); + free(modules); uifw_info("ico_plugin_loader: Leave(module_init)"); return 0; diff --git a/src/ico_window_animation.c b/src/ico_window_animation.c index 8e27a69..7dc53de 100644 --- a/src/ico_window_animation.c +++ b/src/ico_window_animation.c @@ -24,7 +24,7 @@ /** * @brief Window Animation (Weston(Wayland) PlugIn) * - * @date May-29-2013 + * @date Jul-26-2013 */ #include @@ -63,7 +63,7 @@ struct animation_data { int y; /* original Y coordinate */ int width; /* original width */ int height; /* original height */ - char geometry_saved; /* need geometry restor at end */ + char geometry_saved; /* need geometry restore at end */ char transform_set; /* need transform reset at end */ char res[2]; /* (unused) */ struct weston_transform transform; /* transform matrix */ @@ -114,31 +114,32 @@ ico_window_animation(const int op, void *data) uint32_t nowsec; struct timeval nowtv; int time; + int name; - if (op == ICO_WINDOW_MGR_ANIMATION_TYPE) { + if (op == ICO_WINDOW_MGR_ANIMATION_NAME) { /* convert animation name to animation type value */ if (strcasecmp((char *)data, "fade") == 0) { - uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_FADE); + uifw_trace("ico_window_animation: Type %s(%d)", (char *)data, ANIMA_FADE); return ANIMA_FADE; } else if (strcasecmp((char *)data, "zoom") == 0) { - uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_ZOOM); + uifw_trace("ico_window_animation: Type %s(%d)", (char *)data, ANIMA_ZOOM); return ANIMA_ZOOM; } else if (strcasecmp((char *)data, "slide.toleft") == 0) { - uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TOLEFT); + uifw_trace("ico_window_animation: Type %s(%d)", (char *)data, ANIMA_SLIDE_TOLEFT); return ANIMA_SLIDE_TOLEFT; } else if (strcasecmp((char *)data, "slide.toright") == 0) { - uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TORIGHT); + uifw_trace("ico_window_animation: Type %s(%d)", (char *)data, ANIMA_SLIDE_TORIGHT); return ANIMA_SLIDE_TORIGHT; } else if (strcasecmp((char *)data, "slide.totop") == 0) { - uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TOTOP); + uifw_trace("ico_window_animation: Type %s(%d)", (char *)data, ANIMA_SLIDE_TOTOP); return ANIMA_SLIDE_TOTOP; } else if (strcasecmp((char *)data, "slide.tobottom") == 0) { - uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TOBOTTOM); + uifw_trace("ico_window_animation: Type %s(%d)", (char *)data, ANIMA_SLIDE_TOBOTTOM); return ANIMA_SLIDE_TOBOTTOM; } uifw_warn("ico_window_animation: Unknown Type %s", (char *)data); @@ -149,18 +150,19 @@ ico_window_animation(const int op, void *data) if (op == ICO_WINDOW_MGR_ANIMATION_DESTROY) { if ((usurf->animation.state != ICO_WINDOW_MGR_ANIMATION_STATE_NONE) || - (usurf->animadata != NULL)) { + (usurf->animation.animadata != NULL)) { uifw_trace("ico_window_animation: Destroy %08x", (int)usurf); animation_end(usurf, 0); } return ICO_WINDOW_MGR_ANIMATION_RET_NOANIMA; } + if (op == ICO_WINDOW_MGR_ANIMATION_OPCANCEL) { /* cancel animation */ if ((usurf->animation.state != ICO_WINDOW_MGR_ANIMATION_STATE_NONE) && (usurf->animation.animation.frame != NULL)) { uifw_trace("ico_window_animation: cancel %s.%08x", - usurf->uclient->appid, usurf->id); + usurf->uclient->appid, usurf->surfaceid); (*usurf->animation.animation.frame)(&usurf->animation.animation, NULL, 0); } animation_end(usurf, 1); @@ -180,15 +182,22 @@ ico_window_animation(const int op, void *data) &usurf->animation.animation.link); } } - else if (((usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) && - (op == ICO_WINDOW_MGR_ANIMATION_OPOUT)) || - ((usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_OUT) && - (op == ICO_WINDOW_MGR_ANIMATION_OPIN))) { + else if (((usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_SHOW) && + (op == ICO_WINDOW_MGR_ANIMATION_OPHIDE)) || + ((usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_HIDE) && + (op == ICO_WINDOW_MGR_ANIMATION_OPSHOW))) { + /* change ...In(ex.FadeIn) to ...Out(FadeOut) or ...Out to ...In */ gettimeofday(&nowtv, NULL); nowsec = (uint32_t)(((long long)nowtv.tv_sec) * 1000L + ((long long)nowtv.tv_usec) / 1000L); usurf->animation.current = 100 - usurf->animation.current; - time = (usurf->animation.time > 0) ? usurf->animation.time : animation_time; + if (op == ICO_WINDOW_MGR_ANIMATION_OPHIDE) { + time = usurf->animation.hide_time; + } + else { + time = usurf->animation.show_time; + } + time = (time > 0) ? time : animation_time; ret = ((usurf->animation.current) * time) / 100; if (nowsec >= (uint32_t)ret) { usurf->animation.starttime = nowsec - ret; @@ -201,27 +210,45 @@ ico_window_animation(const int op, void *data) } /* set animation function */ - if (op == ICO_WINDOW_MGR_ANIMATION_OPIN) { - usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_IN; - uifw_trace("ico_window_animation: show(in) %s.%08x", - usurf->uclient->appid, usurf->id); + if (op == ICO_WINDOW_MGR_ANIMATION_OPSHOW) { + usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_SHOW; + name = usurf->animation.show_name; + usurf->animation.name = name; + uifw_trace("ico_window_animation: show(in) %s.%08x anima=%d", + usurf->uclient->appid, usurf->surfaceid, name); ret = ICO_WINDOW_MGR_ANIMATION_RET_ANIMA; } - else { - usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_OUT; - uifw_trace("ico_window_animation: hide(out) %s.%08x", - usurf->uclient->appid, usurf->id); + else if (op == ICO_WINDOW_MGR_ANIMATION_OPHIDE) { + usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_HIDE; + name = usurf->animation.hide_name; + usurf->animation.name = name; + uifw_trace("ico_window_animation: hide(out) %s.%08x anima=%d", + usurf->uclient->appid, usurf->surfaceid, name); ret = ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW; } - if ((usurf->animation.type == ANIMA_SLIDE_TOLEFT) || - (usurf->animation.type == ANIMA_SLIDE_TORIGHT) || - (usurf->animation.type == ANIMA_SLIDE_TOTOP) || - (usurf->animation.type == ANIMA_SLIDE_TOBOTTOM)) { + else if (op == ICO_WINDOW_MGR_ANIMATION_OPMOVE) { + usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_MOVE; + name = usurf->animation.move_name; + usurf->animation.name = name; + uifw_trace("ico_window_animation: move %s.%08x anima=%d", + usurf->uclient->appid, usurf->surfaceid, name); + ret = ICO_WINDOW_MGR_ANIMATION_RET_ANIMA; + } + else { + usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_RESIZE; + name = usurf->animation.resize_name; + usurf->animation.name = name; + uifw_trace("ico_window_animation: resize %s.%08x anima=%d", + usurf->uclient->appid, usurf->surfaceid, name); + ret = ICO_WINDOW_MGR_ANIMATION_RET_ANIMA; + } + if ((name == ANIMA_SLIDE_TOLEFT) || (name == ANIMA_SLIDE_TORIGHT) || + (name == ANIMA_SLIDE_TOTOP) || (name == ANIMA_SLIDE_TOBOTTOM)) { usurf->animation.animation.frame = animation_slide; - ivi_shell_restrain_configure(usurf->shsurf, 1); + usurf->restrain_configure = 1; (*usurf->animation.animation.frame)(&usurf->animation.animation, NULL, 1); } - else if (usurf->animation.type == ANIMA_FADE) { + else if (name == ANIMA_FADE) { usurf->animation.animation.frame = animation_fade; (*usurf->animation.animation.frame)(&usurf->animation.animation, NULL, 1); } @@ -229,10 +256,12 @@ ico_window_animation(const int op, void *data) /* no yet support */ usurf->animation.animation.frame = NULL; usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_NONE; - ivi_shell_restrain_configure(usurf->shsurf, 0); + usurf->restrain_configure = 0; + usurf->animation.name = 0; wl_list_remove(&usurf->animation.animation.link); ret = ICO_WINDOW_MGR_ANIMATION_RET_NOANIMA; } + usurf->animation.type = op; } if (ret == ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW) { usurf->animation.visible = ANIMA_HIDE_AT_END; @@ -278,24 +307,24 @@ animation_cont(struct weston_animation *animation, struct weston_output *output, animation->frame_counter = 1; usurf->animation.starttime = nowsec; usurf->animation.current = 1000; - if (! usurf->animadata) { + if (! usurf->animation.animadata) { if (free_data) { - usurf->animadata = (void *)free_data; + usurf->animation.animadata = (void *)free_data; free_data = free_data->next_free; } else { - usurf->animadata = (void *)malloc(sizeof(struct animation_data)); + usurf->animation.animadata = (void *)malloc(sizeof(struct animation_data)); } - memset(usurf->animadata, 0, sizeof(struct animation_data)); + memset(usurf->animation.animadata, 0, sizeof(struct animation_data)); } - animadata = (struct animation_data *)usurf->animadata; + animadata = (struct animation_data *)usurf->animation.animadata; animadata->x = usurf->x; animadata->y = usurf->y; animadata->width = usurf->width; animadata->height = usurf->height; animadata->geometry_saved = 1; } - else if (! usurf->animadata) { + else if (! usurf->animation.animadata) { animation_end(usurf, 0); return 999; } @@ -307,7 +336,21 @@ animation_cont(struct weston_animation *animation, struct weston_output *output, nowsec = (uint32_t)(((long long)0x100000000L) + ((long long)nowsec) - ((long long)usurf->animation.starttime)); } - time = (usurf->animation.time > 0) ? usurf->animation.time : animation_time; + switch (usurf->animation.state) { + case ICO_WINDOW_MGR_ANIMATION_STATE_SHOW: + time = usurf->animation.show_time; + break; + case ICO_WINDOW_MGR_ANIMATION_STATE_HIDE: + time = usurf->animation.hide_time; + break; + case ICO_WINDOW_MGR_ANIMATION_STATE_MOVE: + time = usurf->animation.move_time; + break; + default: + time = usurf->animation.resize_time; + break; + } + time = (time > 0) ? time : animation_time; if (((output == NULL) && (msecs == 0)) || (nowsec >= ((uint32_t)time))) { par = 100; } @@ -338,7 +381,7 @@ animation_end(struct uifw_win_surface *usurf, const int disp) struct animation_data *animadata; usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_NONE; - animadata = (struct animation_data *)usurf->animadata; + animadata = (struct animation_data *)usurf->animation.animadata; if (animadata) { if (animadata->end_function) { @@ -356,32 +399,49 @@ animation_end(struct uifw_win_surface *usurf, const int disp) wl_list_remove(&animadata->transform.link); animadata->transform_set = 0; } - usurf->surface->geometry.dirty = 1; + weston_surface_geometry_dirty(usurf->surface); } if (disp) { if ((usurf->animation.visible == ANIMA_HIDE_AT_END) && - (ivi_shell_is_visible(usurf->shsurf))) { - ivi_shell_set_visible(usurf->shsurf, 0); - weston_surface_damage_below(usurf->surface); + (usurf->visible != 0)) { + ico_window_mgr_set_visible(usurf, 0); weston_surface_damage(usurf->surface); - weston_compositor_schedule_repaint(weston_ec); } if ((usurf->animation.visible == ANIMA_SHOW_AT_END) && - (! ivi_shell_is_visible(usurf->shsurf))) { - ivi_shell_set_visible(usurf->shsurf, 1); - weston_surface_damage_below(usurf->surface); + (usurf->visible == 0)) { + ico_window_mgr_set_visible(usurf, 1); weston_surface_damage(usurf->surface); } - ivi_shell_restrain_configure(usurf->shsurf, 0); + usurf->restrain_configure = 0; + weston_surface_geometry_dirty(usurf->surface); weston_compositor_schedule_repaint(weston_ec); } usurf->animation.visible = ANIMA_NOCONTROL_AT_END; - usurf->animation.type = usurf->animation.type_next; + if (usurf->animation.next_name != ICO_WINDOW_MGR_ANIMATION_NONE) { + switch(usurf->animation.type) { + case ICO_WINDOW_MGR_ANIMATION_OPHIDE: + usurf->animation.hide_name = usurf->animation.next_name; + break; + case ICO_WINDOW_MGR_ANIMATION_OPSHOW: + usurf->animation.show_name = usurf->animation.next_name; + break; + case ICO_WINDOW_MGR_ANIMATION_OPMOVE: + usurf->animation.move_name = usurf->animation.next_name; + break; + case ICO_WINDOW_MGR_ANIMATION_OPRESIZE: + usurf->animation.resize_name = usurf->animation.next_name; + break; + default: + break; + } + usurf->animation.next_name = ICO_WINDOW_MGR_ANIMATION_NONE; + } if (animadata) { - usurf->animadata = NULL; + usurf->animation.animadata = NULL; animadata->next_free = free_data; free_data = animadata; } + usurf->animation.type = ICO_WINDOW_MGR_ANIMATION_OPNONE; } /*--------------------------------------------------------------------------*/ @@ -403,13 +463,13 @@ animation_slide(struct weston_animation *animation, struct weston_surface *es; int dwidth, dheight; int par; + int x; + int y; usurf = container_of(animation, struct uifw_win_surface, animation.animation); par = animation_cont(animation, output, msecs); if (par > 0) { - uifw_trace("animation_slide: usurf=%08x count=%d %d%% skip", - (int)usurf, animation->frame_counter, par); /* continue animation */ if( par <= 100) { weston_compositor_schedule_repaint(weston_ec); @@ -417,68 +477,72 @@ animation_slide(struct weston_animation *animation, return; } par = usurf->animation.current; - animadata = (struct animation_data *)usurf->animadata; + animadata = (struct animation_data *)usurf->animation.animadata; - uifw_trace("animation_slide: usurf=%08x count=%d %d%% type=%d state=%d", + uifw_trace("animation_slide: usurf=%08x count=%d %d%% name=%d state=%d", (int)usurf, animation->frame_counter, par, - usurf->animation.type, usurf->animation.state); + usurf->animation.name, usurf->animation.state); es = usurf->surface; + x = usurf->x; + y = usurf->y; - switch (usurf->animation.type) { + switch (usurf->animation.name) { case ANIMA_SLIDE_TORIGHT: /* slide in left to right */ - if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) { + if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_SHOW) { /* slide in left to right */ - usurf->x = 0 - ((animadata->x + animadata->width) * (100 - par) / 100); + x = 0 - animadata->width + + ((animadata->x + animadata->width) * par / 100); } else { /* slide out right to left */ - usurf->x = 0 - ((animadata->x + animadata->width) * par / 100); + x = 0 - animadata->width + + ((animadata->x + animadata->width) * (100 - par) / 100); } break; case ANIMA_SLIDE_TOLEFT: /* slide in right to left */ dwidth = (container_of(weston_ec->output_list.next, struct weston_output, link))->width; - if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) { + if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_SHOW) { /* slide in right to left */ - usurf->x = animadata->x + (dwidth - animadata->x) * (100 - par) / 100; + x = animadata->x + (dwidth - animadata->x) * (100 - par) / 100; } else { /* slide out left to right */ - usurf->x = animadata->x + (dwidth - animadata->x) * par / 100; + x = animadata->x + (dwidth - animadata->x) * par / 100; } break; case ANIMA_SLIDE_TOBOTTOM: /* slide in top to bottom */ - if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) { + if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_SHOW) { /* slide in top to bottom */ - usurf->y = 0 - ((animadata->y + animadata->height) * (100 - par) / 100); + y = 0 - animadata->height + + ((animadata->y + animadata->height) * par / 100); } else { /* slide out bottom to top */ - usurf->y = 0 - ((animadata->y + animadata->height) * par / 100); + y = 0 - animadata->height + + ((animadata->y + animadata->height) * (100 - par) / 100); } break; default: /*ANIMA_SLIDE_TOTOP*/ /* slide in bottom to top */ dheight = (container_of(weston_ec->output_list.next, struct weston_output, link))->height; - if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) { + if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_SHOW) { /* slide in bottom to top */ - usurf->y = animadata->y + (dheight - animadata->y) * (100 - par) / 100; + y = animadata->y + (dheight - animadata->y) * (100 - par) / 100; } else { /* slide out top to bottom */ - usurf->y = animadata->y + (dheight - animadata->y) * par / 100; + y = animadata->y + (dheight - animadata->y) * par / 100; } break; } - es->geometry.x = usurf->x; - es->geometry.y = usurf->y; - ivi_shell_set_positionsize(usurf->shsurf, - usurf->x, usurf->y, usurf->width, usurf->height); - if ((es->output) && (es->buffer) && + es->geometry.x = usurf->node_tbl->disp_x + x; + es->geometry.y = usurf->node_tbl->disp_y + y; + if ((es->output) && (es->buffer_ref.buffer) && (es->geometry.width > 0) && (es->geometry.height > 0)) { - weston_surface_damage_below(es); + weston_surface_geometry_dirty(es); weston_surface_damage(es); } if (par >= 100) { @@ -516,8 +580,6 @@ animation_fade(struct weston_animation *animation, par = animation_cont(animation, output, msecs); if (par > 0) { - uifw_trace("animation_fade: usurf=%08x count=%d %d%% skip", - (int)usurf, animation->frame_counter, par); /* continue animation */ if( par <= 100) { weston_compositor_schedule_repaint(weston_ec); @@ -525,7 +587,7 @@ animation_fade(struct weston_animation *animation, return; } - animadata = (struct animation_data *)usurf->animadata; + animadata = (struct animation_data *)usurf->animation.animadata; es = usurf->surface; par = usurf->animation.current; if (animation->frame_counter == 1) { @@ -539,24 +601,23 @@ animation_fade(struct weston_animation *animation, animadata->end_function = animation_fade_end; } - uifw_trace("animation_fade: usurf=%08x count=%d %d%% type=%d state=%d", + uifw_trace("animation_fade: usurf=%08x count=%d %d%% name=%d state=%d", (int)usurf, animation->frame_counter, par, - usurf->animation.type, usurf->animation.state); + usurf->animation.name, usurf->animation.state); - if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) { + if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_SHOW) { /* fade in */ es->alpha = ((double)par) / ((double)100.0); } else { /* fade out */ - es->alpha = ((double)1.0) - ((double)par) / ((double)100.0); + es->alpha = ((double)1.0) - (((double)par) / ((double)100.0)); } if (es->alpha < 0.0) es->alpha = 0.0; else if (es->alpha > 1.0) es->alpha = 1.0; - if ((es->output) && (es->buffer) && + if ((es->output) && (es->buffer_ref.buffer) && (es->geometry.width > 0) && (es->geometry.height > 0)) { - weston_surface_damage_below(es); weston_surface_damage(es); } if (par >= 100) { @@ -588,9 +649,8 @@ animation_fade_end(struct weston_animation *animation) es = usurf->surface; es->alpha = 1.0; - if ((es->output) && (es->buffer) && + if ((es->output) && (es->buffer_ref.buffer) && (es->geometry.width > 0) && (es->geometry.height > 0)) { - weston_surface_damage_below(es); weston_surface_damage(es); } } @@ -601,13 +661,15 @@ animation_fade_end(struct weston_animation *animation) * this function called from ico_pluign_loader * * @param[in] es weston compositor + * @param[in] argc number of arguments(unused) + * @param[in] argv argument list(unused) * @return result * @retval 0 sccess * @retval -1 error */ /*--------------------------------------------------------------------------*/ WL_EXPORT int -module_init(struct weston_compositor *ec) +module_init(struct weston_compositor *ec, int *argc, char *argv[]) { int i; struct animation_data *animadata; @@ -627,11 +689,13 @@ module_init(struct weston_compositor *ec) } weston_ec = ec; - default_animation = (char *)ivi_shell_default_animation(&animation_time, - &animation_fpar); + default_animation = (char *)ico_ivi_default_animation_name(); + animation_time = ico_ivi_default_animation_time(); + animation_fpar = ico_ivi_default_animation_fps(); + animation_fpar = ((1000 * 100) / animation_fpar) / animation_time; - ico_window_mgr_set_animation(ico_window_animation); + ico_window_mgr_set_hook_animation(ico_window_animation); uifw_info("ico_window_animation: Leave(module_init)"); diff --git a/src/ico_window_mgr.c b/src/ico_window_mgr.c index 577911a..a5d9491 100644 --- a/src/ico_window_mgr.c +++ b/src/ico_window_mgr.c @@ -24,7 +24,7 @@ /** * @brief Multi Window Manager (Weston(Wayland) PlugIn) * - * @date Feb-08-2013 + * @date Jul-26-2013 */ #define _GNU_SOURCE @@ -50,16 +50,16 @@ #include "ico_ivi_common.h" #include "ico_ivi_shell.h" #include "ico_window_mgr.h" -#include "ico_ivi_shell-server-protocol.h" +#include "desktop-shell-server-protocol.h" #include "ico_window_mgr-server-protocol.h" -/* SurfaceID */ +/* SurfaceID */ #define INIT_SURFACE_IDS 1024 /* SurfaceId table initiale size */ #define ADD_SURFACE_IDS 512 /* SurfaceId table additional size */ #define SURCAFE_ID_MASK 0x0ffff /* SurfaceId bit mask pattern */ #define UIFW_HASH 64 /* Hash value (2's compliment) */ -/* Client attribute table */ +/* Client attribute table */ #define MAX_CLIENT_ATTR 4 struct uifw_client_attr { char appid[ICO_IVI_APPID_LENGTH]; /* ApplicationId */ @@ -71,25 +71,25 @@ struct uifw_client_attr { struct wl_list link; }; -/* Manager table */ +/* Manager table */ struct uifw_manager { struct wl_resource *resource; /* Manager resource */ - int eventcb; /* Event send flag */ + int manager; /* Manager(=event send flag) */ struct wl_list link; /* link to next manager */ }; -/* Multi Windiw Manager */ +/* Multi Windiw Manager */ struct ico_win_mgr { struct weston_compositor *compositor; /* Weston compositor */ + void *shell; /* shell(ico_ivi_shell) table address */ int32_t surface_head; /* (HostID << 24) | (DisplayNo << 16) */ struct wl_list client_list; /* Clients */ struct wl_list manager_list; /* Manager(ex.HomeScreen) list */ int num_manager; /* Number of managers */ - struct wl_list surface_list; /* Surface list */ - struct wl_list client_attr_list; /* Client attribute list */ - struct uifw_win_surface *active_pointer_surface; /* Active Pointer Surface */ - struct uifw_win_surface *active_keyboard_surface; /* Active Keyboard Surface */ + struct wl_list ivi_layer_list; /* Layer management table list */ + struct uifw_win_surface *active_pointer_usurf; /* Active Pointer Surface */ + struct uifw_win_surface *active_keyboard_usurf; /* Active Keyboard Surface */ struct uifw_win_surface *idhash[UIFW_HASH]; /* UIFW SerfaceID */ struct uifw_win_surface *wshash[UIFW_HASH]; /* Weston Surface */ @@ -97,6 +97,9 @@ struct ico_win_mgr { uint32_t surfaceid_count; /* Number of surface id */ uint32_t surfaceid_max; /* Maximum number of surface id */ uint16_t *surfaceid_map; /* SurfaceId assign bit map */ + + char shell_init; /* shell initialize flag */ + char res; /* (unused) */ }; /* Internal macros */ @@ -106,8 +109,6 @@ struct ico_win_mgr { #define MAKE_WSHASH(v) ((((uint32_t)v) >> 5) & (UIFW_HASH-1)) /* function prototype */ - /* weston compositor interface */ -int module_init(struct weston_compositor *ec); /* get surface table from surfece id */ static struct uifw_win_surface* find_uifw_win_surface_by_id(uint32_t surfaceid); /* get surface table from weston surface*/ @@ -118,96 +119,213 @@ static struct uifw_client* find_client_from_client(struct wl_client* client); /* assign new surface id */ static uint32_t generate_id(void); /* bind shell client */ -static void bind_shell_client(struct wl_client *client); +static void win_mgr_bind_client(struct wl_client *client, void *shell); /* unind shell client */ -static void unbind_shell_client(struct wl_client *client); +static void win_mgr_unbind_client(struct wl_client *client); /* create new surface */ -static void client_register_surface( +static void win_mgr_register_surface( struct wl_client *client, struct wl_resource *resource, struct weston_surface *surface, struct shell_surface *shsurf); + /* surface destory */ +static void win_mgr_destroy_surface(struct weston_surface *surface); /* map new surface */ static void win_mgr_map_surface(struct weston_surface *surface, int32_t *width, int32_t *height, int32_t *sx, int32_t *sy); - /* set applicationId for RemoteUI */ -static void uifw_set_user(struct wl_client *client, struct wl_resource *resource, - int pid, const char *appid); - /* set/reset event flag */ -static void uifw_set_eventcb(struct wl_client *client, struct wl_resource *resource, - int eventcb); + /* send surface change event to manager */ +static void win_mgr_change_surface(struct weston_surface *surface, + const int to, const int manager); + /* surface select */ +static void win_mgr_select_surface(struct weston_surface *surface); + /* surface set title */ +static void win_mgr_set_title(struct weston_surface *surface, const char *title); + /* surface move request from shell */ +static void win_mgr_surface_move(struct weston_surface *surface, int *dx, int *dy); + /* set raise */ +static void win_mgr_set_raise(struct uifw_win_surface *usurf, const int raise); + /* surface change from manager */ +static int win_mgr_surface_change_mgr(struct weston_surface *surface, const int x, + const int y, const int width, const int height); + /* restack surface list */ +static void win_mgr_restack_ivi_layer(struct uifw_win_surface *usurf); + /* create new layer */ +static struct uifw_win_layer *win_mgr_create_layer(struct uifw_win_surface *usurf, + const uint32_t layer); + /* set surface layer */ +static void win_mgr_set_layer(struct uifw_win_surface *usurf, const uint32_t layer); + /* change weston surface */ +static void win_mgr_set_weston_surface(struct uifw_win_surface *usurf); + /* set active surface */ +static void win_mgr_set_active(struct uifw_win_surface *usurf, const int target); + + /* declare manager */ +static void uifw_declare_manager(struct wl_client *client, struct wl_resource *resource, + int manager); + /* create layer and set attribute */ +static void uifw_create_layer(struct wl_client *client, struct wl_resource *resource, + uint32_t layer, int32_t attribute); /* set window layer */ static void uifw_set_window_layer(struct wl_client *client, struct wl_resource *resource, - uint32_t surfaceid, int layer); + uint32_t surfaceid, uint32_t layer); /* set surface size and position */ -static void uifw_set_positionsize(struct wl_client *client, - struct wl_resource *resource, uint32_t surfaceid, - int32_t x, int32_t y, int32_t width, int32_t height); +static void uifw_set_positionsize(struct wl_client *client, struct wl_resource *resource, + uint32_t surfaceid, uint32_t node, int32_t x, int32_t y, + int32_t width, int32_t height, int32_t animation); /* show/hide and raise/lower surface */ static void uifw_set_visible(struct wl_client *client, struct wl_resource *resource, - uint32_t surfaceid, int32_t visible, int32_t raise); + uint32_t surfaceid, int32_t visible, int32_t raise, + int32_t animation); /* set surface animation */ static void uifw_set_animation(struct wl_client *client, struct wl_resource *resource, - uint32_t surfaceid, const char *animation, int32_t time); + uint32_t surfaceid, int32_t type, + const char *animation, int32_t time); /* set active surface (form HomeScreen) */ static void uifw_set_active(struct wl_client *client, struct wl_resource *resource, - uint32_t surfaceid, uint32_t target); + uint32_t surfaceid, int32_t active); /* layer visibility control */ static void uifw_set_layer_visible(struct wl_client *client, struct wl_resource *resource, - int32_t layer, int32_t visible); - /* send surface change event to manager */ -static void uifw_set_client_attr(struct wl_client *client, struct wl_resource *resource, - const char *appid, int32_t attr, int32_t value); - /* set client application attribute */ -static void win_mgr_surface_change(struct weston_surface *surface, - const int to, const int manager); - /* surface change from manager */ -static int win_mgr_surface_change_mgr(struct weston_surface *surface, const int x, - const int y, const int width, const int height); - /* surface destory */ -static void win_mgr_surface_destroy(struct weston_surface *surface); + uint32_t layer, int32_t visible); + /* get application surfaces */ +static void uifw_get_surfaces(struct wl_client *client, struct wl_resource *resource, + const char *appid); + /* map surface buffer to shared memory */ +static void uifw_map_surface(struct wl_client *client, struct wl_resource *resource, + uint32_t surfaceid, const char *mapname, int32_t framerate); + /* unmap surface buffer */ +static void uifw_unmap_surface(struct wl_client *client, struct wl_resource *resource, + uint32_t surfaceid); /* bind manager */ static void bind_ico_win_mgr(struct wl_client *client, void *data, uint32_t version, uint32_t id); /* unbind manager */ static void unbind_ico_win_mgr(struct wl_resource *resource); - /* convert surfaceId to nodeId */ -static int ico_winmgr_usurf_2_node(const int surfaceid); /* send event to manager */ -static int ico_win_mgr_send_to_mgr(const int event, const int surfaceid, - const char *appid, const int param1, - const int param2, const int param3, const int param4, - const int param5, const int param6); - /* convert animation name to type value */ -static int ico_get_animation_type(const char *animation); - /* hook for set user */ -static void (*win_mgr_hook_set_user) - (struct wl_client *client, const char *appid) = NULL; - /* hook for surface create */ -static void (*win_mgr_hook_create) - (struct wl_client *client, struct weston_surface *surface, - int surfaceId, const char *appid) = NULL; - /* hook for surface destory */ -static void (*win_mgr_hook_destroy)(struct weston_surface *surface) = NULL; +static int ico_win_mgr_send_to_mgr(const int event, struct uifw_win_surface *usurf, + const int param1, const int param2, const int param3, + const int param4, const int param5); + /* convert animation name to Id value */ +static int ico_get_animation_name(const char *animation); /* hook for animation */ static int (*win_mgr_hook_animation)(const int op, void *data) = NULL; /* static tables */ /* Multi Window Manager interface */ static const struct ico_window_mgr_interface ico_window_mgr_implementation = { - uifw_set_user, - uifw_set_eventcb, + uifw_declare_manager, + uifw_create_layer, uifw_set_window_layer, uifw_set_positionsize, uifw_set_visible, uifw_set_animation, uifw_set_active, uifw_set_layer_visible, - uifw_set_client_attr + uifw_get_surfaces, + uifw_map_surface, + uifw_unmap_surface }; +/* plugin common value(without ico_plugin_loader) */ +static int _ico_ivi_debug_flag = 0; /* Debug flags */ +static int _ico_ivi_debug_level = 3; /* Debug Level */ +static char *_ico_ivi_animation_name = NULL; /* Default animation name */ +static int _ico_ivi_animation_time = 500; /* Default animation time */ +static int _ico_ivi_animation_fps = 15; /* Animation frame rate */ + /* static management table */ -static struct ico_win_mgr *_ico_win_mgr = NULL; +static struct ico_win_mgr *_ico_win_mgr = NULL; +static int _ico_num_nodes = 0; +static struct uifw_node_table _ico_node_table[ICO_IVI_MAX_DISPLAY]; + + +/*--------------------------------------------------------------------------*/ +/** + * @brief ico_ivi_debugflag: get debug flags + * + * @param None + * @return debug flags + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT int +ico_ivi_debugflag(void) +{ + return _ico_ivi_debug_flag; +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief ico_ivi_debuglevel: answer debug output level. + * + * @param none + * @return debug output level + * @retval 0 No debug output + * @retval 1 Only error output + * @retval 2 Error and Warning output + * @retval 3 Error, Warning and information output + * @retval 4 All output with debug write + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT int +ico_ivi_debuglevel(void) +{ + return _ico_ivi_debug_level; +} +/*--------------------------------------------------------------------------*/ +/** + * @brief ico_ivi_default_animation_name: get default animation name + * + * @param None + * @return Default animation name + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT const char * +ico_ivi_default_animation_name(void) +{ + return _ico_ivi_animation_name; +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief ico_ivi_default_animation_time: get default animation time + * + * @param None + * @return Default animation time(miri sec) + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT int +ico_ivi_default_animation_time(void) +{ + return _ico_ivi_animation_time; +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief ico_ivi_default_animation_fps: get default animation frame rate + * + * @param None + * @return Default animation frame rate(frames/sec) + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT int +ico_ivi_default_animation_fps(void) +{ + return _ico_ivi_animation_fps; +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief ico_ivi_get_mynode: Get my NodeId + * + * @param None + * @return NodeId of my node + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT int +ico_ivi_get_mynode(void) +{ + /* Reference Platform 0.90 only support 1 ECU */ + return 0; +} /*--------------------------------------------------------------------------*/ /** @@ -227,7 +345,7 @@ find_uifw_win_surface_by_id(uint32_t surfaceid) usurf = _ico_win_mgr->idhash[MAKE_IDHASH(surfaceid)]; while (usurf) { - if (usurf->id == surfaceid) { + if (usurf->surfaceid == surfaceid) { return usurf; } usurf = usurf->next_idhash; @@ -236,10 +354,9 @@ find_uifw_win_surface_by_id(uint32_t surfaceid) return NULL; } - /*--------------------------------------------------------------------------*/ /** - * @brief find_uifw_win_surface_by_ws: find UIFW srurace by weston surface + * @brief find_uifw_win_surface_by_ws: find UIFW surface by weston surface * * @param[in] wsurf Weston surface * @return UIFW surface table address @@ -284,13 +401,13 @@ find_client_from_client(struct wl_client* client) return(uclient); } } - uifw_trace("find_client_from_client: NULL"); + uifw_trace("find_client_from_client: client.%08x is NULL", (int)client); return NULL; } /*--------------------------------------------------------------------------*/ /** - * @brief ico_window_mgr_appid: find application id by wayland client + * @brief ico_window_mgr_get_appid: find application id by wayland client * * @param[in] client Wayland client * @return application id @@ -299,7 +416,7 @@ find_client_from_client(struct wl_client* client) */ /*--------------------------------------------------------------------------*/ WL_EXPORT char * -ico_window_mgr_appid(struct wl_client* client) +ico_window_mgr_get_appid(struct wl_client* client) { struct uifw_client *uclient; @@ -386,17 +503,18 @@ generate_id(void) /*--------------------------------------------------------------------------*/ /** - * @brief bind_shell_client: ico_ivi_shell from client + * @brief win_mgr_bind_client: desktop_shell from client * * @param[in] client Wayland client + * @param[in] shell shell(ico_ivi_shell) table address * @return none */ /*--------------------------------------------------------------------------*/ static void -bind_shell_client(struct wl_client *client) +win_mgr_bind_client(struct wl_client *client, void *shell) { struct uifw_client *uclient; - struct uifw_client_attr *lattr; + int newclient; pid_t pid; uid_t uid; gid_t gid; @@ -406,36 +524,45 @@ bind_shell_client(struct wl_client *client) int j; char procpath[128]; - uifw_trace("bind_shell_client: Enter(client=%08x)", (int)client); + uifw_trace("win_mgr_bind_client: Enter(client=%08x, sjell=%08x)", + (int)client, (int)shell); + + /* save shell table address */ + if (shell) { + _ico_win_mgr->shell = shell; + } /* set client */ uclient = find_client_from_client(client); if (! uclient) { /* client not exist, create client management table */ - uifw_trace("bind_shell_client: Create Client"); + uifw_trace("win_mgr_bind_client: Create Client"); uclient = (struct uifw_client *)malloc(sizeof(struct uifw_client)); if (!uclient) { - uifw_error("bind_shell_client: Error, No Memory"); + uifw_error("win_mgr_bind_client: Error, No Memory"); return; } memset(uclient, 0, sizeof(struct uifw_client)); uclient->client = client; - wl_list_insert(&_ico_win_mgr->client_list, &uclient->link); + newclient = 1; + } + else { + newclient = 0; } wl_client_get_credentials(client, &pid, &uid, &gid); - uifw_trace("bind_shell_client: client=%08x pid=%d uid=%d gid=%d", + uifw_trace("win_mgr_bind_client: client=%08x pid=%d uid=%d gid=%d", (int)client, (int)pid, (int)uid, (int)gid); if (pid > 0) { uclient->pid = (int)pid; /* get applicationId from AppCore(AUL) */ if (aul_app_get_appid_bypid(uclient->pid, uclient->appid, ICO_IVI_APPID_LENGTH) == AUL_R_OK) { - uifw_trace("bind_shell_client: client=%08x pid=%d appid=<%s>", + uifw_trace("win_mgr_bind_client: client=%08x pid=%d appid=<%s>", (int)client, uclient->pid, uclient->appid); } else { /* client dose not exist in AppCore, search Linux process table */ - uifw_trace("bind_shell_client: pid=%d dose not exist in AppCore(AUL)", + uifw_trace("win_mgr_bind_client: pid=%d dose not exist in AppCore(AUL)", uclient->pid); memset(uclient->appid, 0, ICO_IVI_APPID_LENGTH); @@ -474,55 +601,47 @@ bind_shell_client(struct wl_client *client) close(fd); } if (uclient->appid[0]) { - uifw_trace("bind_shell_client: client=%08x pid=%d appid=<%s> from " + uifw_trace("win_mgr_bind_client: client=%08x pid=%d appid=<%s> from " "Process table", (int)client, uclient->pid, uclient->appid); + /* weston internal client, not manage */ + if (strcmp(uclient->appid, "weston") == 0) { + newclient = -newclient; + } } else { - uifw_trace("bind_shell_client: pid=%d dose not exist in Process table", + uifw_trace("win_mgr_bind_client: pid=%d dose not exist in Process table", uclient->pid); sprintf(uclient->appid, "?%d?", uclient->pid); } } - - wl_list_for_each (lattr, &_ico_win_mgr->client_attr_list, link) { - if (strcmp(lattr->appid, uclient->appid) == 0) { - for (i = 0; i < MAX_CLIENT_ATTR; i++) { - switch (lattr->attrs[i].attr) { - case ICO_WINDOW_MGR_CLIENT_ATTR_NOCONFIGURE: - uclient->noconfigure = lattr->attrs[i].value; - ivi_shell_set_client_attr(uclient->client, - ICO_CLEINT_ATTR_NOCONFIGURE, - lattr->attrs[i].value); - uifw_trace("bind_shell_client: set to ivi-shell"); - break; - default: - break; - } - } - break; - } + if (newclient > 0) { + wl_list_insert(&_ico_win_mgr->client_list, &uclient->link); + } + else if (newclient < 0) { + free(uclient); + uifw_trace("win_mgr_bind_client: client=%08x is internal, delete", (int)client); } } else { - uifw_trace("bind_shell_client: client=%08x pid dose not exist", (int)client); + uifw_trace("win_mgr_bind_client: client=%08x pid dose not exist", (int)client); } - uifw_trace("bind_shell_client: Leave"); + uifw_trace("win_mgr_bind_client: Leave"); } /*--------------------------------------------------------------------------*/ /** - * @brief unbind_shell_client: unbind ico_ivi_shell from client + * @brief win_mgr_unbind_client: unbind desktop_shell from client * * @param[in] client Wayland client * @return none */ /*--------------------------------------------------------------------------*/ static void -unbind_shell_client(struct wl_client *client) +win_mgr_unbind_client(struct wl_client *client) { struct uifw_client *uclient; - uifw_trace("unbind_shell_client: Enter(client=%08x)", (int)client); + uifw_trace("win_mgr_unbind_client: Enter(client=%08x)", (int)client); uclient = find_client_from_client(client); if (uclient) { @@ -530,19 +649,19 @@ unbind_shell_client(struct wl_client *client) wl_list_remove(&uclient->link); free(uclient); } - uifw_trace("unbind_shell_client: Leave"); + uifw_trace("win_mgr_unbind_client: Leave"); } /*--------------------------------------------------------------------------*/ /** - * @brief ico_get_animation_type: convert animation name to type value + * @brief ico_get_animation_name: convert animation name to Id value * * @param[in] animation animation name - * @return animation type value + * @return animation Id value */ /*--------------------------------------------------------------------------*/ static int -ico_get_animation_type(const char *animation) +ico_get_animation_name(const char *animation) { int anima = ICO_WINDOW_MGR_ANIMATION_NONE; @@ -551,7 +670,7 @@ ico_get_animation_type(const char *animation) } if (win_mgr_hook_animation) { - anima = (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_TYPE, (void *)animation); + anima = (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_NAME, (void *)animation); } if (anima <= 0) { anima = ICO_WINDOW_MGR_ANIMATION_NONE; @@ -561,7 +680,7 @@ ico_get_animation_type(const char *animation) /*--------------------------------------------------------------------------*/ /** - * @brief client_register_surface: create UIFW surface + * @brief win_mgr_register_surface: create UIFW surface * * @param[in] client Wayland client * @param[in] resource client resource @@ -571,67 +690,76 @@ ico_get_animation_type(const char *animation) */ /*--------------------------------------------------------------------------*/ static void -client_register_surface(struct wl_client *client, struct wl_resource *resource, - struct weston_surface *surface, struct shell_surface *shsurf) +win_mgr_register_surface(struct wl_client *client, struct wl_resource *resource, + struct weston_surface *surface, struct shell_surface *shsurf) { - struct uifw_win_surface *us; + struct uifw_win_surface *usurf; struct uifw_win_surface *phash; struct uifw_win_surface *bhash; - struct uifw_client_attr *lattr; uint32_t hash; - int i; - uifw_trace("client_register_surface: Enter(surf=%08x,client=%08x,res=%08x)", + uifw_trace("win_mgr_register_surface: Enter(surf=%08x,client=%08x,res=%08x)", (int)surface, (int)client, (int)resource); /* check new surface */ if (find_uifw_win_surface_by_ws(surface)) { /* surface exist, NOP */ - uifw_trace("client_register_surface: Leave(Already Exist)"); + uifw_trace("win_mgr_register_surface: Leave(Already Exist)"); return; } + /* set default color and shader */ + weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1); + /* create UIFW surface management table */ - us = malloc(sizeof(struct uifw_win_surface)); - if (!us) { - uifw_error("client_register_surface: No Memory"); + usurf = malloc(sizeof(struct uifw_win_surface)); + if (! usurf) { + uifw_error("win_mgr_register_surface: No Memory"); return; } - memset(us, 0, sizeof(struct uifw_win_surface)); - - us->id = generate_id(); - us->surface = surface; - us->shsurf = shsurf; - wl_list_init(&us->animation.animation.link); - us->animation.type = ico_get_animation_type(ivi_shell_default_animation(NULL, NULL)); - us->animation.type_next = us->animation.type; - - if (_ico_win_mgr->num_manager <= 0) { - uifw_trace("client_register_surface: No Manager, Force visible"); - ivi_shell_set_visible(shsurf, 1); /* NOT exist HomeScreen */ + memset(usurf, 0, sizeof(struct uifw_win_surface)); + + usurf->surfaceid = generate_id(); + usurf->surface = surface; + usurf->shsurf = shsurf; + usurf->node_tbl = &_ico_node_table[0]; /* set default node table (display no=0) */ + wl_list_init(&usurf->ivi_layer); + wl_list_init(&usurf->animation.animation.link); + usurf->animation.hide_name = ico_get_animation_name(ico_ivi_default_animation_name()); + usurf->animation.hide_time = ico_ivi_default_animation_time();; + usurf->animation.show_name = usurf->animation.hide_name; + usurf->animation.show_time = usurf->animation.hide_time; + usurf->animation.move_name = usurf->animation.hide_name; + usurf->animation.move_time = usurf->animation.hide_time; + usurf->animation.resize_name = usurf->animation.hide_name; + usurf->animation.resize_time = usurf->animation.hide_time; + + if ((_ico_win_mgr->num_manager <= 0) || + (ico_ivi_debugflag() & ICO_IVI_DEBUG_SHOW_SURFACE)) { + uifw_trace("win_mgr_register_surface: No Manager, Force visible"); + usurf->visible = 1; } else { - uifw_trace("client_register_surface: Manager exist, Not visible"); - ivi_shell_set_visible(shsurf, -1); /* Exist HomeScreen */ + uifw_trace("win_mgr_register_surface: Manager exist, Not visible"); + usurf->visible = 0; } /* set client */ - us->uclient = find_client_from_client(client); - if (! us->uclient) { + usurf->uclient = find_client_from_client(client); + if (! usurf->uclient) { /* client not exist, create client management table */ - uifw_trace("client_register_surface: Create Client"); - bind_shell_client(client); - us->uclient = find_client_from_client(client); - if (! us->uclient) { - uifw_error("client_register_surface: No Memory"); + uifw_trace("win_mgr_register_surface: Create Client"); + win_mgr_bind_client(client, NULL); + usurf->uclient = find_client_from_client(client); + if (! usurf->uclient) { + uifw_error("win_mgr_register_surface: No Memory"); return; } } - wl_list_insert(&_ico_win_mgr->surface_list, &us->link); /* make surface id hash table */ - hash = MAKE_IDHASH(us->id); + hash = MAKE_IDHASH(usurf->surfaceid); phash = _ico_win_mgr->idhash[hash]; bhash = NULL; while (phash) { @@ -639,14 +767,14 @@ client_register_surface(struct wl_client *client, struct wl_resource *resource, phash = phash->next_idhash; } if (bhash) { - bhash->next_idhash = us; + bhash->next_idhash = usurf; } else { - _ico_win_mgr->idhash[hash] = us; + _ico_win_mgr->idhash[hash] = usurf; } /* make weston surface hash table */ - hash = MAKE_WSHASH(us->surface); + hash = MAKE_WSHASH(usurf->surface); phash = _ico_win_mgr->wshash[hash]; bhash = NULL; while (phash) { @@ -654,44 +782,15 @@ client_register_surface(struct wl_client *client, struct wl_resource *resource, phash = phash->next_wshash; } if (bhash) { - bhash->next_wshash = us; + bhash->next_wshash = usurf; } else { - _ico_win_mgr->wshash[hash] = us; + _ico_win_mgr->wshash[hash] = usurf; } /* set default layer id */ - ivi_shell_set_layer(shsurf, 0); - - /* set client attribute */ - wl_list_for_each (lattr, &_ico_win_mgr->client_attr_list, link) { - if (strcmp(lattr->appid, us->uclient->appid) == 0) { - for (i = 0; i < MAX_CLIENT_ATTR; i++) { - switch (lattr->attrs[i].attr) { - case ICO_WINDOW_MGR_CLIENT_ATTR_NOCONFIGURE: - us->uclient->noconfigure = lattr->attrs[i].value; - ivi_shell_set_client_attr(us->uclient->client, - ICO_CLEINT_ATTR_NOCONFIGURE, - lattr->attrs[i].value); - uifw_trace("client_register_surface: set attr(%d=%d) to %08x", - lattr->attrs[i].attr, lattr->attrs[i].value, us->id); - break; - default: - break; - } - } - break; - } - } - - /* send event to manager */ - ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CREATED, - us->id, us->uclient->appid, us->uclient->pid, 0,0,0,0,0); + win_mgr_set_layer(usurf, ICO_IVI_DEFAULT_LAYER); - if (win_mgr_hook_create) { - /* call surface create hook for other plugin */ - (void) (*win_mgr_hook_create)(client, surface, us->id, us->uclient->appid); - } - uifw_trace("client_register_surface: Leave(surfaceId=%08x)", us->id); + uifw_trace("win_mgr_register_surface: Leave(surfaceId=%08x)", usurf->surfaceid); } /*--------------------------------------------------------------------------*/ @@ -719,24 +818,22 @@ win_mgr_map_surface(struct weston_surface *surface, int32_t *width, int32_t *hei if (usurf) { uifw_trace("win_mgr_map_surface: surf=%08x w/h=%d/%d vis=%d", - usurf->id, usurf->width, usurf->height, - ivi_shell_is_visible(usurf->shsurf)); - + usurf->surfaceid, usurf->width, usurf->height, usurf->visible); if ((usurf->width > 0) && (usurf->height > 0)) { uifw_trace("win_mgr_map_surface: HomeScreen registed, PositionSize" "(surf=%08x x/y=%d/%d w/h=%d/%d vis=%d", - usurf->id, usurf->x, usurf->y, usurf->width, usurf->height, - ivi_shell_is_visible(usurf->shsurf)); + usurf->surfaceid, usurf->x, usurf->y, usurf->width, usurf->height, + usurf->visible); *width = usurf->width; *height = usurf->height; - surface->geometry.x = usurf->x; - surface->geometry.y = usurf->y; - surface->geometry.dirty = 1; + weston_surface_configure(surface, usurf->node_tbl->disp_x + usurf->x, + usurf->node_tbl->disp_y + usurf->y, + usurf->width, usurf->height); } else { uifw_trace("win_mgr_map_surface: HomeScreen not regist Surface, " "Change PositionSize(surf=%08x x/y=%d/%d w/h=%d/%d)", - usurf->id, *sx, *sy, *width, *height); + usurf->surfaceid, *sx, *sy, *width, *height); usurf->width = *width; usurf->height = *height; usurf->x = *sx; @@ -746,126 +843,402 @@ win_mgr_map_surface(struct weston_surface *surface, int32_t *width, int32_t *hei if (_ico_win_mgr->num_manager > 0) { /* HomeScreen exist, coodinate set by HomeScreen */ - surface->geometry.x = 0; - surface->geometry.y = 0; - uifw_trace("win_mgr_map_surface: Change size and position"); + if (usurf->visible) { + weston_surface_configure(surface, usurf->node_tbl->disp_x + usurf->x, + usurf->node_tbl->disp_y + usurf->y, + usurf->width, usurf->height); + } + else { + weston_surface_configure(surface, ICO_IVI_MAX_COORDINATE+1, + ICO_IVI_MAX_COORDINATE+1, + usurf->width, usurf->height); + } + uifw_trace("win_mgr_map_surface: Change size/position x/y=%d/%d w/h=%d/%d", + (int)surface->geometry.x, (int)surface->geometry.y, + surface->geometry.width, surface->geometry.height); } - else { + if ((_ico_win_mgr->num_manager <= 0) || + (ico_ivi_debugflag() & ICO_IVI_DEBUG_SHOW_SURFACE)) { uifw_trace("win_mgr_map_surface: Np HomeScreen, chaneg to Visible"); - ivi_shell_set_visible(usurf->shsurf, 1); + ico_window_mgr_set_visible(usurf, 1); } } - ivi_shell_set_positionsize(usurf->shsurf, - usurf->x, usurf->y, usurf->width, usurf->height); + usurf->mapped = 1; + if (usurf->visible) { + win_mgr_restack_ivi_layer(NULL); + } uifw_trace("win_mgr_map_surface: Leave"); } else { - uifw_trace("win_mgr_map_surface: Leave(No Window Manager Surface)"); + uifw_trace("win_mgr_map_surface: Leave(No UIFW Surface)"); } } /*--------------------------------------------------------------------------*/ /** - * @briefdwi uifw_set_user: set user id (for RemoteUI) + * @brief win_mgr_restack_ivi_layer: restack surface list * - * @param[in] client Weyland client - * @param[in] resource resource of request - * @param[in] pid client process id - * @param[in] appid application id + * @param[in] usurf UIFW surface * @return none */ /*--------------------------------------------------------------------------*/ static void -uifw_set_user(struct wl_client *client, struct wl_resource *resource, - int pid, const char *appid) +win_mgr_restack_ivi_layer(struct uifw_win_surface *usurf) { - struct uifw_client *uclient; + struct uifw_win_surface *es; + struct uifw_win_layer *el; + int32_t buf_width, buf_height; + float new_x, new_y; + struct weston_layer *wlayer; + int num_visible = 0; + + uifw_trace("win_mgr_restack_ivi_layer: Enter(surf=%08x)", (int)usurf); + + /* make compositor surface list */ + wlayer = ico_ivi_shell_current_layer(); + + wl_list_init(&wlayer->surface_list); + wl_list_for_each (el, &_ico_win_mgr->ivi_layer_list, link) { + wl_list_for_each (es, &el->surface_list, ivi_layer) { + if ((es->mapped != 0) && (es->surface != NULL)) { + if ((el->visible == FALSE) || (es->visible == FALSE)) { + new_x = (float)(ICO_IVI_MAX_COORDINATE+1); + new_y = (float)(ICO_IVI_MAX_COORDINATE+1); + } + else if (es->surface->buffer_ref.buffer) { + buf_width = weston_surface_buffer_width(es->surface); + buf_height = weston_surface_buffer_height(es->surface); + if (es->width > buf_width) { + new_x = (float)(es->x + + (es->width - es->surface->geometry.width)/2); + } + else { + new_x = (float)es->x; + } + if (es->height > buf_height) { + new_y = (float) (es->y + + (es->height - es->surface->geometry.height)/2); + } + else { + new_y = (float)es->y; + } + new_x += es->node_tbl->disp_x; + new_y += es->node_tbl->disp_y; + num_visible ++; + } + else { + new_x = (float)(ICO_IVI_MAX_COORDINATE+1); + new_y = (float)(ICO_IVI_MAX_COORDINATE+1); + } + wl_list_insert(wlayer->surface_list.prev, &es->surface->layer_link); + if ((new_x != es->surface->geometry.x) || + (new_y != es->surface->geometry.y)) { + weston_surface_damage_below(es->surface); + weston_surface_set_position(es->surface, (float)new_x, (float)new_y); + weston_surface_damage(es->surface); + } + uifw_trace("win_mgr_restack_ivi_layer: %08x x/y=%d/%d w/h=%d/%d", + es->surfaceid, + (int)es->surface->geometry.x, (int)es->surface->geometry.y, + es->surface->geometry.width, es->surface->geometry.height); + } + } + } + + /* damage(redraw) target surfacem if target exist */ + if (usurf) { + weston_surface_damage(usurf->surface); + } - uifw_trace("uifw_set_user: Enter(client=%08x pid=%d appid=%s)", - (int)client, pid, appid); + /* composit and draw screen(plane) */ + weston_compositor_schedule_repaint(_ico_win_mgr->compositor); - uclient = find_client_from_client(client); - if (uclient) { - uclient->pid = pid; - memset(uclient->appid, 0, ICO_IVI_APPID_LENGTH); - strncpy(uclient->appid, appid, ICO_IVI_APPID_LENGTH-1); - uclient->resource = resource; - uifw_trace("uifw_set_user: Leave(Client Exist, change PID/AppId)"); - return; + if ((_ico_win_mgr->shell_init == 0) && (num_visible > 0) && + (_ico_win_mgr->shell != NULL) && (_ico_win_mgr->num_manager > 0)) { + /* start shell fade */ + _ico_win_mgr->shell_init = 1; + ico_ivi_shell_startup(_ico_win_mgr->shell); } + uifw_trace("win_mgr_restack_ivi_layer: Leave"); +} - uclient = (struct uifw_client *)malloc(sizeof(struct uifw_client)); - if (! uclient) { - uifw_trace("uifw_set_user: Leave(Error, No Memory)"); +/*--------------------------------------------------------------------------*/ +/** + * @brief win_mgr_create_layer: create new layer + * + * @param[in] usurf UIFW surface, (if need) + * @param[in] layer layer id + * @return new layer + * @retval != NULL success(layer management table) + * @retval == NULL error(No Memory) + */ +/*--------------------------------------------------------------------------*/ +static struct uifw_win_layer * +win_mgr_create_layer(struct uifw_win_surface *usurf, const uint32_t layer) +{ + struct uifw_win_layer *el; + struct uifw_win_layer *new_el; + + new_el = malloc(sizeof(struct uifw_win_layer)); + if (! new_el) { + uifw_trace("win_mgr_create_layer: Leave(No Memory)"); + return NULL; + } + + memset(new_el, 0, sizeof(struct uifw_win_layer)); + new_el->layer = layer; + new_el->attribute = ICO_WINDOW_MGR_LAYER_ATTR_NORMAL; + new_el->visible = TRUE; + wl_list_init(&new_el->surface_list); + wl_list_init(&new_el->link); + + wl_list_for_each (el, &_ico_win_mgr->ivi_layer_list, link) { + if (layer >= el->layer) break; + } + if (&el->link == &_ico_win_mgr->ivi_layer_list) { + wl_list_insert(_ico_win_mgr->ivi_layer_list.prev, &new_el->link); + } + else { + wl_list_insert(el->link.prev, &new_el->link); + } + + if (usurf) { + wl_list_remove(&usurf->ivi_layer); + wl_list_insert(&new_el->surface_list, &usurf->ivi_layer); + usurf->win_layer = new_el; + } + return new_el; +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief win_mgr_set_layer: set(or change) surface layer + * + * @param[in] usurf UIFW surface + * @param[in] layer layer id + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +win_mgr_set_layer(struct uifw_win_surface *usurf, const uint32_t layer) +{ + struct uifw_win_layer *el; + struct uifw_win_layer *new_el; + + uifw_trace("win_mgr_set_layer: Enter([%08x],%08x,%x)", + (int)usurf, (int)usurf->surface, layer); + + /* check if same layer */ + if ((usurf->win_layer != NULL) && (usurf->win_layer->layer == layer)) { + uifw_trace("win_mgr_set_layer: Leave(Same Layer)"); return; } - memset(uclient, 0, sizeof(struct uifw_client)); - uclient->client = client; - uclient->pid = pid; - memset(uclient->appid, 0, ICO_IVI_APPID_LENGTH); - strncpy(uclient->appid, appid, ICO_IVI_APPID_LENGTH-1); - uclient->resource = resource; + /* search existing layer */ + wl_list_for_each (el, &_ico_win_mgr->ivi_layer_list, link) { + if (el->layer == layer) break; + } + + if (&el->link == &_ico_win_mgr->ivi_layer_list) { + /* layer not exist, create new layer */ + uifw_trace("win_mgr_set_layer: New Layer %d", layer); + new_el = win_mgr_create_layer(usurf, layer); + if (! new_el) { + uifw_trace("win_mgr_set_layer: Leave(No Memory)"); + return; + } + } + else { + uifw_trace("win_mgr_set_layer: Add surface to Layer %d", layer); + wl_list_remove(&usurf->ivi_layer); + wl_list_insert(&el->surface_list, &usurf->ivi_layer); + usurf->win_layer = el; + } + + /* rebild compositor surface list */ + if (usurf->visible) { + win_mgr_restack_ivi_layer(usurf); + } + uifw_trace("win_mgr_set_layer: Leave"); +} - wl_list_insert(&_ico_win_mgr->client_list, &uclient->link); +/*--------------------------------------------------------------------------*/ +/** + * @brief win_mgr_set_active: set(or change) active surface + * + * @param[in] usurf UIFW surface + * @param[in] target target device + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +win_mgr_set_active(struct uifw_win_surface *usurf, const int target) +{ + struct weston_seat *seat; + struct weston_surface *surface; + int object = target; + wl_fixed_t sx, sy; + + uifw_trace("win_mgr_set_active: Enter(%08x,%x)", (int)usurf, target); + + if ((usurf) && (usurf->shsurf) && (usurf->surface)) { + surface = usurf->surface; + if ((target & (ICO_WINDOW_MGR_ACTIVE_POINTER|ICO_WINDOW_MGR_ACTIVE_KEYBOARD)) == 0) { + surface = NULL; + if (_ico_win_mgr->active_pointer_usurf == usurf) { + object |= ICO_WINDOW_MGR_ACTIVE_POINTER; + } + if (_ico_win_mgr->active_keyboard_usurf == usurf) { + object |= ICO_WINDOW_MGR_ACTIVE_KEYBOARD; + } + } + else { + if (object & ICO_WINDOW_MGR_ACTIVE_POINTER) { + _ico_win_mgr->active_pointer_usurf = usurf; + } + if (object & ICO_WINDOW_MGR_ACTIVE_KEYBOARD) { + _ico_win_mgr->active_keyboard_usurf = usurf; + } + } + } + else { + surface = NULL; + if (target == 0) { + object = ICO_WINDOW_MGR_ACTIVE_POINTER | ICO_WINDOW_MGR_ACTIVE_KEYBOARD; + } + if (object & ICO_WINDOW_MGR_ACTIVE_POINTER) { + _ico_win_mgr->active_pointer_usurf = NULL; + } + if (object & ICO_WINDOW_MGR_ACTIVE_KEYBOARD) { + _ico_win_mgr->active_keyboard_usurf = NULL; + } + } - if (win_mgr_hook_set_user) { - (void) (*win_mgr_hook_set_user) (client, uclient->appid); + wl_list_for_each(seat, &_ico_win_mgr->compositor->seat_list, link) { + if ((object & ICO_WINDOW_MGR_ACTIVE_POINTER) && (seat->pointer)) { + if (surface) { + if (seat->pointer->focus != surface) { + uifw_trace("win_mgr_set_active: pointer change surface(%08x=>%08x)", + (int)seat->pointer->focus, (int)surface); + weston_surface_from_global_fixed(surface, + seat->pointer->x, + seat->pointer->y, + &sx, &sy); + weston_pointer_set_focus(seat->pointer, surface, sx, sy); + } + else { + uifw_trace("win_mgr_set_active: pointer nochange surface(%08x)", + (int)surface); + } + } + else { + uifw_trace("win_mgr_set_active: pointer reset surface(%08x)", + (int)seat->pointer->focus); + weston_pointer_set_focus(seat->pointer, NULL, + wl_fixed_from_int(0), wl_fixed_from_int(0)); + } + } + if ((object & ICO_WINDOW_MGR_ACTIVE_KEYBOARD) && (seat->keyboard)) { + if (surface) { + if (seat->keyboard->focus != surface) { + weston_keyboard_set_focus(seat->keyboard, surface); + uifw_trace("win_mgr_set_active: keyboard change surface(%08x=>%08x)", + (int)seat->keyboard->focus, (int)surface); + } + else { + uifw_trace("win_mgr_set_active: keyboard nochange surface(%08x)", + (int)surface); + } + } + else { + uifw_trace("win_mgr_set_active: keyboard reset surface(%08x)", + (int)seat->keyboard); + weston_keyboard_set_focus(seat->keyboard, NULL); + } + } } - uifw_trace("uifw_set_user: Leave"); + uifw_trace("win_mgr_set_active: Leave(%08x)", (int)usurf); } /*--------------------------------------------------------------------------*/ /** - * @brief uifw_set_eventcb: set event callback flag for HomeScreen + * @brief uifw_declare_manager: declare manager(ex.SystemController) client * * @param[in] client Weyland client * @param[in] resource resource of request - * @param[in] eventcb event callback flag(1=callback, 0=no callback) + * @param[in] manager manager(1=manager, 0=not manager) * @return none */ /*--------------------------------------------------------------------------*/ static void -uifw_set_eventcb(struct wl_client *client, struct wl_resource *resource, int eventcb) +uifw_declare_manager(struct wl_client *client, struct wl_resource *resource, int manager) { struct uifw_manager* mgr; struct uifw_win_surface *usurf; struct uifw_client *uclient; + struct uifw_win_layer *el; - uifw_trace("uifw_set_eventcb: Enter client=%08x eventcb=%d", - (int)client, eventcb); + uifw_trace("uifw_declare_manager: Enter client=%08x manager=%d", + (int)client, manager); uclient = find_client_from_client(client); if (uclient) { - uclient->manager = eventcb; + uclient->manager = manager; } /* client set to manager */ _ico_win_mgr->num_manager = 0; wl_list_for_each (mgr, &_ico_win_mgr->manager_list, link) { if (mgr->resource == resource) { - if (mgr->eventcb != eventcb) { - uifw_trace("uifw_set_eventcb: Event Callback %d=>%d", - mgr->eventcb, eventcb); - mgr->eventcb = eventcb; - - if (eventcb) { - wl_list_for_each (usurf, &_ico_win_mgr->surface_list, link) { - /* send window create event to manager */ - uifw_trace("uifw_set_eventcb: Send manager(%08x) WINDOW_CREATED" - "(surf=%08x,pid=%d,appid=%s)", (int)resource, usurf->id, - usurf->uclient->pid, usurf->uclient->appid); - ico_window_mgr_send_window_created(resource, - usurf->id, usurf->uclient->pid, usurf->uclient->appid); + if (mgr->manager != manager) { + uifw_trace("uifw_declare_manager: Event Client.%08x Callback %d=>%d", + (int)client, mgr->manager, manager); + mgr->manager = manager; + + if (manager) { + wl_list_for_each (el, &_ico_win_mgr->ivi_layer_list, link) { + wl_list_for_each (usurf, &el->surface_list, ivi_layer) { + /* send window create event to manager */ + if (usurf->created != 0) { + uifw_trace("uifw_declare_manager: Send manager(%08x) " + "WINDOW_CREATED(surf=%08x,pid=%d,appid=%s)", + (int)resource, usurf->surfaceid, + usurf->uclient->pid, usurf->uclient->appid); + ico_window_mgr_send_window_created(resource, + usurf->surfaceid, + usurf->winname, + usurf->uclient->pid, + usurf->uclient->appid); + } + } } } } } - if (mgr->eventcb) { + if (mgr->manager) { _ico_win_mgr->num_manager++; } } - uifw_trace("uifw_set_eventcb: Leave(managers=%d)", _ico_win_mgr->num_manager); + uifw_trace("uifw_declare_manager: Leave(managers=%d)", _ico_win_mgr->num_manager); +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief uifw_create_layer: create layer Id and set attribute + * + * @param[in] client Weyland client + * @param[in] resource resource of request + * @param[in] layer layer id + * @param[in] attribute layer attribute + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +uifw_create_layer(struct wl_client *client, struct wl_resource *resource, + uint32_t layer, int32_t attribute) +{ + uifw_trace("uifw_create_layer: Enter(layer=%x,attr=%x)", layer, attribute); + uifw_trace("uifw_create_layer: Leave"); } /*--------------------------------------------------------------------------*/ @@ -881,7 +1254,7 @@ uifw_set_eventcb(struct wl_client *client, struct wl_resource *resource, int eve /*--------------------------------------------------------------------------*/ static void uifw_set_window_layer(struct wl_client *client, struct wl_resource *resource, - uint32_t surfaceid, int32_t layer) + uint32_t surfaceid, uint32_t layer) { uifw_trace("uifw_set_window_layer: Enter res=%08x surfaceid=%08x layer=%d", (int)resource, surfaceid, layer); @@ -889,51 +1262,77 @@ uifw_set_window_layer(struct wl_client *client, struct wl_resource *resource, struct uifw_win_surface *usurf = find_uifw_win_surface_by_id(surfaceid); if (! usurf) { - uifw_trace("uifw_set_window_layer: Leave(No Surface(id=%08x)", surfaceid); + uifw_trace("uifw_set_window_layer: Leave(No Surface(id=%08x))", surfaceid); return; } - else if (usurf->layer != layer) { - usurf->layer = layer; - uifw_trace("uifw_set_window_layer: Set Layer(%d) to Shell Surface", layer); - ivi_shell_set_layer(usurf->shsurf, layer); + if (usurf->win_layer->layer != layer) { + win_mgr_set_layer(usurf, layer); - win_mgr_surface_change(usurf->surface, 1, 1); + win_mgr_change_surface(usurf->surface, 1, 1); } uifw_trace("uifw_set_window_layer: Leave"); } /*--------------------------------------------------------------------------*/ /** - * @brief uifw_set_weston_surface: set weston surface from UIFW surface + * @brief win_mgr_set_weston_surface: set weston surface from UIFW surface * * @param[in] usurf UIFW surface * @return none */ /*--------------------------------------------------------------------------*/ static void -uifw_set_weston_surface(struct uifw_win_surface *usurf) +win_mgr_set_weston_surface(struct uifw_win_surface *usurf) { struct weston_surface *es = usurf->surface; - int width = usurf->width; - int height = usurf->height; - int x = usurf->x; - int y = usurf->y; - - if ((es != NULL) && (es->buffer != NULL)) { - if (usurf->width > es->buffer->width) { - width = es->buffer->width; - x += (usurf->width - es->buffer->width)/2; - } - if (usurf->height > es->buffer->height) { - height = es->buffer->height; - y += (usurf->height - es->buffer->height)/2; - } - } - ivi_shell_set_positionsize(usurf->shsurf, - usurf->x, usurf->y, usurf->width, usurf->height); - uifw_trace("uifw_set_weston_surface: w/h=%d/%d->%d/%d x/y=%d/%d->%d/%d", - usurf->width, usurf->height, width, height, usurf->x, usurf->y, x, y); - ivi_shell_surface_configure(usurf->shsurf, x, y, width, height); + int buf_width, buf_height; + int width; + int height; + int x; + int y; + + if (es == NULL) { + uifw_trace("win_mgr_set_weston_surface: usurf(%08x) has no surface", (int)usurf); + return; + } + + if (es->buffer_ref.buffer != NULL) { + buf_width = weston_surface_buffer_width(es); + buf_height = weston_surface_buffer_height(es); + width = usurf->width; + height = usurf->height; + x = usurf->x; + y = usurf->y; + if ((width <= 0) || (height <= 0)) { + width = buf_width; + usurf->width = buf_width; + height = buf_height; + usurf->height = buf_height; + } + if (usurf->width > buf_width) { + width = buf_width; + x += (usurf->width - buf_width)/2; + } + if (usurf->height > buf_height) { + height = buf_height; + y += (usurf->height - buf_height)/2; + } + if (usurf->visible) { + x += usurf->node_tbl->disp_x; + y += usurf->node_tbl->disp_y; + } + else { + x = ICO_IVI_MAX_COORDINATE+1; + y = ICO_IVI_MAX_COORDINATE+1; + } + if ((es->geometry.x != x) || (es->geometry.y != y) || + (es->geometry.width != width) || (es->geometry.height != height)) { + weston_surface_damage_below(es); + weston_surface_configure(es, x, y, width, height); + } + weston_surface_damage(es); + weston_compositor_schedule_repaint(_ico_win_mgr->compositor); + } } /*--------------------------------------------------------------------------*/ @@ -943,39 +1342,51 @@ uifw_set_weston_surface(struct uifw_win_surface *usurf) * @param[in] client Weyland client * @param[in] resource resource of request * @param[in] surfaceid UIFW surface id + * @param[in] node surface node id * @param[in] x X coordinate on screen(if bigger than 16383, no change) * @param[in] y Y coordinate on screen(if bigger than 16383, no change) * @param[in] width surface width(if bigger than 16383, no change) * @param[in] height surface height(if bigger than 16383, no change) + * @param[in] animation with/without animation * @return none */ /*--------------------------------------------------------------------------*/ static void uifw_set_positionsize(struct wl_client *client, struct wl_resource *resource, - uint32_t surfaceid, - int32_t x, int32_t y, int32_t width, int32_t height) + uint32_t surfaceid, uint32_t node, int32_t x, int32_t y, + int32_t width, int32_t height, int32_t animation) { struct uifw_client *uclient; + struct weston_surface *es; int cx, cy, cwidth, cheight; - uifw_trace("uifw_set_positionsize: Enter res=%08x surf=%08x x/y/w/h=%d/%d/%d/%d", - (int)resource, surfaceid, x, y, width, height); + uifw_trace("uifw_set_positionsize: Enter surf=%08x node=%x x/y/w/h=%d/%d/%d/%d anim=%d", + surfaceid, node, x, y, width, height, animation); + if (((int)node) >= _ico_num_nodes) { + uifw_trace("uifw_set_positionsize: node=%d dose not exist(max=%d)", + node, _ico_num_nodes); + node = 0; + } struct uifw_win_surface* usurf = find_uifw_win_surface_by_id(surfaceid); if (usurf && (usurf->surface)) { /* weston surface exist */ - struct weston_surface *es = usurf->surface; + usurf->node_tbl = &_ico_node_table[node]; + es = usurf->surface; /* if x,y,width,height bigger then ICO_IVI_MAX_COORDINATE, no change */ - ivi_shell_get_positionsize(usurf->shsurf, &cx, &cy, &cwidth, &cheight); + cx = usurf->x; + cy = usurf->y; + cwidth = usurf->width; + cheight = usurf->height; if (x > ICO_IVI_MAX_COORDINATE) x = cx; if (y > ICO_IVI_MAX_COORDINATE) y = cy; if (width > ICO_IVI_MAX_COORDINATE) width = cwidth; if (height > ICO_IVI_MAX_COORDINATE) height = cheight; /* check animation */ - if ((ivi_shell_is_restrain(usurf->shsurf)) && + if ((usurf->animation.restrain_configure != 0) && (x == usurf->x) && (y == usurf->y) && (width == usurf->width) && (height == usurf->height)) { uifw_trace("uifw_set_positionsize: Leave(same position size at animation)"); @@ -994,10 +1405,10 @@ uifw_set_positionsize(struct wl_client *client, struct wl_resource *resource, } uifw_trace("uifw_set_positionsize: Initial Position/Size visible=%d", - ivi_shell_is_visible(usurf->shsurf)); + usurf->visible); /* Initiale position is (0,0) */ - es->geometry.x = 0; - es->geometry.y = 0; + weston_surface_set_position(es, (float)(usurf->node_tbl->disp_x), + (float)(usurf->node_tbl->disp_y)); } uifw_trace("uifw_set_positionsize: Old geometry x/y=%d/%d,w/h=%d/%d", @@ -1008,24 +1419,22 @@ uifw_set_positionsize(struct wl_client *client, struct wl_resource *resource, usurf->y = y; usurf->width = width; usurf->height = height; - ivi_shell_set_positionsize(usurf->shsurf, x, y, width, height); if (_ico_win_mgr->num_manager <= 0) { /* no manager(HomeScreen), set geometory */ - es->geometry.x = x; - es->geometry.y = y; + weston_surface_set_position(es, (float)(usurf->node_tbl->disp_x + x), + (float)(usurf->node_tbl->disp_y + y)); } - if ((es->output) && (es->buffer) && + if ((es->output) && (es->buffer_ref.buffer) && (es->geometry.width > 0) && (es->geometry.height > 0)) { uifw_trace("uifw_set_positionsize: Fixed Geometry, Change(Vis=%d)", - ivi_shell_is_visible(usurf->shsurf)); - uifw_set_weston_surface(usurf); - weston_surface_damage_below(es); - weston_surface_damage(es); - weston_compositor_schedule_repaint(_ico_win_mgr->compositor); + usurf->visible); + if (usurf->visible) { + win_mgr_set_weston_surface(usurf); + } } - win_mgr_surface_change(es, 0, 1); + win_mgr_change_surface(es, 0, 1); - uifw_trace("uifw_set_positionsize: Leave(OK,output=%x)", (int)es->output); + uifw_trace("uifw_set_positionsize: Leave(OK,output=%08x)", (int)es->output); } else { uifw_trace("uifw_set_positionsize: Leave(surf=%08x NOT Found)", surfaceid); @@ -1041,18 +1450,21 @@ uifw_set_positionsize(struct wl_client *client, struct wl_resource *resource, * @param[in] surfaceid UIFW surface id * @param[in] visible visible(1=show/0=hide/other=no change) * @param[in] raise raise(1=raise/0=lower/other=no change) + * @param[in] animation with/without animation * @return none */ /*--------------------------------------------------------------------------*/ static void uifw_set_visible(struct wl_client *client, struct wl_resource *resource, - uint32_t surfaceid, int32_t visible, int32_t raise) + uint32_t surfaceid, int32_t visible, int32_t raise, int32_t animation) { struct uifw_win_surface* usurf; struct uifw_client *uclient; - int animation; + int restack; + int retanim; - uifw_trace("uifw_set_visible: Enter(surf=%08x,%d,%d)", surfaceid, visible, raise); + uifw_trace("uifw_set_visible: Enter(surf=%08x,%d,%d,%d)", + surfaceid, visible, raise, animation); uclient = find_client_from_client(client); if (uclient) { @@ -1075,37 +1487,31 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource, uifw_trace("uifw_set_visible: Leave(Surface Not Exist)"); return; } + restack = 0; - if ((visible == ICO_WINDOW_MGR_VISIBLE_SHOW) || - (visible == ICO_WINDOW_MGR_VISIBLE_SHOW_ANIMATION)) { + if (visible == ICO_WINDOW_MGR_VISIBLE_SHOW) { - if ((usurf->width <= 0) || (usurf->height <= 0)) { - /* not declare surface geometry, initialize */ - usurf->width = usurf->surface->geometry.width; - usurf->height = usurf->surface->geometry.height; - uifw_trace("uifw_set_visible: Set w/h=%d/%d", usurf->width, usurf->height); - } - if (! ivi_shell_is_visible(usurf->shsurf)) { - if (uclient) { - /* manager exist, change to visible */ - ivi_shell_set_visible(usurf->shsurf, 1); - } + if (! usurf->visible) { + usurf->visible = 1; uifw_trace("uifw_set_visible: Change to Visible"); - ivi_shell_set_toplevel(usurf->shsurf); + ico_ivi_shell_set_toplevel(usurf->shsurf); /* Weston surface configure */ - uifw_trace("uifw_set_visible: Visible to Weston WSurf=%08x,%d/%d/%d/%d", - (int)usurf->surface, usurf->x, usurf->y, + uifw_trace("uifw_set_visible: Visible to Weston WSurf=%08x,%d.%d/%d/%d/%d", + (int)usurf->surface, usurf->node_tbl->node, usurf->x, usurf->y, usurf->width, usurf->height); - uifw_set_weston_surface(usurf); - ivi_shell_set_surface_type(usurf->shsurf); + ico_ivi_shell_set_surface_type(usurf->shsurf); + win_mgr_set_weston_surface(usurf); + + restack = 1; /* need damage */ - if ((visible == ICO_WINDOW_MGR_VISIBLE_SHOW_ANIMATION) && - (usurf->animation.type != ICO_WINDOW_MGR_ANIMATION_NONE) && + if ((animation == ICO_WINDOW_MGR_ANIMATION_ANIMATION) && + (usurf->animation.show_name != ICO_WINDOW_MGR_ANIMATION_NONE) && (win_mgr_hook_animation != NULL)) { - animation = (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_OPIN, - (void *)usurf); + retanim = (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_OPSHOW, + (void *)usurf); + uifw_trace("uifw_set_visible: ret call animation = %d", retanim); } } else if ((raise != ICO_WINDOW_MGR_RAISE_LOWER) && @@ -1114,24 +1520,28 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource, return; } } - else if ((visible == ICO_WINDOW_MGR_VISIBLE_HIDE) || - (visible == ICO_WINDOW_MGR_VISIBLE_HIDE_ANIMATION)) { + else if (visible == ICO_WINDOW_MGR_VISIBLE_HIDE) { - if (ivi_shell_is_visible(usurf->shsurf)) { + if (usurf->visible) { /* Weston surface configure */ - uifw_set_weston_surface(usurf); + weston_surface_damage_below(usurf->surface); + win_mgr_set_weston_surface(usurf); - animation = ICO_WINDOW_MGR_ANIMATION_RET_ANIMA; - if ((visible == ICO_WINDOW_MGR_VISIBLE_HIDE_ANIMATION) && - (usurf->animation.type > 0) && + retanim = ICO_WINDOW_MGR_ANIMATION_RET_ANIMA; + if ((animation == ICO_WINDOW_MGR_ANIMATION_ANIMATION) && + (usurf->animation.hide_name != ICO_WINDOW_MGR_ANIMATION_NONE) && (win_mgr_hook_animation != NULL)) { - animation = (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_OPOUT, - (void *)usurf); + retanim = (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_OPHIDE, + (void *)usurf); } - if (animation != ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW) { - ivi_shell_set_visible(usurf->shsurf, 0); + if (retanim != ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW) { + usurf->visible = 0; uifw_trace("uifw_set_visible: Change to UnVisible"); + /* change visible to unvisible, restack surface list */ + restack = 1; + /* Weston surface configure */ + win_mgr_set_weston_surface(usurf); } else { uifw_trace("uifw_set_visible: UnVisible but animation"); @@ -1150,25 +1560,33 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource, } /* raise/lower */ - if ((raise == ICO_WINDOW_MGR_RAISE_LOWER) || (raise != ICO_WINDOW_MGR_RAISE_RAISE)) { - ivi_shell_set_raise(usurf->shsurf, raise); + if ((raise == ICO_WINDOW_MGR_RAISE_LOWER) || (raise == ICO_WINDOW_MGR_RAISE_RAISE)) { + win_mgr_set_raise(usurf, raise); + if (usurf->visible == 0) { + restack |= 2; + } + } + else { + raise = ICO_WINDOW_MGR_V_NOCHANGE; } - if ((usurf->surface) && (usurf->surface->buffer) && (usurf->surface->output)) { - weston_surface_damage_below(usurf->surface); + if ((restack == 1) && (usurf->surface) && + (usurf->surface->buffer_ref.buffer) && (usurf->surface->output)) { weston_surface_damage(usurf->surface); - weston_compositor_schedule_repaint(_ico_win_mgr->compositor); } - /* send event(VISIBLE) to manager */ - ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_VISIBLE, - surfaceid, NULL, - (visible == ICO_WINDOW_MGR_VISIBLE_SHOW) || - (visible == ICO_WINDOW_MGR_VISIBLE_SHOW_ANIMATION) ? 1 : - ((visible == ICO_WINDOW_MGR_VISIBLE_HIDE) || - (visible == ICO_WINDOW_MGR_VISIBLE_HIDE_ANIMATION) ? 0 : - ICO_WINDOW_MGR_VISIBLE_NOCHANGE), - raise, uclient ? 0 : 1, 0,0,0); + else if(restack & 2) { + win_mgr_restack_ivi_layer(usurf); + } + /* send event(VISIBLE) to manager */ + if (restack) { + ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_VISIBLE, + usurf, + (visible == ICO_WINDOW_MGR_VISIBLE_SHOW) ? 1 : + ((visible == ICO_WINDOW_MGR_VISIBLE_HIDE) ? 0 : + ICO_WINDOW_MGR_V_NOCHANGE), + raise, uclient ? 0 : 1, 0,0); + } uifw_trace("uifw_set_visible: Leave(OK)"); } @@ -1179,6 +1597,7 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource, * @param[in] client Weyland client * @param[in] resource resource of request * @param[in] surfaceid UIFW surface id + * @param[in] type how to change surface * @param[in] anmation animation name * @param[in] time animation time(ms), if 0, default time * @return none @@ -1186,23 +1605,64 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource, /*--------------------------------------------------------------------------*/ static void uifw_set_animation(struct wl_client *client, struct wl_resource *resource, - uint32_t surfaceid, const char *animation, int time) + uint32_t surfaceid, int32_t type, const char *animation, int32_t time) { + int animaid; struct uifw_win_surface* usurf = find_uifw_win_surface_by_id(surfaceid); - uifw_trace("uifw_set_transition: Enter(surf=%08x, animation=%s, time=%d)", - surfaceid, animation, time); + uifw_trace("uifw_set_transition: Enter(surf=%08x,type=%x,anim=%s,time=%d)", + surfaceid, type, animation, time); if (usurf) { if ((*animation != 0) && (*animation != ' ')) { - usurf->animation.type_next = ico_get_animation_type(animation); - uifw_trace("uifw_set_animation: Leave(OK) type=%d", usurf->animation.type_next); - if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_NONE) { - usurf->animation.type = usurf->animation.type_next; + animaid = ico_get_animation_name(animation); + uifw_trace("uifw_set_animation: Leave(OK) type=%d", animaid); + if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_HIDE) { + if (usurf->animation.type == ICO_WINDOW_MGR_ANIMATION_OPHIDE) { + usurf->animation.next_name = animaid; + } + else { + usurf->animation.hide_name = animaid; + } + } + if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_SHOW) { + if (usurf->animation.type == ICO_WINDOW_MGR_ANIMATION_OPSHOW) { + usurf->animation.next_name = animaid; + } + else { + usurf->animation.show_name = animaid; + } + } + if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_MOVE) { + if (usurf->animation.type == ICO_WINDOW_MGR_ANIMATION_OPMOVE) { + usurf->animation.next_name = animaid; + } + else { + usurf->animation.move_name = animaid; + } + } + if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_RESIZE) { + if (usurf->animation.type == ICO_WINDOW_MGR_ANIMATION_OPRESIZE) { + usurf->animation.next_name = animaid; + } + else { + usurf->animation.resize_name = animaid; + } } } - if (time > 0) { - usurf->animation.time = time; + if ((time > 0) && (time != ICO_WINDOW_MGR_V_NOCHANGE)) { + if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_HIDE) { + usurf->animation.hide_time = time; + } + if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_SHOW) { + usurf->animation.show_time = time; + } + if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_MOVE) { + usurf->animation.move_time = time; + } + if (type & ICO_WINDOW_MGR_ANIMATION_TYPE_RESIZE) { + usurf->animation.resize_time = time; + } } } else { @@ -1217,105 +1677,104 @@ uifw_set_animation(struct wl_client *client, struct wl_resource *resource, * @param[in] client Weyland client * @param[in] resource resource of request * @param[in] surfaceid UIFW surface id - * @param[in] target target device + * @param[in] active target device * @return none */ /*--------------------------------------------------------------------------*/ static void uifw_set_active(struct wl_client *client, struct wl_resource *resource, - uint32_t surfaceid, uint32_t target) + uint32_t surfaceid, int32_t active) { struct uifw_win_surface* usurf; - uifw_trace("uifw_set_active: Enter(surf=%08x,target=%x)", surfaceid, target); + uifw_trace("uifw_set_active: Enter(surf=%08x,active=%x)", surfaceid, active); if ((surfaceid > 0) && - ((target & (ICO_IVI_SHELL_ACTIVE_POINTER|ICO_IVI_SHELL_ACTIVE_KEYBOARD)) != 0)) { + ((active & (ICO_WINDOW_MGR_ACTIVE_POINTER|ICO_WINDOW_MGR_ACTIVE_KEYBOARD)) != 0)) { usurf = find_uifw_win_surface_by_id(surfaceid); } else { usurf = NULL; } if (usurf) { - switch (target & (ICO_IVI_SHELL_ACTIVE_POINTER|ICO_IVI_SHELL_ACTIVE_KEYBOARD)) { - case ICO_IVI_SHELL_ACTIVE_POINTER: - if (usurf != _ico_win_mgr->active_pointer_surface) { - if (_ico_win_mgr->active_pointer_surface) { + switch (active & (ICO_WINDOW_MGR_ACTIVE_POINTER|ICO_WINDOW_MGR_ACTIVE_KEYBOARD)) { + case ICO_WINDOW_MGR_ACTIVE_POINTER: + if (usurf != _ico_win_mgr->active_pointer_usurf) { + if (_ico_win_mgr->active_pointer_usurf) { ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE, - _ico_win_mgr->active_pointer_surface->id, NULL, - (_ico_win_mgr->active_keyboard_surface == - _ico_win_mgr->active_pointer_surface) ? - ICO_IVI_SHELL_ACTIVE_KEYBOARD : - ICO_IVI_SHELL_ACTIVE_NONE, - 0,0,0,0,0); + _ico_win_mgr->active_pointer_usurf, + (_ico_win_mgr->active_keyboard_usurf == + _ico_win_mgr->active_pointer_usurf) ? + ICO_WINDOW_MGR_ACTIVE_KEYBOARD : + ICO_WINDOW_MGR_ACTIVE_NONE, + 0,0,0,0); } - _ico_win_mgr->active_pointer_surface = usurf; + _ico_win_mgr->active_pointer_usurf = usurf; ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE, - surfaceid, NULL, - ICO_IVI_SHELL_ACTIVE_POINTER | - (_ico_win_mgr->active_keyboard_surface == usurf) ? - ICO_IVI_SHELL_ACTIVE_KEYBOARD : 0, - 0,0,0,0,0); - ivi_shell_set_active(usurf->shsurf, ICO_IVI_SHELL_ACTIVE_POINTER); + usurf, + ICO_WINDOW_MGR_ACTIVE_POINTER | + (_ico_win_mgr->active_keyboard_usurf == usurf) ? + ICO_WINDOW_MGR_ACTIVE_KEYBOARD : 0, + 0,0,0,0); + win_mgr_set_active(usurf, ICO_WINDOW_MGR_ACTIVE_POINTER); } break; - case ICO_IVI_SHELL_ACTIVE_KEYBOARD: - if (usurf != _ico_win_mgr->active_keyboard_surface) { - if (_ico_win_mgr->active_keyboard_surface) { + case ICO_WINDOW_MGR_ACTIVE_KEYBOARD: + if (usurf != _ico_win_mgr->active_keyboard_usurf) { + if (_ico_win_mgr->active_keyboard_usurf) { ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE, - _ico_win_mgr->active_keyboard_surface->id, NULL, - (_ico_win_mgr->active_keyboard_surface == - _ico_win_mgr->active_pointer_surface) ? - ICO_IVI_SHELL_ACTIVE_POINTER : - ICO_IVI_SHELL_ACTIVE_NONE, - 0,0,0,0,0); + _ico_win_mgr->active_keyboard_usurf, + (_ico_win_mgr->active_keyboard_usurf == + _ico_win_mgr->active_pointer_usurf) ? + ICO_WINDOW_MGR_ACTIVE_POINTER : + ICO_WINDOW_MGR_ACTIVE_NONE, + 0,0,0,0); } - _ico_win_mgr->active_keyboard_surface = usurf; + _ico_win_mgr->active_keyboard_usurf = usurf; ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE, - surfaceid, NULL, - ICO_IVI_SHELL_ACTIVE_KEYBOARD | - (_ico_win_mgr->active_pointer_surface == usurf) ? - ICO_IVI_SHELL_ACTIVE_POINTER : 0, - 0,0,0,0,0); - ivi_shell_set_active(usurf->shsurf, ICO_IVI_SHELL_ACTIVE_KEYBOARD); + usurf, + ICO_WINDOW_MGR_ACTIVE_KEYBOARD | + (_ico_win_mgr->active_pointer_usurf == usurf) ? + ICO_WINDOW_MGR_ACTIVE_POINTER : 0, + 0,0,0,0); + win_mgr_set_active(usurf, ICO_WINDOW_MGR_ACTIVE_KEYBOARD); } break; default: - if ((usurf != _ico_win_mgr->active_pointer_surface) || - (usurf != _ico_win_mgr->active_keyboard_surface)) { - if (_ico_win_mgr->active_pointer_surface) { + if ((usurf != _ico_win_mgr->active_pointer_usurf) || + (usurf != _ico_win_mgr->active_keyboard_usurf)) { + if (_ico_win_mgr->active_pointer_usurf) { ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE, - _ico_win_mgr->active_pointer_surface->id, - NULL, ICO_IVI_SHELL_ACTIVE_NONE, - 0,0,0,0,0); - if (_ico_win_mgr->active_keyboard_surface == - _ico_win_mgr->active_pointer_surface) { - _ico_win_mgr->active_keyboard_surface = NULL; + _ico_win_mgr->active_pointer_usurf, + ICO_WINDOW_MGR_ACTIVE_NONE, + 0,0,0,0); + if (_ico_win_mgr->active_keyboard_usurf == + _ico_win_mgr->active_pointer_usurf) { + _ico_win_mgr->active_keyboard_usurf = NULL; } } - if (_ico_win_mgr->active_keyboard_surface) { + if (_ico_win_mgr->active_keyboard_usurf) { ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE, - _ico_win_mgr->active_keyboard_surface->id, - NULL, ICO_IVI_SHELL_ACTIVE_NONE, - 0,0,0,0,0); + _ico_win_mgr->active_keyboard_usurf, + ICO_WINDOW_MGR_ACTIVE_NONE, + 0,0,0,0); } - _ico_win_mgr->active_pointer_surface = usurf; - _ico_win_mgr->active_keyboard_surface = usurf; + _ico_win_mgr->active_pointer_usurf = usurf; + _ico_win_mgr->active_keyboard_usurf = usurf; ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE, - surfaceid, NULL, - ICO_IVI_SHELL_ACTIVE_POINTER | - ICO_IVI_SHELL_ACTIVE_KEYBOARD, - 0,0,0,0,0); - ivi_shell_set_active(usurf->shsurf, - ICO_IVI_SHELL_ACTIVE_POINTER | - ICO_IVI_SHELL_ACTIVE_KEYBOARD); + usurf, + ICO_WINDOW_MGR_ACTIVE_POINTER | + ICO_WINDOW_MGR_ACTIVE_KEYBOARD, + 0,0,0,0); + win_mgr_set_active(usurf, ICO_WINDOW_MGR_ACTIVE_POINTER | + ICO_WINDOW_MGR_ACTIVE_KEYBOARD); } break; } uifw_trace("uifw_set_active: Leave(Change Active)"); } else { - ivi_shell_set_active(NULL, target); + win_mgr_set_active(NULL, active); uifw_trace("uifw_set_active: Leave(Reset active surface)"); } } @@ -1333,92 +1792,125 @@ uifw_set_active(struct wl_client *client, struct wl_resource *resource, /*--------------------------------------------------------------------------*/ static void uifw_set_layer_visible(struct wl_client *client, struct wl_resource *resource, - int32_t layer, int32_t visible) + uint32_t layer, int32_t visible) { + struct uifw_win_layer *el; + struct uifw_win_layer *new_el; + struct uifw_win_surface *usurf; + uifw_trace("uifw_set_layer_visible: Enter(layer=%d, visilbe=%d)", layer, visible); - ivi_shell_set_layer_visible(layer, visible); + /* Search Layer */ + wl_list_for_each (el, &_ico_win_mgr->ivi_layer_list, link) { + if (el->layer == layer) break; + } + + if (&el->link == &_ico_win_mgr->ivi_layer_list) { + /* layer not exist, create new layer */ + uifw_trace("uifw_set_layer_visible: New Layer %d", layer); + new_el = win_mgr_create_layer(NULL, layer); + if (! new_el) { + uifw_trace("uifw_set_layer_visible: Leave(No Memory)"); + return; + } + new_el->visible = (visible != 0) ? TRUE : FALSE; + ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_LAYER_VISIBLE, NULL, + layer, new_el->visible, 0,0,0); + uifw_trace("uifw_set_layer_visible: Leave(new layer)"); + return; + } + + /* control all surface in layer */ + if ((el->visible != FALSE) && (visible == 0)) { + /* layer change to NOT visible */ + uifw_trace("uifw_set_layer_visible: change to not visible"); + el->visible = FALSE; + } + else if ((el->visible == FALSE) && (visible != 0)) { + /* layer change to visible */ + uifw_trace("uifw_set_layer_visible: change to visible"); + el->visible = TRUE; + } + else { + /* no change */ + uifw_trace("uifw_set_layer_visible: Leave(no Change %d=>%d)", + el->visible, visible); + return; + } + + /* set damege area */ + wl_list_for_each (usurf, &el->surface_list, ivi_layer) { + if ((usurf->visible != FALSE) && (usurf->surface != NULL) && + (usurf->surface->output != NULL)) { + /* Damage(redraw) target surface */ + weston_surface_damage_below(usurf->surface); + } + } + + /* rebild compositor surface list */ + win_mgr_restack_ivi_layer(NULL); + + /* send layer visible event to manager */ + ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_LAYER_VISIBLE, NULL, + layer, el->visible, 0,0,0); uifw_trace("uifw_set_layer_visible: Leave"); } /*--------------------------------------------------------------------------*/ /** - * @brief uifw_set_client_attr: set client application attribute + * @brief uifw_get_surfaces: get application surfaces * * @param[in] client Weyland client * @param[in] resource resource of request - * @param[in] appid client application name - * @param[in] attr attribute - * @param[in] value attribute value + * @param[in] appid application id * @return none */ /*--------------------------------------------------------------------------*/ static void -uifw_set_client_attr(struct wl_client *client, struct wl_resource *resource, - const char *appid, int32_t attr, int32_t value) +uifw_get_surfaces(struct wl_client *client, struct wl_resource *resource, const char *appid) { - struct uifw_client_attr *lattr; - struct uifw_client *uclient; - int idx, freeidx; - - uifw_trace("uifw_set_client_attr: Enter(appid=%s, attr=%d, value=%d)", - appid, attr, value); - - freeidx = -1; - wl_list_for_each (lattr, &_ico_win_mgr->client_attr_list, link) { - if (strcmp(lattr->appid, appid) == 0) { - for (idx = 0; idx < MAX_CLIENT_ATTR; idx++) { - if (lattr->attrs[idx].attr == attr) { - lattr->attrs[idx].value = value; - freeidx = 999; - break; - } - if ((freeidx < 0) && (lattr->attrs[idx].attr < 0)) { - freeidx = idx; - } - } - if ((idx >= MAX_CLIENT_ATTR) && (freeidx >= 0)) { - lattr->attrs[freeidx].attr = attr; - lattr->attrs[freeidx].value = value; - } - else { - freeidx = 998; - } - break; - } - } - if (freeidx < 0) { - lattr = malloc(sizeof(struct uifw_client_attr)); - if (lattr) { - memset(lattr, 0, sizeof(struct uifw_client_attr)); - strncpy(lattr->appid, appid, ICO_IVI_APPID_LENGTH-1); - for (idx = 1; idx < MAX_CLIENT_ATTR; idx++) { - lattr->attrs[idx].attr = -1; - } - lattr->attrs[0].attr = attr; - lattr->attrs[0].value = value; - wl_list_insert(&_ico_win_mgr->client_attr_list, &lattr->link); - } - } + uifw_trace("uifw_get_surfaces: Enter(appid=%s)", appid); + uifw_trace("uifw_get_surfaces: Leave"); +} - wl_list_for_each (uclient, &_ico_win_mgr->client_list, link) { - if (strcmp(uclient->appid, appid) == 0) { - switch(attr) { - case ICO_WINDOW_MGR_CLIENT_ATTR_NOCONFIGURE: - uclient->noconfigure = value; - ivi_shell_set_client_attr(uclient->client, - ICO_CLEINT_ATTR_NOCONFIGURE, value); - uifw_trace("uifw_set_client_attr: set to ivi-shell"); - break; - default: - uifw_trace("uifw_set_client_attr: Unknown attr(%d)", attr); - break; - } - break; - } - } - uifw_trace("uifw_set_client_attr: Leave"); +/*--------------------------------------------------------------------------*/ +/** + * @brief uifw_map_surface: map surface buffer to shared memory + * + * @param[in] client Weyland client + * @param[in] resource resource of request + * @param[in] surfaceid surface id + * @param[in] mapname shared memory map name + * @param[in] framerate frame rate of shared memory update(frame/sec) + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +uifw_map_surface(struct wl_client *client, struct wl_resource *resource, + uint32_t surfaceid, const char *mapname, int32_t framerate) +{ + uifw_trace("uifw_map_surface: Enter(surface=%08x,map=%s,fps=%d)", + surfaceid, mapname, framerate); + uifw_trace("uifw_map_surface: Leave"); +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief uifw_unmap_surface: unmap surface buffer to shared memory + * + * @param[in] client Weyland client + * @param[in] resource resource of request + * @param[in] surfaceid surface id + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +uifw_unmap_surface(struct wl_client *client, struct wl_resource *resource, + uint32_t surfaceid) +{ + uifw_trace("uifw_map_surface: Enter(surface=%08x)", surfaceid); + uifw_trace("uifw_map_surface: Leave"); } /*--------------------------------------------------------------------------*/ @@ -1452,8 +1944,7 @@ win_mgr_surface_change_mgr(struct weston_surface *surface, } num_mgr = ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CONFIGURE, - usurf->id, usurf->uclient->appid, usurf->layer, - x, y, width, height, 1); + usurf, x, y, width, height, 1); uifw_trace("win_mgr_surface_change_mgr: Leave(%d)", num_mgr); return num_mgr; @@ -1461,7 +1952,7 @@ win_mgr_surface_change_mgr(struct weston_surface *surface, /*--------------------------------------------------------------------------*/ /** - * @brief win_mgr_surface_change: surface change + * @brief win_mgr_change_surface: surface change * * @param[in] surface Weston surface * @param[in] to destination(0=Client&Manager,1=Client,-1=Manager) @@ -1470,97 +1961,321 @@ win_mgr_surface_change_mgr(struct weston_surface *surface, */ /*--------------------------------------------------------------------------*/ static void -win_mgr_surface_change(struct weston_surface *surface, const int to, const int manager) +win_mgr_change_surface(struct weston_surface *surface, const int to, const int manager) { struct uifw_win_surface *usurf; + int x; + int y; - uifw_trace("win_mgr_surface_change: Enter(%08x,%d,%d)", (int)surface, to, manager); + uifw_trace("win_mgr_change_surface: Enter(%08x,%d,%d)", (int)surface, to, manager); /* Find surface */ usurf = find_uifw_win_surface_by_ws(surface); if (! usurf) { - uifw_trace("win_mgr_surface_change: Leave(Not Exist)"); + uifw_trace("win_mgr_change_surface: Leave(Not Exist)"); return; } + /* if not configure surface, set surface size */ + if (((usurf->width <= 0) || (usurf->height <= 0)) && (usurf->surface)) { + uifw_trace("win_mgr_change_surface: set surface x/y=%d/%d=>%d/%d w/h=%d/%d=>%d/%d", + (int)usurf->surface->geometry.x, (int)usurf->surface->geometry.y, + usurf->x, usurf->y, usurf->width, usurf->height, + usurf->surface->geometry.width, usurf->surface->geometry.height); + usurf->width = usurf->surface->geometry.width; + usurf->height = usurf->surface->geometry.height; + if (usurf->visible) { + weston_surface_set_position(usurf->surface, + (float)(usurf->node_tbl->disp_x + usurf->x), + (float)(usurf->node_tbl->disp_y + usurf->y)); + win_mgr_restack_ivi_layer(usurf); + } + else { + weston_surface_set_position(usurf->surface, (float)(ICO_IVI_MAX_COORDINATE+1), + (float)(ICO_IVI_MAX_COORDINATE+1)); + } + } + /* send wayland event to client */ - if ((to >= 0) && (usurf->shsurf != NULL) && (manager !=0)) { - uifw_trace("win_mgr_surface_change: Send SHELL_SURFACE_CONFIGURE(%08x,w/h=%d/%d)", - usurf->id, usurf->width, usurf->height); - ivi_shell_send_configure(usurf->shsurf, usurf->id, - (WL_SHELL_SURFACE_RESIZE_RIGHT | - WL_SHELL_SURFACE_RESIZE_BOTTOM), - usurf->width, usurf->height); + if ((to >= 0) && (usurf->shsurf != NULL) && (manager !=0) && + (usurf->width > 0) && (usurf->height > 0)) { + uifw_trace("win_mgr_change_surface: SHELL_SURFACE_CONFIGURE %08x(%08x),w/h=%d/%d ", + usurf->surfaceid, (int)usurf->surface, usurf->width, usurf->height); + ico_ivi_shell_send_configure(usurf->surface, + WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, + usurf->width, usurf->height); + } + + if (usurf->visible) { + x = usurf->node_tbl->disp_x + usurf->x; + y = usurf->node_tbl->disp_y + usurf->y; + } + else { + x = ICO_IVI_MAX_COORDINATE+1; + y = ICO_IVI_MAX_COORDINATE+1; + } + /* change geometry if request from manager */ + if (manager) { + if ((usurf->width != usurf->surface->geometry.width) || + (usurf->height != usurf->surface->geometry.height) || + (usurf->surface->geometry.x != (float)x) || + (usurf->surface->geometry.y != (float)y)) { + weston_surface_configure(usurf->surface, (float)x, (float)y, + usurf->width, usurf->height); + weston_compositor_schedule_repaint(_ico_win_mgr->compositor); + } } /* send manager event to HomeScreen */ if (to <= 0) { - ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CONFIGURE, - usurf->id, usurf->uclient->appid, usurf->layer, - usurf->x, usurf->y, usurf->width, usurf->height, - (manager != 0) ? 0 : 1); + if (manager) { + ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CONFIGURE, + usurf, usurf->x, usurf->y, + usurf->width, usurf->height, 0); + } + else { + ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CONFIGURE, + usurf, (int)usurf->surface->geometry.x, + (int)usurf->surface->geometry.y, + usurf->surface->geometry.width, + usurf->surface->geometry.height, 1); + } + } + + /* change geometry if request from client */ + if (! manager) { + if ((usurf->width != usurf->surface->geometry.width) || + (usurf->height != usurf->surface->geometry.height) || + (usurf->surface->geometry.x != (float)x) || + (usurf->surface->geometry.y != (float)y)) { + weston_surface_configure(usurf->surface, (float)x, (float)y, + usurf->width, usurf->height); + weston_compositor_schedule_repaint(_ico_win_mgr->compositor); + } } - uifw_trace("win_mgr_surface_change: Leave(OK)"); + uifw_trace("win_mgr_change_surface: Leave(OK)"); } /*--------------------------------------------------------------------------*/ /** - * @brief win_mgr_surface_select: select surface by Bottun/Touch + * @brief win_mgr_select_surface: select surface by Bottun/Touch * * @param[in] surface Weston surface * @return none */ /*--------------------------------------------------------------------------*/ static void -win_mgr_surface_select(struct weston_surface *surface) +win_mgr_select_surface(struct weston_surface *surface) { struct uifw_win_surface *usurf; - uifw_trace("win_mgr_surface_select: Enter(%08x)", (int)surface); + uifw_trace("win_mgr_select_surface: Enter(%08x)", (int)surface); /* find surface */ usurf = find_uifw_win_surface_by_ws(surface); if (! usurf) { - uifw_trace("win_mgr_surface_select: Leave(Not Exist)"); + uifw_trace("win_mgr_select_surface: Leave(Not Exist)"); + return; + } + if (usurf != _ico_win_mgr->active_pointer_usurf) { + + /* send active event to manager */ + if (ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE, + usurf, ICO_WINDOW_MGR_ACTIVE_SELECTED, 0,0,0,0) <= 0) { + uifw_trace("win_mgr_select_surface: not found manager, set active"); + win_mgr_set_active(usurf, ICO_WINDOW_MGR_ACTIVE_POINTER | + ICO_WINDOW_MGR_ACTIVE_KEYBOARD); + } + } + uifw_trace("win_mgr_select_surface: Leave(OK)"); +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief win_mgr_set_title: set tile name to surface + * + * @param[in] surface weston surface + * @param[in] title title name + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +win_mgr_set_title(struct weston_surface *surface, const char *title) +{ + struct uifw_win_surface *usurf; + + uifw_trace("win_mgr_set_title: Enter(%08x) name=%s", (int)surface, title); + + usurf = find_uifw_win_surface_by_ws(surface); + if (! usurf) { + uifw_trace("win_mgr_set_title: Leave(Not Exist)"); return; } + if (((usurf->width > 0) && (usurf->height > 0)) && + ((usurf->created == 0) || + (strncmp(title, usurf->winname, ICO_IVI_WINNAME_LENGTH-1) != 0))) { + strncpy(usurf->winname, title, ICO_IVI_WINNAME_LENGTH-1); + usurf->winname[ICO_IVI_WINNAME_LENGTH-1] = 0; + if (usurf->created == 0) { + ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CREATED, usurf, 0,0,0,0,0); + usurf->created = 1; + } + else { + ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_NAME, usurf, 0,0,0,0,0); + } + } + else { + strncpy(usurf->winname, title, ICO_IVI_WINNAME_LENGTH-1); + usurf->winname[ICO_IVI_WINNAME_LENGTH-1] = 0; + } + uifw_trace("win_mgr_set_title: Leave"); +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief win_mgr_surface_move: set tile name to surface + * + * @param[in] surface weston surface + * @param[in] title title name + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +win_mgr_surface_move(struct weston_surface *surface, int *dx, int *dy) +{ + struct uifw_win_surface *usurf; - /* send active event to manager */ - ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_ACTIVE, - usurf->id, NULL, ICO_IVI_SHELL_ACTIVE_SELECTED, 0,0,0,0,0); + uifw_trace("win_mgr_surface_move: Enter(%08x) x/y=%d,%d", (int)surface, *dx, *dy); - uifw_trace("win_mgr_surface_select: Leave(OK)"); + usurf = find_uifw_win_surface_by_ws(surface); + if (! usurf) { + uifw_trace("win_mgr_surface_move: Leave(Not Exist)"); + return; + } + if (usurf->visible) { + *dx = usurf->node_tbl->disp_x + usurf->x; + *dy = usurf->node_tbl->disp_y + usurf->y; + } + else { + *dx = ICO_IVI_MAX_COORDINATE+1; + *dy = ICO_IVI_MAX_COORDINATE+1; + } + uifw_trace("win_mgr_surface_move: Leave(change to x/y=%d/%d)", *dx, *dy); } /*--------------------------------------------------------------------------*/ /** - * @brief win_mgr_surface_destroy: surface destroy + * @brief ico_window_mgr_set_visible: change surface visibility + * + * @param[in] usurf UIFW surface + * @param[in] visible visible(=1)/unvisible(0) + * @return none + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT void +ico_window_mgr_set_visible(struct uifw_win_surface *usurf, const int visible) +{ + if (visible) { + if (usurf->visible == 0) { + uifw_trace("ico_window_mgr_set_visible: Chagne to Visible(%08x)", (int)usurf); + usurf->visible = 1; + /* change unvisible to visible, restack surface list */ + win_mgr_restack_ivi_layer(usurf); + } + } + else { + if (usurf->visible != 0) { + uifw_trace("ico_window_mgr_set_visible: Chagne to Unvisible(%08x)", (int)usurf); + usurf->visible = 0; + /* change visible to unvisible, restack surface list */ + win_mgr_restack_ivi_layer(usurf); + } + } + ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_VISIBLE, + usurf, usurf->visible, usurf->raise, 0, 0,0); +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief win_mgr_set_raise: change surface raise/lower + * + * @param[in] usurf UIFW surface + * @param[in] raise raise(=1)/lower(0) + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +win_mgr_set_raise(struct uifw_win_surface *usurf, const int raise) +{ + uifw_trace("win_mgr_set_raise: Enter(%08x,%d) layer=%x", + (int)usurf, raise, (int)usurf->win_layer->layer); + + wl_list_remove(&usurf->ivi_layer); + if (raise) { + /* raise ... surface stack to top of layer */ + wl_list_insert(&usurf->win_layer->surface_list, &usurf->ivi_layer); + usurf->raise = 1; + uifw_trace("win_mgr_set_raise: Raise Link to Top"); + } + else { + /* Lower ... surface stack to bottom of layer */ + wl_list_insert(usurf->win_layer->surface_list.prev, &usurf->ivi_layer); + usurf->raise = 0; + uifw_trace("win_mgr_set_raise: Lower Link to Bottom"); + } + + /* rebild compositor surface list */ + if (usurf->visible) { + win_mgr_restack_ivi_layer(usurf); + } + ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_VISIBLE, + usurf, usurf->visible, usurf->raise, 0, 0,0); + + uifw_trace("win_mgr_set_raise: Leave"); +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief win_mgr_destroy_surface: surface destroy * * @param[in] surface Weston surface * @return none */ /*--------------------------------------------------------------------------*/ static void -win_mgr_surface_destroy(struct weston_surface *surface) +win_mgr_destroy_surface(struct weston_surface *surface) { struct uifw_win_surface *usurf; struct uifw_win_surface *phash; struct uifw_win_surface *bhash; uint32_t hash; - uifw_trace("win_mgr_surface_destroy: Enter(%08x)", (int)surface); - usurf = find_uifw_win_surface_by_ws(surface); if (! usurf) { - uifw_trace("win_mgr_surface_destroy: Leave(Not Exist)"); + uifw_trace("win_mgr_destroy_surface: UIFW surface Not Exist"); return; } + uifw_trace("win_mgr_destroy_surface: Enter(%08x) %08x", (int)surface, usurf->surfaceid); + + /* destroy active surface */ + if (usurf == _ico_win_mgr->active_pointer_usurf) { + _ico_win_mgr->active_pointer_usurf = NULL; + } + if (usurf == _ico_win_mgr->active_keyboard_usurf) { + _ico_win_mgr->active_keyboard_usurf = NULL; + } /* destory animation extenson */ if (win_mgr_hook_animation) { (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_DESTROY, (void *)usurf); } - hash = MAKE_IDHASH(usurf->id); + + /* delete from layer list */ + wl_list_remove(&usurf->ivi_layer); + win_mgr_restack_ivi_layer(NULL); + + /* delete from hash table */ + hash = MAKE_IDHASH(usurf->surfaceid); phash = _ico_win_mgr->idhash[hash]; bhash = NULL; while ((phash) && (phash != usurf)) { @@ -1588,21 +2303,14 @@ win_mgr_surface_destroy(struct weston_surface *surface) _ico_win_mgr->wshash[hash] = usurf->next_wshash; } - wl_list_remove(&usurf->link); - wl_list_init(&usurf->link); - ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_DESTROYED, - usurf->id, NULL, 0,0,0,0,0,0); + usurf, 0,0,0,0,0); - hash = usurf->id & SURCAFE_ID_MASK; + hash = usurf->surfaceid & SURCAFE_ID_MASK; _ico_win_mgr->surfaceid_map[(hash - 1)/16] &= ~(1 << ((hash - 1) % 16)); free(usurf); - - if (win_mgr_hook_destroy) { - (void) (*win_mgr_hook_destroy) (surface); - } - uifw_trace("win_mgr_surface_destroy: Leave(OK)"); + uifw_trace("win_mgr_destroy_surface: Leave(OK)"); } /*--------------------------------------------------------------------------*/ @@ -1620,16 +2328,25 @@ static void bind_ico_win_mgr(struct wl_client *client, void *data, uint32_t version, uint32_t id) { - struct wl_resource *add_resource; + struct wl_resource *add_resource; struct uifw_manager *nm; + struct uifw_client *uclient; uifw_trace("bind_ico_win_mgr: Enter(client=%08x, id=%x)", (int)client, (int)id); - add_resource = wl_client_add_object(client, &ico_window_mgr_interface, - &ico_window_mgr_implementation, id, _ico_win_mgr); - add_resource->destroy = unbind_ico_win_mgr; + add_resource = wl_resource_create(client, &ico_window_mgr_interface, 1, id); + if (add_resource) { + wl_resource_set_implementation(add_resource, &ico_window_mgr_implementation, + _ico_win_mgr, unbind_ico_win_mgr); + } + + /* Create client management tabel */ + uclient = find_client_from_client(client); + if (! uclient) { + win_mgr_bind_client(client, NULL); + } - /* Manager */ + /* Manager */ nm = (struct uifw_manager *)malloc(sizeof(struct uifw_manager)); memset(nm, 0, sizeof(struct uifw_manager)); nm->resource = add_resource; @@ -1661,99 +2378,123 @@ unbind_ico_win_mgr(struct wl_resource *resource) free(mgr); } else { - if (mgr->eventcb) { + if (mgr->manager) { _ico_win_mgr->num_manager++; } } } - - free(resource); uifw_trace("unbind_ico_win_mgr: Leave"); } /*--------------------------------------------------------------------------*/ /** - * @brief ico_winmgr_usurf_2_node: get surface nodeId - * - * @param[in] surfaceid UIFW surface id - * @return node id - * @retval >= 0 success(surface node id) - * @retval < 0 error(surface id dose not exist) - */ -/*--------------------------------------------------------------------------*/ -static int -ico_winmgr_usurf_2_node(const int surfaceid) -{ - /* currently support single ECU system */ - return(ICO_IVI_SURFACEID_2_NODEID(surfaceid)); -} - -/*--------------------------------------------------------------------------*/ -/** * @brief ico_win_mgr_send_to_mgr: send event to manager(HomeScreen) * * @param[in] event event code(if -1, not send event) - * @param[in] surfaceid UIFW surface id - * @param[in] appid applicationId + * @param[in] usurf UIFW surface table * @param[in] param1 parameter 1 * @param[in] : : - * @param[in] param6 parameter 6 + * @param[in] param5 parameter 5 * @return number of managers * @retval > 0 number of managers * @retval 0 manager not exist */ /*--------------------------------------------------------------------------*/ static int -ico_win_mgr_send_to_mgr(const int event, const int surfaceid, const char *appid, +ico_win_mgr_send_to_mgr(const int event, struct uifw_win_surface *usurf, const int param1, const int param2, const int param3, - const int param4, const int param5, const int param6) + const int param4, const int param5) { int num_mgr = 0; struct uifw_manager* mgr; + /* send created if not send created event */ + if ((usurf != NULL) && (usurf->created == 0) && + (((usurf->width > 0) && (usurf->height > 0)) || + ((event != ICO_WINDOW_MGR_WINDOW_CREATED) && + (event != ICO_WINDOW_MGR_WINDOW_NAME)))) { + wl_list_for_each (mgr, &_ico_win_mgr->manager_list, link) { + if (mgr->manager) { + uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) WINDOW_CREATED" + "(surf=%08x,name=%s,pid=%d,appid=%s)", (int)mgr->resource, + usurf->surfaceid, usurf->winname, usurf->uclient->pid, + usurf->uclient->appid); + ico_window_mgr_send_window_created(mgr->resource, usurf->surfaceid, + usurf->winname, usurf->uclient->pid, + usurf->uclient->appid); + } + } + usurf->created = 1; + } + wl_list_for_each (mgr, &_ico_win_mgr->manager_list, link) { - if (mgr->eventcb) { + if (mgr->manager) { num_mgr ++; + switch(event) { case ICO_WINDOW_MGR_WINDOW_CREATED: - uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) WINDOW_CREATED" - "(surf=%08x,pid=%d,appid=%s)", - (int)mgr->resource, surfaceid, param1, appid); - ico_window_mgr_send_window_created(mgr->resource, surfaceid, param1, appid); + /* Do nothing anymore because sended window create event */ + break; + + case ICO_WINDOW_MGR_WINDOW_NAME: + uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) WINDOW_NAME" + "(surf=%08x,name=%s)", (int)mgr->resource, + usurf->surfaceid, usurf->winname); + ico_window_mgr_send_window_name(mgr->resource, usurf->surfaceid, + usurf->winname); + break; + + case ICO_WINDOW_MGR_WINDOW_DESTROYED: + uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) DESTROYED" + "(surf=%08x)", (int)mgr->resource, usurf->surfaceid); + ico_window_mgr_send_window_destroyed(mgr->resource, usurf->surfaceid); break; case ICO_WINDOW_MGR_WINDOW_VISIBLE: uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) VISIBLE" "(surf=%08x,vis=%d,raise=%d,hint=%d)", - (int)mgr->resource, surfaceid, param1, param2, param3); + (int)mgr->resource, usurf->surfaceid, param1, param2, param3); ico_window_mgr_send_window_visible(mgr->resource, - surfaceid, param1, param2, param3); + usurf->surfaceid, param1, param2, param3); break; case ICO_WINDOW_MGR_WINDOW_CONFIGURE: uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) CONFIGURE" - "(surf=%08x,app=%s,layer=%d,x/y=%d/%d,w/h=%d/%d,hint=%d)", - (int)mgr->resource, surfaceid, appid, - param1, param2, param3, param4, param5, param6); - ico_window_mgr_send_window_configure(mgr->resource, surfaceid, appid, - param1, param2, param3, param4, - param5, param6); - break; - - case ICO_WINDOW_MGR_WINDOW_DESTROYED: - uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) DESTROYED " - "surf=%08x", (int)mgr->resource, surfaceid); - ico_window_mgr_send_window_destroyed(mgr->resource, surfaceid); + "(surf=%08x,app=%s,node=%x,layer=%x,x/y=%d/%d,w/h=%d/%d,hint=%d)", + (int)mgr->resource, usurf->surfaceid, usurf->uclient->appid, + usurf->node_tbl->node, usurf->win_layer->layer, + param1, param2, param3, param4, param5); + ico_window_mgr_send_window_configure(mgr->resource, usurf->surfaceid, + usurf->node_tbl->node, + usurf->win_layer->layer, + param1, param2, param3, param4, param5); break; case ICO_WINDOW_MGR_WINDOW_ACTIVE: - uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) ACTIVE surf=%08x " - "active=%d", (int)mgr->resource, surfaceid, param1); - ico_window_mgr_send_window_active(mgr->resource, surfaceid, + uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) ACTIVE" + "(surf=%08x,active=%d)", (int)mgr->resource, usurf->surfaceid, + param1); + ico_window_mgr_send_window_active(mgr->resource, usurf->surfaceid, (uint32_t)param1); break; + case ICO_WINDOW_MGR_LAYER_VISIBLE: + uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) LAYER_VISIBLE" + "(layer=%x,visivle=%d)", (int)mgr->resource, param1, param2); + ico_window_mgr_send_layer_visible(mgr->resource, (uint32_t)param1, param2); + break; + + case ICO_WINDOW_MGR_MAP_SURFACE: + uifw_trace("ico_win_mgr_send_to_mgr: Send Manager(%08x) MAP SURFACE" + "(%08x,ev=%x,w/h/s/f=%d/%d/%d/%x)", (int)mgr->resource, + usurf->surfaceid, + param1, param2, param3, param4, param5); + ico_window_mgr_send_map_surface(mgr->resource, param1, usurf->surfaceid, + param2, param3, param4, param5); + break; + default: + uifw_error("ico_win_mgr_send_to_mgr: Illegal event(%08x)", event); break; } } @@ -1763,62 +2504,14 @@ ico_win_mgr_send_to_mgr(const int event, const int surfaceid, const char *appid, /*--------------------------------------------------------------------------*/ /** - * @brief ico_win_mgr_hook_set_user: set hook function for set user - * - * @param[in] hook_set_user hook function - * @return none - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ico_win_mgr_hook_set_user(void (*hook_set_user)(struct wl_client *client, - const char *appid)) -{ - uifw_trace("ico_win_mgr_hook_set_user: Hook %08x", (int)hook_set_user); - win_mgr_hook_set_user = hook_set_user; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_win_mgr_hook_create: set hook function for create surface - * - * @param[in] hook_create hook function - * @return none - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ico_win_mgr_hook_create(void (*hook_create)(struct wl_client *client, - struct weston_surface *surface, - int surfaceId, const char *appid)) -{ - uifw_trace("ico_win_mgr_hook_create: Hook %08x", (int)hook_create); - win_mgr_hook_create = hook_create; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_win_mgr_hook_destroy: set hook function for destroy surface - * - * @param[in] hook_destroy hook function - * @return none - */ -/*--------------------------------------------------------------------------*/ -WL_EXPORT void -ico_win_mgr_hook_destroy(void (*hook_destroy)(struct weston_surface *surface)) -{ - uifw_trace("ico_win_mgr_hook_destroy: Hook %08x", (int)hook_destroy); - win_mgr_hook_destroy = hook_destroy; -} - -/*--------------------------------------------------------------------------*/ -/** - * @brief ico_window_mgr_set_animation: set animation hook routine + * @brief ico_window_mgr_set_hook_animation: set animation hook routine * * @param[in] hook_animation hook routine * @return none */ /*--------------------------------------------------------------------------*/ WL_EXPORT void -ico_window_mgr_set_animation(int (*hook_animation)(const int op, void *data)) +ico_window_mgr_set_hook_animation(int (*hook_animation)(const int op, void *data)) { win_mgr_hook_animation = hook_animation; } @@ -1829,18 +2522,48 @@ ico_window_mgr_set_animation(int (*hook_animation)(const int op, void *data)) * this function called from ico_pluign_loader * * @param[in] es weston compositor + * @param[in] argc number of arguments(unused) + * @param[in] argv argument list(unused) * @return result * @retval 0 sccess * @retval -1 error */ /*--------------------------------------------------------------------------*/ WL_EXPORT int -module_init(struct weston_compositor *ec) +module_init(struct weston_compositor *ec, int *argc, char *argv[]) { int nodeId; + int i; + int idx; + struct weston_output *output; + struct weston_config_section *section; + char *displayno = NULL; + char *p; uifw_info("ico_window_mgr: Enter(module_init)"); + /* get ivi debug level */ + section = weston_config_get_section(ec->config, "ivi-debug", NULL, NULL); + if (section) { + weston_config_section_get_int(section, "flag", &_ico_ivi_debug_flag, 0); + weston_config_section_get_int(section, "log", &_ico_ivi_debug_level, 3); + } + + /* get animation default */ + section = weston_config_get_section(ec->config, "ivi-animation", NULL, NULL); + if (section) { + weston_config_section_get_string(section, "default", &_ico_ivi_animation_name, NULL); + weston_config_section_get_int(section, "time", &_ico_ivi_animation_time, 500); + weston_config_section_get_int(section, "fps", &_ico_ivi_animation_fps, 15); + } + + /* get display number list */ + section = weston_config_get_section(ec->config, "ivi-display", NULL, NULL); + if (section) { + weston_config_section_get_string(section, "displayno", &displayno, NULL); + } + + /* create ico_window_mgr management table */ _ico_win_mgr = (struct ico_win_mgr *)malloc(sizeof(struct ico_win_mgr)); if (_ico_win_mgr == NULL) { uifw_error("ico_window_mgr: malloc failed"); @@ -1853,7 +2576,7 @@ module_init(struct weston_compositor *ec) uifw_error("ico_window_mgr: malloc failed"); return -1; } - uifw_trace("ico_window_mgr: sh=%08x", (int)_ico_win_mgr); + uifw_trace("ico_window_mgr: table=%08x", (int)_ico_win_mgr); memset(_ico_win_mgr->surfaceid_map, 0, INIT_SURFACE_IDS/8); _ico_win_mgr->compositor = ec; @@ -1861,38 +2584,89 @@ module_init(struct weston_compositor *ec) _ico_win_mgr->surfaceid_max = INIT_SURFACE_IDS; _ico_win_mgr->surfaceid_count = INIT_SURFACE_IDS; - uifw_trace("ico_window_mgr: wl_display_add_global(bind_ico_win_mgr)"); - if (wl_display_add_global(ec->wl_display, &ico_window_mgr_interface, - _ico_win_mgr, bind_ico_win_mgr) == NULL) { - uifw_error("ico_window_mgr: Error(wl_display_add_global)"); + uifw_trace("ico_window_mgr: wl_global_create(bind_ico_win_mgr)"); + if (wl_global_create(ec->wl_display, &ico_window_mgr_interface, 1, + _ico_win_mgr, bind_ico_win_mgr) == NULL) { + uifw_error("ico_window_mgr: Error(wl_global_create)"); return -1; } - wl_list_init(&_ico_win_mgr->surface_list); wl_list_init(&_ico_win_mgr->client_list); wl_list_init(&_ico_win_mgr->manager_list); - wl_list_init(&_ico_win_mgr->client_attr_list); + wl_list_init(&_ico_win_mgr->ivi_layer_list); + /* create display list */ + if (displayno != NULL) { + p = displayno; + } + else { + p = NULL; + } + _ico_num_nodes = 0; + wl_list_for_each(output, &ec->output_list, link) { + _ico_num_nodes++; + if (_ico_num_nodes >= ICO_IVI_MAX_DISPLAY) break; + } + memset(&_ico_node_table[0], 0, sizeof(_ico_node_table)); + i = 0; + wl_list_for_each(output, &ec->output_list, link) { + p = strtok(p, ","); + if (p) { + idx = strtol(p, (char **)0, 0); + uifw_trace("ico_window_mgr: config Display.%d is %d", i, idx); + p = NULL; + if ((idx < 0) || (idx >= _ico_num_nodes)) { + idx = i; + } + } + else { + idx = i; + } + if (_ico_node_table[idx].node) { + for (idx = 0; idx < _ico_num_nodes; idx++) { + if (_ico_node_table[idx].node == 0) break; + } + if (idx >= _ico_num_nodes) { + uifw_error("ico_window_mgr: number of display overflow"); + idx = 0; + } + } + _ico_node_table[idx].node = idx + 0x100; + _ico_node_table[idx].displayno = i; + _ico_node_table[idx].disp_x = output->x; + _ico_node_table[idx].disp_y = output->y; + _ico_node_table[idx].disp_width = output->width; + _ico_node_table[idx].disp_height = output->height; + i ++; + if (i >= _ico_num_nodes) break; + } + idx = 0; + for (i = 0; i < _ico_num_nodes; i++) { + _ico_node_table[i].node &= 0x0ff; + uifw_trace("ico_window_mgr: Display.%d no=%d x/y=%d/%d w/h=%d/%d", + i, _ico_node_table[i].displayno, + _ico_node_table[i].disp_x, _ico_node_table[i].disp_y, + _ico_node_table[i].disp_width, _ico_node_table[i].disp_height); + } + if (displayno) free(displayno); + + /* my node Id ... this version fixed 0 */ nodeId = ico_ivi_get_mynode(); + _ico_win_mgr->surface_head = ICO_IVI_SURFACEID_BASE(nodeId); - uifw_trace("ico_window_mgr: NoedId=%08x SurfaceIdBase=%08x", + uifw_trace("ico_window_mgr: NoedId=%04x SurfaceIdBase=%08x", nodeId, _ico_win_mgr->surface_head); - /* Regist usurf_2_node to ivi_common plugin */ - ico_ivi_set_usurf_2_node(ico_winmgr_usurf_2_node); - - /* Regist send_to_mgr to ivi_common plugin */ - ico_ivi_set_send_to_mgr(ico_win_mgr_send_to_mgr); - ico_ivi_set_send_surface_change(win_mgr_surface_change_mgr); - /* Hook to IVI-Shell */ - ivi_shell_hook_bind(bind_shell_client); - ivi_shell_hook_unbind(unbind_shell_client); - ivi_shell_hook_create(client_register_surface); - ivi_shell_hook_destroy(win_mgr_surface_destroy); - ivi_shell_hook_map(win_mgr_map_surface); - ivi_shell_hook_change(win_mgr_surface_change); - ivi_shell_hook_select(win_mgr_surface_select); + ico_ivi_shell_hook_bind(win_mgr_bind_client); + ico_ivi_shell_hook_unbind(win_mgr_unbind_client); + ico_ivi_shell_hook_create(win_mgr_register_surface); + ico_ivi_shell_hook_destroy(win_mgr_destroy_surface); + ico_ivi_shell_hook_map(win_mgr_map_surface); + ico_ivi_shell_hook_change(win_mgr_change_surface); + ico_ivi_shell_hook_select(win_mgr_select_surface); + ico_ivi_shell_hook_title(win_mgr_set_title); + ico_ivi_shell_hook_move(win_mgr_surface_move); uifw_info("ico_window_mgr: Leave(module_init)"); diff --git a/src/ico_window_mgr.h b/src/ico_window_mgr.h index c098d94..7e416e9 100644 --- a/src/ico_window_mgr.h +++ b/src/ico_window_mgr.h @@ -24,13 +24,13 @@ /** * @brief Public functions in ico_window_mgr Weston plugin * - * @date Feb-08-2013 + * @date Jul-26-2013 */ #ifndef _ICO_WINDOW_MGR_H_ #define _ICO_WINDOW_MGR_H_ -/* Cleint management table */ +/* Cleint management table */ struct uifw_client { struct wl_client *client; /* Wayland client */ int pid; /* ProcessId (pid) */ @@ -42,31 +42,68 @@ struct uifw_client { struct wl_list link; }; +/* Node information */ +struct uifw_node_table { + uint16_t node; /* node Id */ + uint16_t displayno; /* weston display number */ + int disp_x; /* display frame buffer X-coordinate */ + int disp_y; /* display frame buffer Y-coordinate */ + int disp_width; /* display width */ + int disp_height; /* display height */ +}; + +/* Layer management table */ +struct uifw_win_layer { + uint32_t layer; /* Layer Id */ + uint16_t attribute; /* Layer attribute */ + char visible; /* visibility */ + char res; /* (unused) */ + struct wl_list surface_list; /* Surfacae list */ + struct wl_list link; /* Link pointer for layer list */ +}; + /* UIFW surface */ struct shell_surface; struct uifw_win_surface { - uint32_t id; /* UIFW SurfaceId */ - int layer; /* LayerId */ + uint32_t surfaceid; /* UIFW SurfaceId */ + struct uifw_node_table *node_tbl; /* Node manager of ico_window_mgr */ + struct uifw_win_layer *win_layer; /* surface layer */ struct weston_surface *surface; /* Weston surface */ struct shell_surface *shsurf; /* Shell(IVI-Shell) surface */ struct uifw_client *uclient; /* Client */ - int x; /* X-axis */ - int y; /* Y-axis */ + int x; /* X-coordinate */ + int y; /* Y-coordinate */ int width; /* Width */ int height; /* Height */ + char winname[ICO_IVI_WINNAME_LENGTH];/* Window name */ + char visible; /* visibility */ + char raise; /* raise(top of the layer) */ + char created; /* sended created event to manager */ + char mapped; /* end of map */ + char restrain_configure; /* restrant configure event */ + char res[3]; /* (unused) */ struct _uifw_win_surface_animation { /* wndow animation */ - struct weston_animation animation; /* animation control */ - short type; /* animation type */ - short type_next; /* next animation type */ - short time; /* animation time */ + struct weston_animation animation; /* weston animation control */ + uint16_t type; /* current animation type */ + uint16_t name; /* curremt animation nameId */ + uint16_t next_name; /* next animation nameId */ + uint16_t hide_name; /* animation nameId for hide */ + uint16_t hide_time; /* animation time(ms) for hide */ + uint16_t show_name; /* animation nameId for show */ + uint16_t show_time; /* animation time(ms) for show */ + uint16_t move_name; /* animation nameId for move */ + uint16_t move_time; /* animation time(ms) for move */ + uint16_t resize_name; /* animation nameId for resize */ + uint16_t resize_time; /* animation time(ms) for resize */ short current; /* animation current percentage */ char state; /* animation state */ - char visible; /* need visible(1)/hide(2) at end of animation*/ - char res[2]; /* (unused) */ + char visible; /* need hide(1)/show(2) at end of animation*/ + char restrain_configure; /* restrain surface resize */ + char res; /* (unused) */ uint32_t starttime; /* start time(ms) */ + void *animadata; /* animation data */ } animation; - void *animadata; /* animation data */ - struct wl_list link; /* surface link list */ + struct wl_list ivi_layer; /* surface list of same layer */ struct uifw_win_surface *next_idhash; /* UIFW SurfaceId hash list */ struct uifw_win_surface *next_wshash; /* Weston SurfaceId hash list */ }; @@ -82,25 +119,28 @@ struct uifw_win_surface { /* animation state */ #define ICO_WINDOW_MGR_ANIMATION_STATE_NONE 0 /* not animation */ -#define ICO_WINDOW_MGR_ANIMATION_STATE_IN 1 /* show(in) animation */ -#define ICO_WINDOW_MGR_ANIMATION_STATE_OUT 2 /* hide(out) animation */ +#define ICO_WINDOW_MGR_ANIMATION_STATE_SHOW 1 /* show(in) animation */ +#define ICO_WINDOW_MGR_ANIMATION_STATE_HIDE 2 /* hide(out) animation */ #define ICO_WINDOW_MGR_ANIMATION_STATE_MOVE 3 /* move animation */ #define ICO_WINDOW_MGR_ANIMATION_STATE_RESIZE 4 /* resize animation */ /* extended(plugin) animation operation */ -#define ICO_WINDOW_MGR_ANIMATION_TYPE 0 /* convert animation name to value*/ +#define ICO_WINDOW_MGR_ANIMATION_NAME 0 /* convert animation name to Id */ #define ICO_WINDOW_MGR_ANIMATION_DESTROY 99 /* surface destroy */ -#define ICO_WINDOW_MGR_ANIMATION_OPIN 1 /* change to show */ -#define ICO_WINDOW_MGR_ANIMATION_OPOUT 2 /* change to hide */ +#define ICO_WINDOW_MGR_ANIMATION_OPNONE 0 /* no animation */ +#define ICO_WINDOW_MGR_ANIMATION_OPHIDE 1 /* change to hide */ +#define ICO_WINDOW_MGR_ANIMATION_OPSHOW 2 /* change to show */ #define ICO_WINDOW_MGR_ANIMATION_OPMOVE 3 /* surface move */ #define ICO_WINDOW_MGR_ANIMATION_OPRESIZE 4 /* surface resize */ #define ICO_WINDOW_MGR_ANIMATION_OPCANCEL 9 /* animation cancel */ /* Prototype for function */ + /* surface visible control */ +void ico_window_mgr_set_visible(struct uifw_win_surface *usurf, const int visible); /* get client applicationId */ -char *ico_window_mgr_appid(struct wl_client* client); +char *ico_window_mgr_get_appid(struct wl_client* client); /* set window animation hook */ -void ico_window_mgr_set_animation(int (*hook_animation)(const int op, void *data)); +void ico_window_mgr_set_hook_animation(int (*hook_animation)(const int op, void *data)); #endif /*_ICO_WINDOW_MGR_H_*/ diff --git a/tests/test-client.c b/tests/test-client.c index 28fd1a2..2532674 100644 --- a/tests/test-client.c +++ b/tests/test-client.c @@ -21,7 +21,7 @@ * OF THIS SOFTWARE. */ /** - * @brief Wayland Application for uint test of Weston(Wayland) IVI plugins + * @brief Wayland Application for unit test of Weston(Wayland) IVI plugins * * @date Feb-08-2013 */ @@ -34,7 +34,6 @@ #include #include #include -#include "ico_ivi_shell-client-protocol.h" #include "ico_window_mgr-client-protocol.h" #include "ico_input_mgr-client-protocol.h" #include "test-common.h" @@ -46,7 +45,6 @@ struct display { struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shell *shell; - struct ico_ivi_shell *ico_ivi_shell; struct ico_window_mgr *ico_window_mgr; struct ico_exinput *ico_exinput; struct input *input; @@ -266,8 +264,8 @@ output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, { struct output *output = data; - print_log("CLIENT: Event[handle_mode] x/y=%d/%d flags=%08x refresh=%d", - width, height, flags, refresh); + print_log("CLIENT: Event[handle_mode] %08x x/y=%d/%d flags=%08x refresh=%d", + (int)wl_output, width, height, flags, refresh); if (flags & WL_OUTPUT_MODE_CURRENT) { output->width = width; @@ -375,10 +373,6 @@ handle_global(void *data, struct wl_registry *registry, uint32_t id, else if (strcmp(interface, "wl_shell") == 0) { display->shell = wl_registry_bind(display->registry, id, &wl_shell_interface, 1); } - else if (strcmp(interface, "ico_ivi_shell") == 0) { - display->ico_ivi_shell = - wl_registry_bind(display->registry, id, &ico_ivi_shell_interface, 1); - } else if (strcmp(interface, "ico_window_mgr") == 0) { display->ico_window_mgr = wl_registry_bind(display->registry, id, &ico_window_mgr_interface, 1); @@ -474,7 +468,7 @@ send_state(struct display* display) } static void -create_surface(struct display *display) +create_surface(struct display *display, const char *title) { struct surface *surface; @@ -492,6 +486,7 @@ create_surface(struct display *display) wl_shell_surface_add_listener(surface->shell_surface, &shell_surface_listener, display); wl_shell_surface_set_toplevel(surface->shell_surface); + wl_shell_surface_set_title(surface->shell_surface, title); } } wl_display_flush(display->display); @@ -520,7 +515,7 @@ static void clear_surface(struct display *display) { if (! display->surface) { - create_surface(display); + create_surface(display, "test-client"); } else { opengl_clear_window(display->init_color); @@ -584,6 +579,7 @@ int main(int argc, char *argv[]) wl_registry_add_listener(display->registry, ®istry_listener, display); wl_display_dispatch(display->display); + sleep_with_wayland(display->display, 1000); fd = 0; @@ -608,7 +604,7 @@ int main(int argc, char *argv[]) break; } else if (strncasecmp(buf, "create-surface", ret) == 0) { - create_surface(display); + create_surface(display, "test-client"); } else if (strncasecmp(buf, "clear-surface", 13) == 0) { display->init_color = strtoul(&buf[14], (char **)0, 0); diff --git a/tests/test-common.c b/tests/test-common.c index b1a18b7..390b20f 100644 --- a/tests/test-common.c +++ b/tests/test-common.c @@ -214,15 +214,16 @@ wait_with_wayland(struct wl_display *display, int msec, int *endflag) fd = wl_display_get_fd(display); do { - /* Flush send data */ - wl_display_flush(display); - /* Check wayland input */ - nread = 0; - if (ioctl(fd, FIONREAD, &nread) < 0) { + while(1) { + /* Flush send data */ + wl_display_flush(display); + nread = 0; - } - if (nread >= 8) { + if (ioctl(fd, FIONREAD, &nread) < 0) { + nread = 0; + } + if (nread < 8) break; /* Read event from wayland */ wl_display_dispatch(display); } diff --git a/tests/test-eflapp.c b/tests/test-eflapp.c index 8bb6d7a..1bc3a61 100644 --- a/tests/test-eflapp.c +++ b/tests/test-eflapp.c @@ -51,6 +51,7 @@ main(int argc, char *argv[]) int height; unsigned int color; int r, g, b, a; + int rr, gg, bb; int appno = 1; char sTitle[64]; @@ -86,22 +87,20 @@ main(int argc, char *argv[]) ecore_evas_callback_resize_set(ee, _resize_cb); ecore_evas_callback_delete_request_set(ee, _on_destroy); - sprintf(sTitle, "EFL Native Application %d", appno); + sprintf(sTitle, "EFL_Native_Application_%d", appno); ecore_evas_title_set(ee, sTitle); ecore_evas_show(ee); canvas = ecore_evas_get(ee); bg = evas_object_rectangle_add(canvas); - r = (color>>16)&0x0ff; - g = (color>>8)&0x0ff; - b = color&0x0ff; + rr = (color>>16)&0x0ff; + gg = (color>>8)&0x0ff; + bb = color&0x0ff; a = (color>>24)&0x0ff; - if (a != 255) { - r = (r * a) / 255; - g = (g * a) / 255; - b = (b * a) / 255; - } + r = (rr * a) / 255; + g = (gg * a) / 255; + b = (bb * a) / 255; evas_object_color_set(bg, r, g, b, a); /* bg color */ evas_object_move(bg, 0, 0); /* at origin */ evas_object_resize(bg, width, height); /* covers full canvas */ @@ -132,19 +131,22 @@ main(int argc, char *argv[]) ecore_evas_resize(sub_ee, ((2 * width) / 3) - 6, ((2 * height) / 3) - 6); r1 = evas_object_rectangle_add(sub_canvas); - evas_object_color_set(r1, g, b, r, 255); + evas_object_color_set(r1, gg, bb, rr, 255); evas_object_move(r1, 10, 10); evas_object_resize(r1, 100, 100); evas_object_show(r1); r2 = evas_object_rectangle_add(sub_canvas); - evas_object_color_set(r2, b/2, g/2, r/2, 128); + r = rr * 128 / 256; + g = gg * 128 / 256; + b = bb * 128 / 256; + evas_object_color_set(r2, b, g, r, 128); evas_object_move(r2, 10, 10); evas_object_resize(r2, 50, 50); evas_object_show(r2); r3 = evas_object_rectangle_add(sub_canvas); - evas_object_color_set(r3, b, r, g, 255); + evas_object_color_set(r3, bb, rr, gg, 255); evas_object_move(r3, 60, 60); evas_object_resize(r3, 50, 50); evas_object_show(r3); diff --git a/tests/test-homescreen.c b/tests/test-homescreen.c index 2975dbd..a4fc461 100644 --- a/tests/test-homescreen.c +++ b/tests/test-homescreen.c @@ -21,7 +21,7 @@ * OF THIS SOFTWARE. */ /** - * @brief HomeScreen for uint test of Weston(Wayland) IVI plugins + * @brief HomeScreen for unit test of Weston(Wayland) IVI plugins * * @date Feb-08-2013 */ @@ -42,19 +42,18 @@ #include #include #include -#include "ico_ivi_shell-client-protocol.h" #include "ico_window_mgr-client-protocol.h" #include "ico_input_mgr-client-protocol.h" #include "test-common.h" #define MAX_APPID 128 -#define ICO_IVI_MAX_COORDINATE 16383 struct surface_name { struct surface_name *next; int surfaceid; int pid; char appid[MAX_APPID]; + int node; int x; int y; int width; @@ -69,7 +68,6 @@ struct display { struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shell *shell; - struct ico_ivi_shell *ico_ivi_shell; struct ico_window_mgr *ico_window_mgr; struct ico_input_mgr_control *ico_input_mgr; struct ico_input_mgr_device *ico_input_device; @@ -304,7 +302,7 @@ static const struct wl_surface_listener surface_listener = { }; static void -create_surface(struct display *display) +create_surface(struct display *display, const char *title) { struct surface *surface; int id; @@ -321,6 +319,7 @@ create_surface(struct display *display) wl_shell_get_shell_surface(display->shell, surface->surface); if (surface->shell_surface) { wl_shell_surface_set_toplevel(surface->shell_surface); + wl_shell_surface_set_title(surface->shell_surface, title); } } wl_display_flush(display->display); @@ -348,7 +347,7 @@ static void clear_surface(struct display *display) { if (! display->surface) { - create_surface(display); + create_surface(display, "HomeScreen-BG"); } else { opengl_clear_window(display->init_color); @@ -364,8 +363,8 @@ output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y, { struct output *output = data; - print_log("HOMESCREEN: Event[handle_geometry] x/y=%d/%d p.w/h=%d/%d trans=%d", - x, y, physical_width, physical_height, transform); + print_log("HOMESCREEN: Event[handle_geometry] %08x x/y=%d/%d p.w/h=%d/%d trans=%d", + (int)wl_output, x, y, physical_width, physical_height, transform); output->x = x; output->y = y; @@ -377,8 +376,8 @@ output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, { struct output *output = data; - print_log("HOMESCREEN: Event[handle_mode] x/y=%d/%d flags=%08x refresh=%d", - width, height, flags, refresh); + print_log("HOMESCREEN: Event[handle_mode] %08x x/y=%d/%d flags=%08x refresh=%d", + (int)wl_output, width, height, flags, refresh); if (flags & WL_OUTPUT_MODE_CURRENT) { struct display *display = output->display; @@ -392,11 +391,11 @@ output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, if (display->bgsurface_name) { ico_window_mgr_set_positionsize(display->ico_window_mgr, display->bgsurface_name->surfaceid, - 0, 0, width, height); + 0, 0, 0, 0, width, height); } else if (display->bg_created == 0) { display->bg_created = 9; - create_surface(output->display); + create_surface(display, "HomeScreen-BG"); } } } @@ -435,6 +434,9 @@ search_surfacename(struct display *display, const char *surfname) if (strcmp(p->appid, surfname) == 0) break; p = p->next; } + if (! p) { + print_log("HOMESCREEN: app(%s) dose not exist", surfname); + } return(p); } @@ -455,7 +457,7 @@ search_surfaceid(struct display *display, const int surfaceid) static void window_created(void *data, struct ico_window_mgr *ico_window_mgr, - uint32_t surfaceid, int32_t pid, const char *appid) + uint32_t surfaceid, const char *winname, int32_t pid, const char *appid) { struct display *display = data; struct surface_name *p; @@ -470,12 +472,12 @@ window_created(void *data, struct ico_window_mgr *ico_window_mgr, p = p->next; } if (p) { - print_log("HOMESCREEN: Event[window_created] surface=%08x(app=%s) exist", - (int)surfaceid, appid); + print_log("HOMESCREEN: Event[window_created] surface=%08x(app=%s,name=%s) exist", + (int)surfaceid, appid, winname); } else { - print_log("HOMESCREEN: Event[window_created] new surface=%08x(app=%s)", - (int)surfaceid, appid); + print_log("HOMESCREEN: Event[window_created] new surface=%08x(app=%s) winname=%s", + (int)surfaceid, appid, winname); p = malloc(sizeof(struct surface_name)); if (! p) { return; @@ -495,7 +497,7 @@ window_created(void *data, struct ico_window_mgr *ico_window_mgr, /* Set default size and show */ if (p->width > 0) { ico_window_mgr_set_positionsize(display->ico_window_mgr, surfaceid, - p->x, p->y, p->width, p->height); + 0, p->x, p->y, p->width, p->height, 0); } print_log("HOMESCREEN: Created window[%08x] (app=%s)", (int)surfaceid, appid); @@ -505,9 +507,10 @@ window_created(void *data, struct ico_window_mgr *ico_window_mgr, if (display->bg_created == 1) { display->bg_created = 9; ico_window_mgr_set_positionsize(display->ico_window_mgr, surfaceid, - 0, 0, display->init_width, display->init_height); + 0, 0, 0, + display->init_width, display->init_height, 0); } - ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, 1, 0); + ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, 1, 0, 0); print_log("HOMESCREEN: Created window[%08x] (app=%s) Visible", (int)surfaceid, appid); p->visible = 1; @@ -515,6 +518,13 @@ window_created(void *data, struct ico_window_mgr *ico_window_mgr, } static void +window_name(void *data, struct ico_window_mgr *ico_window_mgr, + uint32_t surfaceid, const char *winname) +{ + print_log("HOMESCREEN: Window Name[%08x] (name=%s)", (int)surfaceid, winname); +} + +static void window_destroyed(void *data, struct ico_window_mgr *ico_window_mgr, uint32_t surfaceid) { struct display *display = data; @@ -562,51 +572,77 @@ window_visible(void *data, struct ico_window_mgr *ico_window_mgr, print_log("HOMESCREEN: Event[window_visible] surface=%08x " "visible=%d raise=%d hint=%d", (int)surfaceid, visible, raise, hint); p->visible = visible; - if (hint == 0) { - ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, visible, 9); + if (hint == 1) { + ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, + visible, ICO_WINDOW_MGR_V_NOCHANGE, 0); } } } static void window_configure(void *data, struct ico_window_mgr *ico_window_mgr, - uint32_t surfaceid, const char *appid, int32_t layer, + uint32_t surfaceid, uint32_t node, uint32_t layer, int32_t x, int32_t y, int32_t width, int32_t height, int32_t hint) { struct display *display = data; struct surface_name *p; print_log("HOMESCREEN: Event[window_configure] surface=%08x " - "app=%s x/y=%d/%d w/h=%d/%d hint=%d", - (int)surfaceid, appid, x, y, width, height, hint); + "node=%x x/y=%d/%d w/h=%d/%d hint=%d", + (int)surfaceid, node, x, y, width, height, hint); p = search_surfaceid(display, (int)surfaceid); if (! p) { - print_log("HOMESCREEN: Event[window_configure] surface=%08x(app=%s) new create", - (int)surfaceid, appid); - window_created(data, ico_window_mgr, surfaceid, 0, appid); - p = search_surfaceid(display, (int)surfaceid); - if (! p) { - print_log("HOMESCREEN: Event[window_configure] can not make table"); - return; - } + print_log("HOMESCREEN: Event[window_configure] surface=%08x dose not exist", + (int)surfaceid); + } + else { + p->node = node; } } static void +window_layer_visible(void *data, struct ico_window_mgr *ico_window_mgr, + uint32_t layer, int32_t visible) +{ + print_log("HOMESCREEN: Event[layer_visible]layer=%x visible=%d", + (int)layer, visible); +} + +static void window_active(void *data, struct ico_window_mgr *ico_window_mgr, - uint32_t surfaceid, const uint32_t active) + uint32_t surfaceid, const int32_t active) { print_log("HOMESCREEN: Event[window_active] surface=%08x acive=%d", (int)surfaceid, (int)active); } +static void +window_surfaces(void *data, struct ico_window_mgr *ico_window_mgr, + const char *appid, struct wl_array *surfaces) +{ + print_log("HOMESCREEN: Event[app_surfaces] app=%s", appid); +} + +static void +window_map(void *data, struct ico_window_mgr *ico_window_mgr, + int32_t event, uint32_t surfaceid, + int32_t width, int32_t height, int32_t stride, int32_t format) +{ + print_log("HOMESCREEN: Event[map_surface] ev=%d surf=%08x w/h/s/f=%d/%d/%d/%x", + event, (int)surfaceid, width, height, stride, format); +} + static const struct ico_window_mgr_listener window_mgr_listener = { window_created, + window_name, window_destroyed, window_visible, window_configure, - window_active + window_active, + window_layer_visible, + window_surfaces, + window_map }; static void @@ -677,17 +713,13 @@ handle_global(void *data, struct wl_registry *registry, uint32_t id, display->shell = wl_registry_bind(display->registry, id, &wl_shell_interface, 1); } - else if (strcmp(interface, "ico_ivi_shell") == 0) { - display->ico_ivi_shell = - wl_registry_bind(display->registry, id, &ico_ivi_shell_interface, 1); - } else if (strcmp(interface, "ico_window_mgr") == 0) { display->ico_window_mgr = wl_registry_bind(display->registry, id, &ico_window_mgr_interface, 1); ico_window_mgr_add_listener(display->ico_window_mgr, &window_mgr_listener, display); print_log("HOMESCREEN: created window_mgr global %p", display->ico_window_mgr); - ico_window_mgr_set_eventcb(display->ico_window_mgr, 1); + ico_window_mgr_declare_manager(display->ico_window_mgr, 1); } else if (strcmp(interface, "ico_input_mgr_control") == 0) { display->ico_input_mgr = wl_registry_bind(display->registry, id, @@ -705,10 +737,10 @@ handle_global(void *data, struct wl_registry *registry, uint32_t id, ico_exinput_add_listener(display->ico_exinput, &exinput_listener, display); print_log("HOMESCREEN: created exinput global %p", display->ico_exinput); - ico_window_mgr_set_eventcb(display->ico_window_mgr, 1); + ico_window_mgr_declare_manager(display->ico_window_mgr, 1); display->bg_created = 1; - create_surface(display); + create_surface(display, "HomeScreen-BG"); } } @@ -778,7 +810,10 @@ kill_app(struct display *display, char *buf) narg = pars_command(buf, args, 10); if (narg >= 1) { p = search_surfacename(display, args[0]); - if (kill(p->pid, SIGINT) < 0) { + if (! p) { + print_log("HOMESCREEN: kill[%s] Application dose not exist", args[0]); + } + else if (kill(p->pid, SIGINT) < 0) { print_log("HOMESCREEN: kill[%s.%d] Application dose not exist", p->appid, p->pid); } @@ -846,22 +881,38 @@ static void positionsize_surface(struct display *display, char *buf) { char *args[10]; + struct surface_name *p; int narg; int surfaceid; int x, y, width, height; + int anima = 0; + int node = 0; narg = pars_command(buf, args, 10); if (narg >= 5) { surfaceid = search_surface(display, args[0]); + p = search_surfacename(display, args[0]); x = strtol(args[1], (char **)0, 0); y = strtol(args[2], (char **)0, 0); width = strtol(args[3], (char **)0, 0); height = strtol(args[4], (char **)0, 0); + if (narg >= 6) { + node = strtol(args[5], (char **)0, 0); + if (p) { + p->node = node; + } + } + else if (p) { + node = p->node; + } + if (narg >= 7) { + anima = strtol(args[6], (char **)0, 0); + } if ((surfaceid >= 0) && (x >= 0) && (y >=0) && (width >= 0) && (height >=0)) { - print_log("HOMESCREEN: set_positionsize(%s,%08x,%d,%d,%d,%d)", - args[0], surfaceid, x, y, width, height); + print_log("HOMESCREEN: set_positionsize(%s,%08x,%d,%d,%d,%d,%d)", + args[0], surfaceid, node, x, y, width, height); ico_window_mgr_set_positionsize(display->ico_window_mgr, surfaceid, - x, y, width, height); + node, x, y, width, height, anima); } else { print_log("HOMESCREEN: Unknown surface(%s) at positionsize command", args[0]); @@ -869,7 +920,7 @@ positionsize_surface(struct display *display, char *buf) } else { print_log("HOMESCREEN: positionsize command" - "[positionsize appid x y width heigh] has no argument"); + "[positionsize appid x y width heigh node anima] has no argument"); } } @@ -877,28 +928,46 @@ static void move_surface(struct display *display, char *buf) { char *args[10]; + struct surface_name *p; int narg; int surfaceid; int x, y; + int anima = 0; + int node = 0; narg = pars_command(buf, args, 10); if (narg >= 3) { surfaceid = search_surface(display, args[0]); + p = search_surfacename(display, args[0]); x = strtol(args[1], (char **)0, 0); y = strtol(args[2], (char **)0, 0); + if (narg >= 4) { + node = strtol(args[3], (char **)0, 0); + if (p) { + p->node = node; + } + } + else if (p) { + node = p->node; + } + if (narg >= 5) { + anima = strtol(args[4], (char **)0, 0); + } + if ((surfaceid >= 0) && (x >= 0) && (y >=0)) { - print_log("HOMESCREEN: move(%s,%08x,%d,%d)", args[0], surfaceid, x, y); + print_log("HOMESCREEN: move(%s,%08x,%d.%d,%d anima=%d)", args[0], surfaceid, + node, x, y, anima); ico_window_mgr_set_positionsize(display->ico_window_mgr, surfaceid, - x, y, - ICO_IVI_MAX_COORDINATE+1, - ICO_IVI_MAX_COORDINATE+1); + node, x, y, + ICO_WINDOW_MGR_V_NOCHANGE, + ICO_WINDOW_MGR_V_NOCHANGE, anima); } else { print_log("HOMESCREEN: Unknown surface(%s) at move command", args[0]); } } else { - print_log("HOMESCREEN: move command[positionsize appid x y] has no argument"); + print_log("HOMESCREEN: move command[positionsize appid x y node anima] has no argument"); } } @@ -906,21 +975,32 @@ static void resize_surface(struct display *display, char *buf) { char *args[10]; + struct surface_name *p; int narg; int surfaceid; int width, height; + int anima = 0; + int node = 0; narg = pars_command(buf, args, 10); if (narg >= 3) { surfaceid = search_surface(display, args[0]); + p = search_surfacename(display, args[0]); + if (p) { + node = p->node; + } width = strtol(args[1], (char **)0, 0); height = strtol(args[2], (char **)0, 0); + if (narg >= 4) { + anima = strtol(args[3], (char **)0, 0); + } + if ((surfaceid >= 0) && (width >= 0) && (height >=0)) { - print_log("HOMESCREEN: resize(%s,%08x,%d,%d)", - args[0], surfaceid, width, height); + print_log("HOMESCREEN: resize(%s,%08x,%d.%d,%d,anima=%d)", + args[0], surfaceid, node, width, height, anima); ico_window_mgr_set_positionsize(display->ico_window_mgr, surfaceid, - ICO_IVI_MAX_COORDINATE+1, - ICO_IVI_MAX_COORDINATE+1, width, height); + node, ICO_WINDOW_MGR_V_NOCHANGE, + ICO_WINDOW_MGR_V_NOCHANGE, width, height, anima); } else { print_log("HOMESCREEN: Unknown surface(%s) at resize command", args[0]); @@ -928,7 +1008,7 @@ resize_surface(struct display *display, char *buf) } else { print_log("HOMESCREEN: positionsize command" - "[resize appid width heigh] has no argument"); + "[resize appid width heigh anima] has no argument"); } } @@ -940,16 +1020,21 @@ visible_surface(struct display *display, char *buf) int surfaceid; int visible; int raise; + int anima = 0; narg = pars_command(buf, args, 10); if (narg >= 3) { surfaceid = search_surface(display, args[0]); visible = strtol(args[1], (char **)0, 0); raise = strtol(args[2], (char **)0, 0); + if (narg >= 4) { + anima = strtol(args[3], (char **)0, 0); + } if ((surfaceid >= 0) && (visible >= 0) && (raise >=0)) { - print_log("HOMESCREEN: visible(%s,%08x,%d,%d)", - args[0], surfaceid, visible, raise); - ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, visible, raise); + print_log("HOMESCREEN: visible(%s,%08x,%d,%d,%d)", + args[0], surfaceid, visible, raise, anima); + ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, + visible, raise, anima); } else { print_log("HOMESCREEN: Unknown surface(%s) at visible command", args[0]); @@ -967,18 +1052,24 @@ show_surface(struct display *display, char *buf, const int show) char *args[10]; int narg; int surfaceid; + int anima = 0; narg = pars_command(buf, args, 10); if (narg >= 1) { surfaceid = search_surface(display, args[0]); + if (narg >= 2) { + anima = strtol(args[1], (char **)0, 0); + } if (surfaceid >= 0) { if (show) { - print_log("HOMESCREEN: show(%s,%08x)", args[0], surfaceid); - ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, 1, 9); + print_log("HOMESCREEN: show(%s,%08x,anima=%d)", args[0], surfaceid, anima); + ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, + 1, ICO_WINDOW_MGR_V_NOCHANGE, anima); } else { - print_log("HOMESCREEN: hide(%s,%08x)", args[0], surfaceid); - ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, 0, 9); + print_log("HOMESCREEN: hide(%s,%08x,anima=%d)", args[0], surfaceid, anima); + ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, + 0, ICO_WINDOW_MGR_V_NOCHANGE, anima); } } else { @@ -986,7 +1077,7 @@ show_surface(struct display *display, char *buf, const int show) } } else { - print_log("HOMESCREEN: show command[show/hide appid] has no argument"); + print_log("HOMESCREEN: show command[show/hide appid anima] has no argument"); } } @@ -996,18 +1087,24 @@ raise_surface(struct display *display, char *buf, const int raise) char *args[10]; int narg; int surfaceid; + int anima = 0; narg = pars_command(buf, args, 10); if (narg >= 1) { surfaceid = search_surface(display, args[0]); + if (narg >= 2) { + anima = strtol(args[1], (char **)0, 0); + } if (surfaceid >= 0) { if (raise) { - print_log("HOMESCREEN: raise(%s,%08x)", args[0], surfaceid); - ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, 9, 1); + print_log("HOMESCREEN: raise(%s,%08x,anima=%d)", args[0], surfaceid, anima); + ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, + ICO_WINDOW_MGR_V_NOCHANGE, 1, anima); } else { - print_log("HOMESCREEN: lower(%s,%08x)", args[0], surfaceid); - ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, 9, 0); + print_log("HOMESCREEN: lower(%s,%08x,anima=%d)", args[0], surfaceid, anima); + ico_window_mgr_set_visible(display->ico_window_mgr, surfaceid, + ICO_WINDOW_MGR_V_NOCHANGE, 0, anima); } } else { @@ -1015,7 +1112,7 @@ raise_surface(struct display *display, char *buf, const int raise) } } else { - print_log("HOMESCREEN: show command[raise/lower appid] has no argument"); + print_log("HOMESCREEN: show command[raise/lower appid anima] has no argument"); } } @@ -1039,7 +1136,7 @@ animation_surface(struct display *display, char *buf) } print_log("HOMESCREEN: animation(%s,%08x,%s,%d)", args[0], surfaceid, args[1], time); - ico_window_mgr_set_animation(display->ico_window_mgr, surfaceid, + ico_window_mgr_set_animation(display->ico_window_mgr, surfaceid, 0x7fffffff, args[1], time); } else { @@ -1093,7 +1190,7 @@ input_add(struct display *display, char *buf) print_log("HOMESCREEN: input_add(%s.%d to %s[%d])", args[0], input, args[2], fix); ico_input_mgr_control_add_input_app(display->ico_input_mgr, - args[2], args[0], input, fix); + args[2], args[0], input, fix, 0); } else { print_log("HOMESCREEN: Unknown input(%s) at input_add command", args[1]); diff --git a/tests/testdata/cl_surface1.dat b/tests/testdata/cl_surface1.dat index 3c9e6c7..b0725ad 100644 --- a/tests/testdata/cl_surface1.dat +++ b/tests/testdata/cl_surface1.dat @@ -3,15 +3,15 @@ # # 1. Create Surface create-surface -# 2. Sleep 2 sec with color change -sleep 0.4 +# 2. Sleep 1 sec with color change +sleep 1 clear-surface 0x80ff2020 -sleep 0.6 +sleep 0.5 clear-surface 0xb020ff20 -sleep 0.6 +sleep 0.5 clear-surface 0xe02020ff -sleep 0.6 +sleep 0.5 clear-surface 0xff808080 -sleep 0.6 +sleep 0.5 # 3. End of this Application (exit) bye diff --git a/tests/testdata/cl_surface4.dat b/tests/testdata/cl_surface4.dat new file mode 100644 index 0000000..f43922a --- /dev/null +++ b/tests/testdata/cl_surface4.dat @@ -0,0 +1,11 @@ +# Test for Weston IVI Plugin for Native Application +# Surface Create and Exit +# +# 1. Create Surface +create-surface +# 2. Sleep 2 sec with color change +sleep 0.1 +clear-surface 0x80ff4060 +sleep 15 +# 3. End of this Application (exit) +bye diff --git a/tests/testdata/hs_alltest.dat b/tests/testdata/hs_alltest.dat index 8971c9b..4e7e7f2 100644 --- a/tests/testdata/hs_alltest.dat +++ b/tests/testdata/hs_alltest.dat @@ -5,7 +5,7 @@ launch ../tests/test-client < ../tests/testdata/cl_surface1.dat 2> ../tests/testlog/test-client01.log waitcreate 2 show test-client -sleep 2 +sleep 4 waitdestroy 60 sleep 1 # @@ -16,13 +16,13 @@ resize test-client 600 400 move test-client 300 100 show test-client sleep 1 -move test-client 320 120 +move test-client 400 150 sleep 0.5 -move test-client 340 140 +move test-client 500 200 sleep 0.5 -move test-client 360 160 +move test-client 600 250 sleep 0.5 -move test-client 380 180 +move test-client 700 300 sleep 0.5 hide test-client sleep 1 @@ -45,56 +45,114 @@ sleep 1 waitdestroy 60 sleep 1 # -# 3. Launch Weston sample client -launch /usr/bin/wayland-flower 2> ../tests/testlog/wayland-flower.log +# 3. Surface animation +launch ../tests/test-client < ../tests/testdata/cl_surface4.dat 2> ../tests/testlog/test-client04.log waitcreate 2 -move wayland-flower 200 100 -show wayland-flower +resize test-client 200 300 +move test-client 400 250 0 +# +# fade and show/hide +animation test-client fade 400 +show test-client 1 +sleep 0.7 +hide test-client 1 sleep 1 -resize wayland-flower 500 400 -sleep 2 -kill wayland-flower +# +# slide.toleft and show/hide +animation test-client slide.toleft 400 +show test-client 1 +sleep 0.7 +hide test-client 1 sleep 1 # -launch /usr/bin/wayland-smoke 2> ../tests/testlog/wayland-smoke.log -waitcreate 2 -move wayland-smoke 100 50 -show wayland-smoke -sleep 0.3 -event XY=168,93 -event Button=Down -sleep 0.1 -event XY=151,88 -event Button=Up +# slide.toright and show/hide +animation test-client slide.toright 400 +show test-client 1 +sleep 0.7 +hide test-client 1 sleep 1 -resize wayland-smoke 400 400 -sleep 0.3 -event XY=457,211 -event Button=Down -sleep 0.1 -event XY=457,209 -event Button=Up +# +# slide.totop and show/hide +animation test-client slide.totop 400 +show test-client 1 +sleep 0.7 +hide test-client 1 sleep 1 -resize wayland-smoke 300 600 -sleep 0.4 -event XY=250,495 -event Button=Down -sleep 0.2 -event XY=246,498 -event Button=Up -sleep 0.8 -resize wayland-smoke 450 300 -sleep 0.3 -event XY=511,296 -event Button=Down -sleep 0.1 -event XY=R508,300 -event Button=Up +# +# slide.tobottom and show/hide +animation test-client slide.tobottom 400 +show test-client 1 +sleep 0.7 +hide test-client 1 +sleep 1 +# +# zoom and show/hide +animation test-client zoom 400 +show test-client 1 +sleep 0.7 +hide test-client 1 +sleep 2 +# +# fade and move +animation test-client fade 600 +move test-client 600 200 1 +sleep 1 +move test-client 500 300 1 sleep 1 -kill wayland-smoke +# +waitdestroy 60 sleep 1 # -# 4. Set Layer +# 4. Launch Weston sample client +#launch /usr/bin/wayland-flower 2> ../tests/testlog/wayland-flower.log +#waitcreate 2 +#move wayland-flower 200 100 +#show wayland-flower +#sleep 1 +#resize wayland-flower 500 400 +#sleep 2 +#kill wayland-flower +#sleep 1 +# +#launch /usr/bin/wayland-smoke 2> ../tests/testlog/wayland-smoke.log +#waitcreate 2 +#move wayland-smoke 100 50 +#show wayland-smoke +#sleep 0.3 +#event XY=168,93 +#event Button=Down +#sleep 0.1 +#event XY=151,88 +#event Button=Up +#sleep 1 +#resize wayland-smoke 400 400 +#sleep 0.3 +#event XY=457,211 +#event Button=Down +#sleep 0.1 +#event XY=457,209 +#event Button=Up +#sleep 1 +#resize wayland-smoke 300 600 +#sleep 0.4 +#event XY=250,495 +#event Button=Down +#sleep 0.2 +#event XY=246,498 +#event Button=Up +#sleep 0.8 +#resize wayland-smoke 450 300 +#sleep 0.3 +#event XY=511,296 +#event Button=Down +#sleep 0.1 +#event XY=R508,300 +#event Button=Up +#sleep 1 +#kill wayland-smoke +#sleep 1 +# +# 5. Set Layer launch ../tests/test-eflapp @1 -color=0xe02040ff > ../tests/testlog/test-eflapp1.log waitcreate 2 layer test-eflapp@1 101 @@ -135,16 +193,16 @@ show test-eflapp@2 sleep 2 # # resize EFL application -resize test-eflapp@2 200 300 +resize test-eflapp@2 300 300 sleep 1 resize test-eflapp@3 720 520 sleep 1 resize test-eflapp@3 520 380 sleep 1 resize test-eflapp@2 520 380 -sleep 1 +sleep 2 # -# 5. Raise/Lower +# 6. Raise/Lower raise test-eflapp@3 sleep 1 raise test-eflapp@4 @@ -158,18 +216,18 @@ sleep 1 lower test-eflapp@3 sleep 2 # -# 6. Layer Change +# 7. Layer Change layer test-eflapp@1 100 sleep 1 layer test-eflapp@2 100 sleep 2 # -# 7. layer visibility control +# 8. layer visibility control layer_visible 102 0 sleep 1 layer_visible 102 1 sleep 1 -# 8. kill eflapp's +# 9. kill eflapp's kill test-eflapp@1 sleep 0.5 kill test-eflapp@2 @@ -181,12 +239,12 @@ sleep 0.5 kill test-eflapp@5 sleep 2 # -# 9. Input test +# 10. Input test launch ../tests/test-client @1 -color=0xe0ff2020 -postsleep=60 < ../tests/testdata/cl_surface3.dat 2> ../tests/testlog/test-client11.log waitcreate 2 sleep 0.3 layer test-client@1 101 -move test-client@1 100 200 +move test-client@1 100 200 1 show test-client@1 sleep 0.5 event XY=240,303 @@ -200,7 +258,7 @@ launch ../tests/test-client @2 -color=0xc020ff20 -postsleep=60 < ../tests/testda waitcreate 2 sleep 0.3 layer test-client@2 101 -move test-client@2 250 300 +move test-client@2 250 300 1 show test-client@2 sleep 0.5 event XY=625,555 @@ -214,7 +272,7 @@ launch ../tests/test-client @3 -color=0xa02020ff -postsleep=60 < ../tests/testda waitcreate 2 sleep 0.3 layer test-client@3 101 -move test-client@3 400 400 +move test-client@3 400 400 1 show test-client@3 sleep 0.5 event XY=848,663 @@ -337,6 +395,6 @@ sleep 0.3 kill test-client@3 sleep 0.5 # -# 10. End of Test +# 11. End of Test bye diff --git a/tests/testdata/hs_animatest.dat b/tests/testdata/hs_animatest.dat new file mode 100644 index 0000000..3f5306c --- /dev/null +++ b/tests/testdata/hs_animatest.dat @@ -0,0 +1,69 @@ +# Test for Weston IVI Plugin for HomeScreen(SystemController) +# Animation Test +# +# 1. Surface animation +sleep 1 +launch ../tests/test-client < ../tests/testdata/cl_surface4.dat 2> ../tests/testlog/test-client04.log +waitcreate 2 +resize test-client 200 300 +move test-client 300 350 0 +# +# fade and show/hide +animation test-client fade 400 +# +show test-client +sleep 0.5 +hide test-client +sleep 1 +# +# slide.toleft and show/hide +animation test-client slide.toleft 400 +show test-client 1 +sleep 1 +hide test-client 1 +sleep 2 +# +# slide.toright and show/hide +animation test-client slide.toright 400 +show test-client 1 +sleep 2 +hide test-client 1 +sleep 2 +# +# slide.totop and show/hide +animation test-client slide.totop 400 +show test-client 1 +sleep 1 +hide test-client 1 +sleep 2 +# +# slide.tobottom and show/hide +animation test-client slide.tobottom 400 +show test-client 1 +sleep 1 +hide test-client 1 +sleep 2 +# +### zoom and show/hide +##animation test-client zoom 400 +##show test-client 1 +##sleep 1 +##hide test-client 1 +##sleep 3 +# +### fade and move +##animation test-client fade 600 +##move test-client 600 200 1 +##sleep 2 +##move test-client 500 300 1 +##sleep 3 +# +waitdestroy 60 +sleep 1 +# +kill test-client +sleep 0.5 +# +# 2. End of Test +bye + diff --git a/tests/testdata/hs_animatest_all.dat b/tests/testdata/hs_animatest_all.dat new file mode 100644 index 0000000..df84c97 --- /dev/null +++ b/tests/testdata/hs_animatest_all.dat @@ -0,0 +1,67 @@ +# Test for Weston IVI Plugin for HomeScreen(SystemController) +# Animation Test +# +# 1. Surface animation +launch ../tests/test-client < ../tests/testdata/cl_surface4.dat 2> ../tests/testlog/test-client04.log +waitcreate 2 +resize test-client 200 300 +move test-client 300 400 0 +# +# fade and show/hide +animation test-client fade 400 +show test-client 1 +sleep 1 +hide test-client 1 +sleep 2 +# +# slide.toleft and show/hide +animation test-client slide.toleft 400 +show test-client 1 +sleep 1 +hide test-client 1 +sleep 2 +# +# slide.toright and show/hide +animation test-client slide.toright 400 +show test-client 1 +sleep 1 +hide test-client 1 +sleep 2 +# +# slide.totop and show/hide +animation test-client slide.totop 400 +show test-client 1 +sleep 1 +hide test-client 1 +sleep 2 +# +# slide.tobottom and show/hide +animation test-client slide.tobottom 400 +show test-client 1 +sleep 1 +hide test-client 1 +sleep 2 +# +# zoom and show/hide +animation test-client zoom 400 +show test-client 1 +sleep 1 +hide test-client 1 +sleep 3 +# +# fade and move +animation test-client fade 600 +move test-client 600 200 1 +sleep 2 +move test-client 500 300 1 +sleep 3 +# +waitdestroy 60 +sleep 1 +# +kill test-client +sleep 0.5 +# +# 2. End of Test +bye + diff --git a/tests/weston-plugin-test b/tests/weston-plugin-test index 4fc0818..8dead71 100755 --- a/tests/weston-plugin-test +++ b/tests/weston-plugin-test @@ -5,25 +5,18 @@ # Remark: This examination premises that Weston does not run. # 1 Delete log file -rm -fr ../tests/testlog -mkdir ../tests/testlog +mkdir ../tests/testlog 2> /dev/null +rm -fr ../tests/testlog/* 2> /dev/null # 2 Start Pseudo event device (for Touch Panel) ../tests/test-send_event -d -mq=5551 2> ../tests/testlog/event_log.log & sleep 1 # 3 Weston/Wayland Envionment -export XDG_RUNTIME_DIR=/tmp/run-root export QT_QPA_PLATFORM=wayland export ELM_ENGINE=wayland_egl export ECORE_EVAS_ENGINE=wayland_egl -#export ELM_ENGINE=wayland_shm -#export ECORE_EVAS_ENGINE=wayland_shm -export EVAS_FONT_DPI=72 -export ECORE_IMF_MODULE=isf -export ELM_MODULES="ctxpopup_copypasteUI>entry/api:datetime_input_ctxpopup>datetime/api" -export ELM_SCALE="0.7" -export ELM_PROFILE=mobile +export XDG_RUNTIME_DIR=/run/user/5000 # 4 Set Environment for Test export WESTON_IVI_PLUGIN_DIR="../src/.libs" @@ -31,7 +24,7 @@ export WESTON_IVI_PLUGIN_DIR="../src/.libs" # 5 Start Weston export XDG_CONFIG_HOME="../tests" MOD_DIR="$PWD/../src/.libs" -/usr/bin/weston --backend=drm-backend.so --modules=$MOD_DIR/ico_plugin_loader.so --idle-time=0 --log=../tests/testlog/weston.log & +/usr/bin/weston --modules=$MOD_DIR/ico_plugin_loader.so --idle-time=0 --log=../tests/testlog/weston.log & sleep 1 # 6 Set library path @@ -41,7 +34,7 @@ export LD_LIBRARY_PATH=../src/.libs:$LD_LIBRARY_PATH ../tests/test-homescreen < ../tests/testdata/hs_alltest.dat 2> ../tests/testlog/test-homescreen.log # 8 End of Test -sleep 1 +sleep 2 /usr/bin/killall weston /usr/bin/killall test-send_event sleep 1 @@ -64,7 +57,7 @@ fi if [ "$?" != "1" ] ; then FOUND_ERR=1 fi -/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" if [ "$?" != "1" ] ; then FOUND_ERR=1 fi diff --git a/tests/weston-plugin-test.anima b/tests/weston-plugin-test.anima new file mode 100755 index 0000000..5360a02 --- /dev/null +++ b/tests/weston-plugin-test.anima @@ -0,0 +1,69 @@ +#!/bin/sh +# +# Weston IVI Plugin Test +# +# Remark: This examination premises that Weston does not run. + +# 1 Delete log file +mkdir ../tests/testlog 2> /dev/null +rm -fr ../tests/testlog/* 2> /dev/null + +# 2 Start Pseudo event device (for Touch Panel) +../tests/test-send_event -d -mq=5551 2> ../tests/testlog/event_log.log & +sleep 1 + +# 3 Weston/Wayland Envionment +export QT_QPA_PLATFORM=wayland +export ELM_ENGINE=wayland_egl +export ECORE_EVAS_ENGINE=wayland_egl + +# 4 Set Environment for Test +export WESTON_IVI_PLUGIN_DIR="../src/.libs" + +# 5 Start Weston +export XDG_CONFIG_HOME="../tests" +MOD_DIR="$PWD/../src/.libs" +/usr/bin/weston --modules=$MOD_DIR/ico_plugin_loader.so --idle-time=0 --log=../tests/testlog/weston.log & +sleep 1 + +# 6 Set library path +export LD_LIBRARY_PATH=../src/.libs:$LD_LIBRARY_PATH + +# 7 Start test-homescreen +../tests/test-homescreen < ../tests/testdata/hs_animatest.dat 2> ../tests/testlog/test-homescreen.log + +# 8 End of Test +sleep 2 +/usr/bin/killall weston +/usr/bin/killall test-send_event +sleep 1 + +# 9 Check Error +FOUND_ERR=0 +/bin/grep "ERR>" testlog/* +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "WRN>" testlog/* +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "Error" testlog/* +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "error" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi + +if [ $FOUND_ERR = 0 ] ; then + echo "Weston IVI Plugin Test: OK" +else + echo "Weston IVI Plugin Test: ERROR" +fi + diff --git a/tests/weston-plugin-test.input b/tests/weston-plugin-test.input index ce9e8a7..7c7af36 100755 --- a/tests/weston-plugin-test.input +++ b/tests/weston-plugin-test.input @@ -63,7 +63,7 @@ fi if [ "$?" != "1" ] ; then FOUND_ERR=1 fi -/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" if [ "$?" != "1" ] ; then FOUND_ERR=1 fi diff --git a/tests/weston-plugin-test.notouch b/tests/weston-plugin-test.notouch index e4803f8..4ed6c5e 100755 --- a/tests/weston-plugin-test.notouch +++ b/tests/weston-plugin-test.notouch @@ -64,7 +64,7 @@ fi if [ "$?" != "1" ] ; then FOUND_ERR=1 fi -/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" if [ "$?" != "1" ] ; then FOUND_ERR=1 fi diff --git a/tests/weston-plugin-test.resize b/tests/weston-plugin-test.resize index 95f48a5..53dafa2 100755 --- a/tests/weston-plugin-test.resize +++ b/tests/weston-plugin-test.resize @@ -64,7 +64,7 @@ fi if [ "$?" != "1" ] ; then FOUND_ERR=1 fi -/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" if [ "$?" != "1" ] ; then FOUND_ERR=1 fi diff --git a/tests/weston-plugin-test.resize_flower b/tests/weston-plugin-test.resize_flower index 47ecdfc..ecf7fba 100755 --- a/tests/weston-plugin-test.resize_flower +++ b/tests/weston-plugin-test.resize_flower @@ -64,7 +64,7 @@ fi if [ "$?" != "1" ] ; then FOUND_ERR=1 fi -/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" if [ "$?" != "1" ] ; then FOUND_ERR=1 fi diff --git a/tests/weston-plugin-test.resize_native b/tests/weston-plugin-test.resize_native index e2afd5a..d8ff139 100755 --- a/tests/weston-plugin-test.resize_native +++ b/tests/weston-plugin-test.resize_native @@ -64,7 +64,7 @@ fi if [ "$?" != "1" ] ; then FOUND_ERR=1 fi -/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" if [ "$?" != "1" ] ; then FOUND_ERR=1 fi diff --git a/tests/weston-plugin-test.resize_smoke b/tests/weston-plugin-test.resize_smoke index 8f417ca..4816cf3 100755 --- a/tests/weston-plugin-test.resize_smoke +++ b/tests/weston-plugin-test.resize_smoke @@ -68,7 +68,7 @@ fi if [ "$?" != "1" ] ; then FOUND_ERR=1 fi -/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" if [ "$?" != "1" ] ; then FOUND_ERR=1 fi diff --git a/tests/weston-plugin-test.resize_smoke2 b/tests/weston-plugin-test.resize_smoke2 index 17b861f..4ecf436 100755 --- a/tests/weston-plugin-test.resize_smoke2 +++ b/tests/weston-plugin-test.resize_smoke2 @@ -64,7 +64,7 @@ fi if [ "$?" != "1" ] ; then FOUND_ERR=1 fi -/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" if [ "$?" != "1" ] ; then FOUND_ERR=1 fi diff --git a/tests/weston-plugin-test.slide b/tests/weston-plugin-test.slide index d5ae9d6..08c9c2c 100755 --- a/tests/weston-plugin-test.slide +++ b/tests/weston-plugin-test.slide @@ -62,7 +62,7 @@ fi if [ "$?" != "1" ] ; then FOUND_ERR=1 fi -/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" if [ "$?" != "1" ] ; then FOUND_ERR=1 fi diff --git a/tests/weston-plugin-test_gdb b/tests/weston-plugin-test_gdb index 7fcaee5..8a420a1 100755 --- a/tests/weston-plugin-test_gdb +++ b/tests/weston-plugin-test_gdb @@ -63,7 +63,7 @@ fi if [ "$?" != "1" ] ; then FOUND_ERR=1 fi -/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" if [ "$?" != "1" ] ; then FOUND_ERR=1 fi diff --git a/tests/weston-plugin-vbox b/tests/weston-plugin-vbox new file mode 100755 index 0000000..06304ab --- /dev/null +++ b/tests/weston-plugin-vbox @@ -0,0 +1,72 @@ +#!/bin/sh +# +# Weston IVI Plugin Test +# +# Remark: This examination premises that Weston does not run. + +# 1 Delete log file +mkdir ../tests/testlog 2> /dev/null +rm -fr ../tests/testlog/* 2> /dev/null + +# 2 Start Pseudo event device (for Touch Panel) +../tests/test-send_event -d -mq=5551 2> ../tests/testlog/event_log.log & +sleep 1 + +# 3 Weston/Wayland Envionment +export QT_QPA_PLATFORM=wayland +#export ELM_ENGINE=wayland_egl +#export ECORE_EVAS_ENGINE=wayland_egl +export ELM_ENGINE=wayland_shm +export ECORE_EVAS_ENGINE=wayland_shm +export XDG_RUNTIME_DIR=/run/user/5000 + +# 4 Set Environment for Test +export WESTON_IVI_PLUGIN_DIR="../src/.libs" + +# 5 Start Weston +export XDG_CONFIG_HOME="../tests" +MOD_DIR="$PWD/../src/.libs" +/usr/bin/weston --backend=fbdev-backend.so --modules=$MOD_DIR/ico_plugin_loader.so --idle-time=0 --log=../tests/testlog/weston.log & +sleep 1 + +# 6 Set library path +export LD_LIBRARY_PATH=../src/.libs:$LD_LIBRARY_PATH + +# 7 Start test-homescreen +../tests/test-homescreen < ../tests/testdata/hs_alltest.dat 2> ../tests/testlog/test-homescreen.log + +# 8 End of Test +sleep 2 +/usr/bin/killall weston +/usr/bin/killall test-send_event +sleep 1 + +# 9 Check Error +FOUND_ERR=0 +/bin/grep "ERR>" testlog/* +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "WRN>" testlog/* +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "Error" testlog/* +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "error" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" | /bin/grep -v "initialize backlight" +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi + +if [ $FOUND_ERR = 0 ] ; then + echo "Weston IVI Plugin Test: OK" +else + echo "Weston IVI Plugin Test: ERROR" +fi + diff --git a/tests/weston.ini b/tests/weston.ini index 62d8338..cda6216 100644 --- a/tests/weston.ini +++ b/tests/weston.ini @@ -2,7 +2,14 @@ modules=error_but_no_problem_for_test.so # This is Error for Test(No Problem) -#[output] +#[input-method] +#path=/no_input_method_err_but_no_problem.so + +[shell] +num-workspaces=1 +shell-exe= + +[output] #name=HDMI3 #mode=1680x945 #mode=1920x1080 @@ -23,3 +30,26 @@ modules=error_but_no_problem_for_test.so #name=X1 #mode=1024x768 #transform=flipped-270 + +[ivi-plugin] +modules=ico_ivi_shell.so,ico_window_mgr.so,ico_window_animation.so,ico_input_mgr.so + +[ivi-display] +displayno=1,0 + +[ivi-animation] +# default animation +default=fade +# animation time (ms) +time=500 +# animation frame rate(frame/sec) +fps=15 + +[ivi-debug] +# debug flags +# bit.0 0=hide on surface create(for with HomeScreen)/1=show on surface create +flag=0 + +# 0=no debug log write(1=err/2=warn/3=info/4=debug) +log=4 + diff --git a/tests/weston_ivi_plugin.ini b/tests/weston_ivi_plugin.ini deleted file mode 100644 index 98ed6f7..0000000 --- a/tests/weston_ivi_plugin.ini +++ /dev/null @@ -1,23 +0,0 @@ -[plugin] -modules=ico_ivi_common.so,ico_ivi_shell.so,ico_window_mgr.so,ico_window_animation.so,ico_input_mgr.so - -[shell] -# default animation -animation=fade -# animation time (ms) -animation_time=500 -# animation frame rate(frame/sec) -animation_fps=15 - -# 0=hide on surface create(for with HomeScreen)/1=show on surface create(for Debug) -visible_on_create=0 - -[debug] -# option flag -# 0x00000001 : =1, At the time of unvisible of surface, it travels surface outside a screen. -# : =0, Exclude surface of the unvisible from a list of surface of Westons. -option_flag=1 - -# 0=no debug write(1=err/2=warn/3=info/4=debug) -ivi_debug=4 - diff --git a/weston.ini b/weston.ini deleted file mode 100644 index 3ed96fa..0000000 --- a/weston.ini +++ /dev/null @@ -1,23 +0,0 @@ -[core] -modules=ico_plugin_loader.so - -[output] -name=HDMI3 -#mode=1680x945 -mode=173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync -#transform=90 - -#[output] -#name=LVDS1 -#mode=1680x1050 -#transform=90 - -[output] -name=VGA1 -#mode=173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync -#transform=90 - -#[output] -#name=X1 -#mode=1024x768 -#transform=flipped-270 diff --git a/weston_ivi_plugin.ini b/weston_ivi_plugin.ini deleted file mode 100644 index 98ed6f7..0000000 --- a/weston_ivi_plugin.ini +++ /dev/null @@ -1,23 +0,0 @@ -[plugin] -modules=ico_ivi_common.so,ico_ivi_shell.so,ico_window_mgr.so,ico_window_animation.so,ico_input_mgr.so - -[shell] -# default animation -animation=fade -# animation time (ms) -animation_time=500 -# animation frame rate(frame/sec) -animation_fps=15 - -# 0=hide on surface create(for with HomeScreen)/1=show on surface create(for Debug) -visible_on_create=0 - -[debug] -# option flag -# 0x00000001 : =1, At the time of unvisible of surface, it travels surface outside a screen. -# : =0, Exclude surface of the unvisible from a list of surface of Westons. -option_flag=1 - -# 0=no debug write(1=err/2=warn/3=info/4=debug) -ivi_debug=4 - -- 2.7.4