0.9.14 release -- improve: it corresponded to Wayland/Weston 1.4.0 15/16115/1
authorMasayuki Sasaki <masayuki.sasaki@mail.toyota-td.jp>
Fri, 7 Feb 2014 04:01:30 +0000 (13:01 +0900)
committerMasayuki Sasaki <masayuki.sasaki@mail.toyota-td.jp>
Fri, 7 Feb 2014 04:07:27 +0000 (13:07 +0900)
Change-Id: I1567c6659cf59da67ad57a1e59b0f4beb354d383
Signed-off-by: Masayuki Sasaki <masayuki.sasaki@mail.toyota-td.jp>
21 files changed:
configure.ac
packaging/ico-uxf-weston-plugin.changes
packaging/ico-uxf-weston-plugin.spec
protocol/xdg-shell.xml [new file with mode: 0644]
settings/weston.ini
src/Makefile.am
src/ico_exposay.c [new file with mode: 0644]
src/ico_input-panel.c [new file with mode: 0644]
src/ico_input_mgr.c
src/ico_input_mgr.h
src/ico_ivi_common_private.h
src/ico_ivi_shell.c
src/ico_ivi_shell.h [new file with mode: 0644]
src/ico_ivi_shell_private.h
src/ico_plugin_loader.c
src/ico_plugin_version.h
src/ico_window_animation.c
src/ico_window_mgr.c
src/ico_window_mgr.h
src/ico_window_mgr_private.h
tests/weston.ini

index 1a070d2..7f28765 100644 (file)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.68])
 AC_INIT([ico-uxf-weston-plugin],
-        [0.9.12],
+        [0.9.14],
         [https://BUG-REPORT-ADDRESS])
 
 AC_CONFIG_HEADERS([config.h])
@@ -30,7 +30,9 @@ AC_CHECK_HEADERS([execinfo.h])
 
 AC_CHECK_FUNCS([mkostemp strchrnul])
 
-PKG_CHECK_MODULES([PLUGIN], [weston >= 1.1.1 pixman-1 xkbcommon])
+PKG_CHECK_MODULES([PLUGIN], [wayland-server >= 1.3.0 weston >= 1.3.0 pixman-1 xkbcommon])
+
+PKG_CHECK_MODULES([EGL], [egl])
 
 if test "x$GCC" = "xyes"; then
        my_common_gcc_flags="-Wall -Wextra -Wno-unused-parameter \
index 775ed7b..ef29faa 100644 (file)
@@ -1,3 +1,10 @@
+* Fri Feb 07 2014 Shibata Makoto <shibata@mac.tec.toyota.co.jp> accepted/tizen/ivi/20140128.174118@6241868
+- 0.9.14 release
+-- improve: it corresponded to Wayland/Weston 1.4.0
+-- bugfix:  when change of surface different from deletion of surface overlaps, ico_window_mgr may crash
+-- bugfix:  when HomeScreen shows the menu and installation/uninstallation of a package are performed, a live thumbnail may blink
+-- improve: output the conflict message of a configuration file(weston.ini) with a weston-ivi-config package
+
 * Fri Jan 24 2014 Shibata Makoto <shibata@mac.tec.toyota.co.jp> accepted/tizen/ivi/release/20140109.181723@96ba865
 - 0.9.12 release
 -- bugfix: ico_input_mgr avoid crashes in case the assigned app were not running
index f108e53..d81c088 100644 (file)
@@ -1,13 +1,13 @@
 Name:       ico-uxf-weston-plugin
 Summary:    Weston Plugins for IVI
-Version:    0.9.12
+Version:    0.9.14
 Release:    1.1
 Group:      Graphics & UI Framework/Automotive UI
 License:    MIT
 URL:        ""
 Source0:    %{name}-%{version}.tar.bz2
 
-BuildRequires: pkgconfig(weston) >= 1.3.0
+BuildRequires: pkgconfig(weston) >= 1.4.0
 BuildRequires: pkgconfig(pixman-1)
 BuildRequires: pkgconfig(xkbcommon) >= 0.0.578
 BuildRequires: pkgconfig(eina)
@@ -18,8 +18,9 @@ BuildRequires: pkgconfig(ecore-wayland)
 BuildRequires: pkgconfig(aul)
 BuildRequires: pkgconfig(ecore)
 BuildRequires: mesa-devel
-Requires: weston >= 1.3.0
+Requires: weston >= 1.4.0
 Requires: weekeyboard
+Conflicts: weston-ivi-config
 
 %description
 Weston Plugins for IVI
diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml
new file mode 100644 (file)
index 0000000..4e5cff8
--- /dev/null
@@ -0,0 +1,438 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="xdg_shell">
+
+  <copyright>
+    Copyright © 2008-2013 Kristian Høgsberg
+    Copyright © 2013      Rafael Antognolli
+    Copyright © 2013      Jasper St. Pierre
+    Copyright © 2010-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.
+  </copyright>
+
+  <interface name="xdg_shell" version="1">
+    <description summary="create desktop-style surfaces">
+      This interface is implemented by servers that provide
+      desktop-style user interfaces.
+
+      It allows clients to associate a xdg_surface with
+      a basic surface.
+    </description>
+
+    <enum name="version">
+      <description summary="latest protocol version">
+       Use this enum to check the protocol version, and it will be updated
+       automatically.
+      </description>
+      <entry name="current" value="1" summary="Always the latest version"/>
+    </enum>
+
+
+    <request name="use_unstable_version">
+      <description summary="enable use of this unstable version">
+       Use this request in order to enable use of this interface.
+
+       Understand and agree that one is using an unstable interface,
+       that will likely change in the future, breaking the API.
+      </description>
+      <arg name="version" type="int"/>
+    </request>
+
+    <request name="get_xdg_surface">
+      <description summary="create a shell surface from a surface">
+       Create a shell surface for an existing surface.
+
+       Only one shell or popup surface can be associated with a given
+       surface.
+      </description>
+      <arg name="id" type="new_id" interface="xdg_surface"/>
+      <arg name="surface" type="object" interface="wl_surface"/>
+    </request>
+
+    <request name="get_xdg_popup">
+      <description summary="create a shell surface from a surface">
+       Create a popup surface for an existing surface.
+
+       Only one shell or popup surface can be associated with a given
+       surface.
+      </description>
+      <arg name="id" type="new_id" interface="xdg_popup"/>
+      <arg name="surface" type="object" interface="wl_surface"/>
+      <arg name="parent" type="object" interface="wl_surface"/>
+      <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+      <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+      <arg name="x" type="int"/>
+      <arg name="y" type="int"/>
+      <arg name="flags" type="uint"/>
+    </request>
+  </interface>
+
+  <interface name="xdg_surface" version="1">
+
+    <description summary="desktop-style metadata interface">
+      An interface that may be implemented by a wl_surface, for
+      implementations that provide a desktop-style user interface.
+
+      It provides requests to treat surfaces like windows, allowing to set
+      properties like maximized, fullscreen, minimized, and to move and resize
+      them, and associate metadata like title and app id.
+
+      On the server side the object is automatically destroyed when
+      the related wl_surface is destroyed.  On client side,
+      xdg_surface.destroy() must be called before destroying
+      the wl_surface object.
+    </description>
+
+    <request name="destroy" type="destructor">
+      <description summary="remove xdg_surface interface">
+       The xdg_surface interface is removed from the wl_surface object
+       that was turned into a xdg_surface with
+       xdg_shell.get_xdg_surface request. The xdg_surface properties,
+       like maximized and fullscreen, are lost. The wl_surface loses
+       its role as a xdg_surface. The wl_surface is unmapped.
+      </description>
+    </request>
+
+    <request name="set_transient_for">
+      <description summary="surface is a child of another surface">
+       Setting a surface as transient of another means that it is child
+       of another surface.
+
+       Child surfaces are stacked above their parents, and will be
+       unmapped if the parent is unmapped too. They should not appear
+       on task bars and alt+tab.
+      </description>
+      <arg name="parent" type="object" interface="wl_surface" allow-null="true"/>
+    </request>
+
+    <request name="set_title">
+      <description summary="set surface title">
+       Set a short title for the surface.
+
+       This string may be used to identify the surface in a task bar,
+       window list, or other user interface elements provided by the
+       compositor.
+
+       The string must be encoded in UTF-8.
+      </description>
+      <arg name="title" type="string"/>
+    </request>
+
+    <request name="set_app_id">
+      <description summary="set surface class">
+       Set an id for the surface.
+
+       The app id identifies the general class of applications to which
+       the surface belongs.
+
+       It should be the ID that appears in the new desktop entry
+       specification, the interface name.
+      </description>
+      <arg name="app_id" type="string"/>
+    </request>
+
+    <request name="pong">
+      <description summary="respond to a ping event">
+       A client must respond to a ping event with a pong request or
+       the client may be deemed unresponsive.
+      </description>
+      <arg name="serial" type="uint" summary="serial of the ping event"/>
+    </request>
+
+    <event name="ping">
+      <description summary="ping client">
+       Ping a client to check if it is receiving events and sending
+       requests. A client is expected to reply with a pong request.
+      </description>
+      <arg name="serial" type="uint"/>
+    </event>
+
+    <request name="move">
+      <description summary="start an interactive move">
+       Start a pointer-driven move of the surface.
+
+       This request must be used in response to a button press event.
+       The server may ignore move requests depending on the state of
+       the surface (e.g. fullscreen or maximized).
+      </description>
+      <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+      <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+    </request>
+
+    <enum name="resize_edge">
+      <description summary="edge values for resizing">
+       These values are used to indicate which edge of a surface
+       is being dragged in a resize operation. The server may
+       use this information to adapt its behavior, e.g. choose
+       an appropriate cursor image.
+      </description>
+      <entry name="none" value="0"/>
+      <entry name="top" value="1"/>
+      <entry name="bottom" value="2"/>
+      <entry name="left" value="4"/>
+      <entry name="top_left" value="5"/>
+      <entry name="bottom_left" value="6"/>
+      <entry name="right" value="8"/>
+      <entry name="top_right" value="9"/>
+      <entry name="bottom_right" value="10"/>
+    </enum>
+
+    <request name="resize">
+      <description summary="start an interactive resize">
+       Start a pointer-driven resizing of the surface.
+
+       This request must be used in response to a button press event.
+       The server may ignore resize requests depending on the state of
+       the surface (e.g. fullscreen or maximized).
+      </description>
+      <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+      <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+      <arg name="edges" type="uint" summary="which edge or corner is being dragged"/>
+    </request>
+
+    <event name="configure">
+      <description summary="suggest resize">
+       The configure event asks the client to resize its surface.
+
+       The size is a hint, in the sense that the client is free to
+       ignore it if it doesn't resize, pick a smaller size (to
+       satisfy aspect ratio or resize in steps of NxM pixels).
+
+       The edges parameter provides a hint about how the surface
+       was resized. The client may use this information to decide
+       how to adjust its content to the new size (e.g. a scrolling
+       area might adjust its content position to leave the viewable
+       content unmoved). Valid edge values are from resize_edge enum.
+
+       The client is free to dismiss all but the last configure
+       event it received.
+
+       The width and height arguments specify the size of the window
+       in surface local coordinates.
+      </description>
+
+      <arg name="edges" type="uint"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+    </event>
+
+    <request name="set_output">
+      <description summary="set the default output used by this surface">
+       Set the default output used by this surface when it is first mapped.
+
+       If this value is NULL (default), it's up to the compositor to choose
+       which display will be used to map this surface.
+
+       When fullscreen or maximized state are set on this surface, and it
+       wasn't mapped yet, the output set with this method will be used.
+       Otherwise, the output where the surface is currently mapped will be
+       used.
+      </description>
+      <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+    </request>
+
+    <event name="request_set_fullscreen">
+      <description summary="server requests that the client set fullscreen">
+       Event sent from the compositor to the client requesting that the client
+       goes to a fullscreen state. It's the client job to call set_fullscreen
+       and really trigger the fullscreen state.
+      </description>
+    </event>
+
+    <event name="request_unset_fullscreen">
+      <description summary="server requests that the client unset fullscreen">
+       Event sent from the compositor to the client requesting that the client
+       leaves the fullscreen state. It's the client job to call
+       unset_fullscreen and really leave the fullscreen state.
+      </description>
+    </event>
+
+    <request name="set_fullscreen">
+      <description summary="set the surface state as fullscreen">
+       Set the surface as fullscreen.
+
+       After this request, the compositor should send a configure event
+       informing the output size.
+
+       This request informs the compositor that the next attached buffer
+       committed will be in a fullscreen state. The buffer size should be the
+       same size as the size informed in the configure event, if the client
+       doesn't want to leave any empty area.
+
+       In other words: the next attached buffer after set_maximized is the new
+       maximized buffer. And the surface will be positioned at the maximized
+       position on commit.
+
+       A simple way to synchronize and wait for the correct configure event is
+       to use a wl_display.sync request right after the set_fullscreen
+       request. When the sync callback returns, the last configure event
+       received just before it will be the correct one, and should contain the
+       right size for the surface to maximize.
+
+       Setting one state won't unset another state. Use
+       xdg_surface.unset_fullscreen for unsetting it.
+      </description>
+    </request>
+
+    <request name="unset_fullscreen">
+      <description summary="unset the surface state as fullscreen">
+       Unset the surface fullscreen state.
+
+       Same negotiation as set_fullscreen must be used.
+      </description>
+    </request>
+
+    <event name="request_set_maximized">
+      <description summary="server requests that the client set maximized">
+       Event sent from the compositor to the client requesting that the client
+       goes to a maximized state. It's the client job to call set_maximized
+       and really trigger the maximized state.
+      </description>
+    </event>
+
+    <event name="request_unset_maximized">
+      <description summary="server requests that the client unset maximized">
+       Event sent from the compositor to the client requesting that the client
+       leaves the maximized state. It's the client job to call unset_maximized
+       and really leave the maximized state.
+      </description>
+    </event>
+
+    <request name="set_maximized">
+      <description summary="set the surface state as maximized">
+       Set the surface as maximized.
+
+       After this request, the compositor will send a configure event
+       informing the output size minus panel and other MW decorations.
+
+       This request informs the compositor that the next attached buffer
+       committed will be in a maximized state. The buffer size should be the
+       same size as the size informed in the configure event, if the client
+       doesn't want to leave any empty area.
+
+       In other words: the next attached buffer after set_maximized is the new
+       maximized buffer. And the surface will be positioned at the maximized
+       position on commit.
+
+       A simple way to synchronize and wait for the correct configure event is
+       to use a wl_display.sync request right after the set_maximized request.
+       When the sync callback returns, the last configure event received just
+       before it will be the correct one, and should contain the right size
+       for the surface to maximize.
+
+       Setting one state won't unset another state. Use
+       xdg_surface.unset_maximized for unsetting it.
+      </description>
+    </request>
+
+    <request name="unset_maximized">
+      <description summary="unset the surface state as maximized">
+       Unset the surface maximized state.
+
+       Same negotiation as set_maximized must be used.
+      </description>
+    </request>
+
+    <request name="set_minimized">
+      <description summary="set the surface state as minimized">
+       Set the surface minimized state.
+
+       Setting one state won't unset another state.
+      </description>
+    </request>
+
+    <event name="focused_set">
+      <description summary="surface was focused">
+       The focused_set event is sent when this surface has been
+       activated. Window decorations should be updated accordingly.
+      </description>
+    </event>
+
+    <event name="focused_unset">
+      <description summary="surface was unfocused">
+       The focused_unset event is sent when this surface has been
+       deactivated, because another surface has been activated. Window
+       decorations should be updated accordingly.
+      </description>
+    </event>
+  </interface>
+
+  <interface name="xdg_popup" version="1">
+    <description summary="desktop-style metadata interface">
+      An interface that may be implemented by a wl_surface, for
+      implementations that provide a desktop-style popups/menus. A popup
+      surface is a transient surface with an added pointer grab.
+
+      An existing implicit grab will be changed to owner-events mode,
+      and the popup grab will continue after the implicit grab ends
+      (i.e. releasing the mouse button does not cause the popup to be
+      unmapped).
+
+      The popup grab continues until the window is destroyed or a mouse
+      button is pressed in any other clients window. A click in any of
+      the clients surfaces is reported as normal, however, clicks in
+      other clients surfaces will be discarded and trigger the callback.
+
+      The x and y arguments specify the locations of the upper left
+      corner of the surface relative to the upper left corner of the
+      parent surface, in surface local coordinates.
+
+      xdg_popup surfaces are always transient for another surface.
+    </description>
+
+    <request name="destroy" type="destructor">
+      <description summary="remove xdg_surface interface">
+       The xdg_surface interface is removed from the wl_surface object
+       that was turned into a xdg_surface with
+       xdg_shell.get_xdg_surface request. The xdg_surface properties,
+       like maximized and fullscreen, are lost. The wl_surface loses
+       its role as a xdg_surface. The wl_surface is unmapped.
+      </description>
+    </request>
+
+    <request name="pong">
+      <description summary="respond to a ping event">
+       A client must respond to a ping event with a pong request or
+       the client may be deemed unresponsive.
+      </description>
+      <arg name="serial" type="uint" summary="serial of the ping event"/>
+    </request>
+
+    <event name="ping">
+      <description summary="ping client">
+       Ping a client to check if it is receiving events and sending
+       requests. A client is expected to reply with a pong request.
+      </description>
+      <arg name="serial" type="uint"/>
+    </event>
+
+    <event name="popup_done">
+      <description summary="popup interaction is done">
+       The popup_done event is sent out when a popup grab is broken,
+       that is, when the users clicks a surface that doesn't belong
+       to the client owning the popup surface.
+      </description>
+      <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+    </event>
+
+  </interface>
+</protocol>
index 83b7f21..673fbc4 100644 (file)
@@ -4,7 +4,7 @@ shell=
 
 [shell]
 num-workspaces=1
-shell-exe=
+client=
 locking=false
 animation=fade
 startup-animation=fade
index ab5f846..b82a9bf 100644 (file)
@@ -2,6 +2,7 @@ lib_LTLIBRARIES = libico-uxf-weston-plugin.la
 
 pkginclude_HEADERS =               \
        desktop-shell-client-protocol.h         \
+       xdg-shell-client-protocol.h                     \
        input-method-client-protocol.h          \
        workspaces-client-protocol.h            \
        ico_window_mgr-client-protocol.h        \
@@ -13,6 +14,7 @@ libico_uxf_weston_plugin_la_LIBADD = -ldrm_intel -lrt -lm
 libico_uxf_weston_plugin_la_LDFLAGS = -version-info 0:9:0
 libico_uxf_weston_plugin_la_SOURCES =          \
        desktop-shell-protocol.c                \
+       xdg-shell-protocol.c                    \
        input-method-protocol.c                 \
        workspaces-protocol.c                   \
        ico_window_mgr-protocol.c               \
@@ -56,20 +58,21 @@ 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.h                                 \
        ico_ivi_shell.c                                 \
+       ico_exposay.c                                   \
+       ico_input-panel.c                               \
        ico_ivi_shell_private.h                 \
        ico_ivi_common_private.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
+       xdg-shell-protocol.c                    \
+       xdg-shell-server-protocol.h
 
 # Multi Window Manager
 ico_window_mgr = ico_window_mgr.la
 ico_window_mgr_la_LDFLAGS = -module -avoid-version
-ico_window_mgr_la_LIBADD = -ldrm_intel $(PLUGIN_LIBS) $(AUL_LIBS)
+ico_window_mgr_la_LIBADD = -lEGL -lGLESv2 -ldrm_intel $(PLUGIN_LIBS) $(AUL_LIBS)
 ico_window_mgr_la_CFLAGS = -I/usr/include/libdrm $(GCC_CFLAGS) $(EXT_CFLAGS) $(PLUGIN_CFLAGS)
 ico_window_mgr_la_SOURCES =                    \
        ico_window_mgr.c                                \
@@ -108,6 +111,9 @@ BUILT_SOURCES =                                             \
        desktop-shell-protocol.c                \
        desktop-shell-server-protocol.h \
        desktop-shell-client-protocol.h \
+       xdg-shell-protocol.c                    \
+       xdg-shell-server-protocol.h             \
+       xdg-shell-client-protocol.h             \
        input-method-protocol.c                 \
        input-method-server-protocol.h  \
        input-method-client-protocol.h  \
diff --git a/src/ico_exposay.c b/src/ico_exposay.c
new file mode 100644 (file)
index 0000000..21f306f
--- /dev/null
@@ -0,0 +1,605 @@
+/*
+ * Copyright © 2010-2012 Intel Corporation
+ * Copyright © 2011-2012 Collabora, Ltd.
+ * Copyright © 2013 Raspberry Pi Foundation
+ * Copyright © 2013-2014 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.
+ */
+
+#include <linux/input.h>
+
+#include "ico_ivi_shell.h"
+
+struct exposay_surface {
+    struct desktop_shell *shell;
+    struct weston_surface *surface;
+    struct weston_view *view;
+    struct wl_list link;
+
+    int x;
+    int y;
+    int width;
+    int height;
+    double scale;
+
+    int row;
+    int column;
+
+    /* The animations only apply a transformation for their own lifetime,
+     * and don't have an option to indefinitely maintain the
+     * transformation in a steady state - so, we apply our own once the
+     * animation has finished. */
+    struct weston_transform transform;
+};
+
+static void exposay_set_state(struct desktop_shell *shell,
+                              enum exposay_target_state state,
+                  struct weston_seat *seat);
+static void exposay_check_state(struct desktop_shell *shell);
+
+static void
+exposay_in_flight_inc(struct desktop_shell *shell)
+{
+    shell->exposay.in_flight++;
+}
+
+static void
+exposay_in_flight_dec(struct desktop_shell *shell)
+{
+    if (--shell->exposay.in_flight > 0)
+        return;
+
+    exposay_check_state(shell);
+}
+
+static void
+exposay_animate_in_done(struct weston_view_animation *animation, void *data)
+{
+    struct exposay_surface *esurface = data;
+
+    wl_list_insert(&esurface->view->geometry.transformation_list,
+                   &esurface->transform.link);
+    weston_matrix_init(&esurface->transform.matrix);
+    weston_matrix_scale(&esurface->transform.matrix,
+                        esurface->scale, esurface->scale, 1.0f);
+    weston_matrix_translate(&esurface->transform.matrix,
+                            esurface->x - esurface->view->geometry.x,
+                esurface->y - esurface->view->geometry.y,
+                0);
+
+    weston_view_geometry_dirty(esurface->view);
+    weston_compositor_schedule_repaint(esurface->view->surface->compositor);
+
+    exposay_in_flight_dec(esurface->shell);
+}
+
+static void
+exposay_animate_in(struct exposay_surface *esurface)
+{
+    exposay_in_flight_inc(esurface->shell);
+
+    weston_move_scale_run(esurface->view,
+                          esurface->x - esurface->view->geometry.x,
+                          esurface->y - esurface->view->geometry.y,
+                  1.0, esurface->scale, 0,
+                          exposay_animate_in_done, esurface);
+}
+
+static void
+exposay_animate_out_done(struct weston_view_animation *animation, void *data)
+{
+    struct exposay_surface *esurface = data;
+    struct desktop_shell *shell = esurface->shell;
+
+    wl_list_remove(&esurface->link);
+    free(esurface);
+
+    exposay_in_flight_dec(shell);
+}
+
+static void
+exposay_animate_out(struct exposay_surface *esurface)
+{
+    exposay_in_flight_inc(esurface->shell);
+
+    /* Remove the static transformation set up by
+     * exposay_transform_in_done(). */
+    wl_list_remove(&esurface->transform.link);
+    weston_view_geometry_dirty(esurface->view);
+
+    weston_move_scale_run(esurface->view,
+                          esurface->x - esurface->view->geometry.x,
+                          esurface->y - esurface->view->geometry.y,
+                  1.0, esurface->scale, 1,
+                  exposay_animate_out_done, esurface);
+}
+
+static void
+exposay_highlight_surface(struct desktop_shell *shell,
+                          struct exposay_surface *esurface)
+{
+    struct weston_view *view = esurface->view;
+
+    shell->exposay.row_current = esurface->row;
+    shell->exposay.column_current = esurface->column;
+
+    activate(shell, view->surface, shell->exposay.seat);
+    shell->exposay.focus_current = view;
+}
+
+static int
+exposay_is_animating(struct desktop_shell *shell)
+{
+    if (shell->exposay.state_cur == EXPOSAY_LAYOUT_INACTIVE ||
+        shell->exposay.state_cur == EXPOSAY_LAYOUT_OVERVIEW)
+        return 0;
+
+    return (shell->exposay.in_flight > 0);
+}
+
+static void
+exposay_pick(struct desktop_shell *shell, int x, int y)
+{
+    struct exposay_surface *esurface;
+
+        if (exposay_is_animating(shell))
+            return;
+
+    wl_list_for_each(esurface, &shell->exposay.surface_list, link) {
+        if (x < esurface->x || x > esurface->x + esurface->width)
+            continue;
+        if (y < esurface->y || y > esurface->y + esurface->height)
+            continue;
+
+        exposay_highlight_surface(shell, esurface);
+        return;
+    }
+}
+
+/* Pretty lame layout for now; just tries to make a square.  Should take
+ * aspect ratio into account really.  Also needs to be notified of surface
+ * addition and removal and adjust layout/animate accordingly. */
+static enum exposay_layout_state
+exposay_layout(struct desktop_shell *shell)
+{
+    struct workspace *workspace = shell->exposay.workspace;
+    struct weston_compositor *compositor = shell->compositor;
+    struct weston_output *output = get_default_output(compositor);
+    struct weston_view *view;
+    struct exposay_surface *esurface, *highlight = NULL;
+    int w, h;
+    int i;
+    int last_row_removed = 0;
+
+    wl_list_init(&shell->exposay.surface_list);
+
+    shell->exposay.num_surfaces = 0;
+    wl_list_for_each(view, &workspace->layer.view_list, layer_link) {
+        if (!get_shell_surface(view->surface))
+            continue;
+        shell->exposay.num_surfaces++;
+    }
+
+    if (shell->exposay.num_surfaces == 0) {
+        shell->exposay.grid_size = 0;
+        shell->exposay.hpadding_outer = 0;
+        shell->exposay.vpadding_outer = 0;
+        shell->exposay.padding_inner = 0;
+        shell->exposay.surface_size = 0;
+        return EXPOSAY_LAYOUT_OVERVIEW;
+    }
+
+    /* Lay the grid out as square as possible, losing surfaces from the
+     * bottom row if required.  Start with fixed padding of a 10% margin
+     * around the outside and 80px internal padding between surfaces, and
+     * maximise the area made available to surfaces after this, but only
+     * to a maximum of 1/3rd the total output size.
+     *
+     * If we can't make a square grid, add one extra row at the bottom
+     * which will have a smaller number of columns.
+     *
+     * XXX: Surely there has to be a better way to express this maths,
+     *      right?!
+     */
+    shell->exposay.grid_size = floor(sqrtf(shell->exposay.num_surfaces));
+    if (pow(shell->exposay.grid_size, 2) != shell->exposay.num_surfaces)
+        shell->exposay.grid_size++;
+    last_row_removed = pow(shell->exposay.grid_size, 2) - shell->exposay.num_surfaces;
+
+    shell->exposay.hpadding_outer = (output->width / 10);
+    shell->exposay.vpadding_outer = (output->height / 10);
+    shell->exposay.padding_inner = 80;
+
+    w = output->width - (shell->exposay.hpadding_outer * 2);
+    w -= shell->exposay.padding_inner * (shell->exposay.grid_size - 1);
+    w /= shell->exposay.grid_size;
+
+    h = output->height - (shell->exposay.vpadding_outer * 2);
+    h -= shell->exposay.padding_inner * (shell->exposay.grid_size - 1);
+    h /= shell->exposay.grid_size;
+
+    shell->exposay.surface_size = (w < h) ? w : h;
+    if (shell->exposay.surface_size > (output->width / 2))
+        shell->exposay.surface_size = output->width / 2;
+    if (shell->exposay.surface_size > (output->height / 2))
+        shell->exposay.surface_size = output->height / 2;
+
+    i = 0;
+    wl_list_for_each(view, &workspace->layer.view_list, layer_link) {
+        int pad;
+
+        pad = shell->exposay.surface_size + shell->exposay.padding_inner;
+
+        if (!get_shell_surface(view->surface))
+            continue;
+
+        esurface = malloc(sizeof(*esurface));
+        if (!esurface) {
+            exposay_set_state(shell, EXPOSAY_TARGET_CANCEL,
+                              shell->exposay.seat);
+            break;
+        }
+
+        wl_list_insert(&shell->exposay.surface_list, &esurface->link);
+        esurface->shell = shell;
+        esurface->view = view;
+
+        esurface->row = i / shell->exposay.grid_size;
+        esurface->column = i % shell->exposay.grid_size;
+
+        esurface->x = shell->exposay.hpadding_outer;
+        esurface->x += pad * esurface->column;
+        esurface->y = shell->exposay.vpadding_outer;
+        esurface->y += pad * esurface->row;
+
+        if (esurface->row == shell->exposay.grid_size - 1)
+            esurface->x += (shell->exposay.surface_size + shell->exposay.padding_inner) * last_row_removed / 2;
+
+        if (view->surface->width > view->surface->height)
+            esurface->scale = shell->exposay.surface_size / (float) view->surface->width;
+        else
+            esurface->scale = shell->exposay.surface_size / (float) view->surface->height;
+        esurface->width = view->surface->width * esurface->scale;
+        esurface->height = view->surface->height * esurface->scale;
+
+        if (shell->exposay.focus_current == esurface->view)
+            highlight = esurface;
+
+        set_alpha_if_fullscreen(get_shell_surface(view->surface));
+
+        exposay_animate_in(esurface);
+
+        i++;
+    }
+
+    if (highlight)
+        exposay_highlight_surface(shell, highlight);
+
+    weston_compositor_schedule_repaint(shell->compositor);
+
+    return EXPOSAY_LAYOUT_ANIMATE_TO_OVERVIEW;
+}
+
+static void
+exposay_focus(struct weston_pointer_grab *grab)
+{
+}
+
+static void
+exposay_motion(struct weston_pointer_grab *grab, uint32_t time,
+           wl_fixed_t x, wl_fixed_t y)
+{
+    struct desktop_shell *shell =
+        container_of(grab, struct desktop_shell, exposay.grab_ptr);
+
+    weston_pointer_move(grab->pointer, x, y);
+
+    exposay_pick(shell,
+                 wl_fixed_to_int(grab->pointer->x),
+                 wl_fixed_to_int(grab->pointer->y));
+}
+
+static void
+exposay_button(struct weston_pointer_grab *grab, uint32_t time, uint32_t button,
+               uint32_t state_w)
+{
+    struct desktop_shell *shell =
+        container_of(grab, struct desktop_shell, exposay.grab_ptr);
+    struct weston_seat *seat = grab->pointer->seat;
+    enum wl_pointer_button_state state = state_w;
+
+    if (button != BTN_LEFT)
+        return;
+
+    /* Store the surface we clicked on, and don't do anything if we end up
+     * releasing on a different surface. */
+    if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
+        shell->exposay.clicked = shell->exposay.focus_current;
+        return;
+    }
+
+    if (shell->exposay.focus_current == shell->exposay.clicked)
+        exposay_set_state(shell, EXPOSAY_TARGET_SWITCH, seat);
+    else
+        shell->exposay.clicked = NULL;
+}
+
+static void
+exposay_pointer_grab_cancel(struct weston_pointer_grab *grab)
+{
+    struct desktop_shell *shell =
+        container_of(grab, struct desktop_shell, exposay.grab_ptr);
+
+    exposay_set_state(shell, EXPOSAY_TARGET_CANCEL, shell->exposay.seat);
+}
+
+static const struct weston_pointer_grab_interface exposay_ptr_grab = {
+    exposay_focus,
+    exposay_motion,
+    exposay_button,
+    exposay_pointer_grab_cancel,
+};
+
+static int
+exposay_maybe_move(struct desktop_shell *shell, int row, int column)
+{
+    struct exposay_surface *esurface;
+
+    wl_list_for_each(esurface, &shell->exposay.surface_list, link) {
+        if (esurface->row != row || esurface->column != column)
+            continue;
+
+        exposay_highlight_surface(shell, esurface);
+        return 1;
+    }
+
+    return 0;
+}
+
+static void
+exposay_key(struct weston_keyboard_grab *grab, uint32_t time, uint32_t key,
+            uint32_t state_w)
+{
+    struct weston_seat *seat = grab->keyboard->seat;
+    struct desktop_shell *shell =
+        container_of(grab, struct desktop_shell, exposay.grab_kbd);
+    enum wl_keyboard_key_state state = state_w;
+
+    if (state != WL_KEYBOARD_KEY_STATE_RELEASED)
+        return;
+
+    switch (key) {
+    case KEY_ESC:
+        exposay_set_state(shell, EXPOSAY_TARGET_CANCEL, seat);
+        break;
+    case KEY_ENTER:
+        exposay_set_state(shell, EXPOSAY_TARGET_SWITCH, seat);
+        break;
+    case KEY_UP:
+        exposay_maybe_move(shell, shell->exposay.row_current - 1,
+                           shell->exposay.column_current);
+        break;
+    case KEY_DOWN:
+        /* Special case for trying to move to the bottom row when it
+         * has fewer items than all the others. */
+        if (!exposay_maybe_move(shell, shell->exposay.row_current + 1,
+                                shell->exposay.column_current) &&
+            shell->exposay.row_current < (shell->exposay.grid_size - 1)) {
+            exposay_maybe_move(shell, shell->exposay.row_current + 1,
+                       (shell->exposay.num_surfaces %
+                        shell->exposay.grid_size) - 1);
+        }
+        break;
+    case KEY_LEFT:
+        exposay_maybe_move(shell, shell->exposay.row_current,
+                           shell->exposay.column_current - 1);
+        break;
+    case KEY_RIGHT:
+        exposay_maybe_move(shell, shell->exposay.row_current,
+                           shell->exposay.column_current + 1);
+        break;
+    case KEY_TAB:
+        /* Try to move right, then down (and to the leftmost column),
+         * then if all else fails, to the top left. */
+        if (!exposay_maybe_move(shell, shell->exposay.row_current,
+                    shell->exposay.column_current + 1) &&
+            !exposay_maybe_move(shell, shell->exposay.row_current + 1, 0))
+            exposay_maybe_move(shell, 0, 0);
+        break;
+    default:
+        break;
+    }
+}
+
+static void
+exposay_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 desktop_shell *shell =
+        container_of(grab, struct desktop_shell, exposay.grab_kbd);
+    struct weston_seat *seat = (struct weston_seat *) grab->keyboard->seat;
+
+    /* We want to know when mod has been pressed and released.
+     * FIXME: There is a problem here: if mod is pressed, then a key
+     * is pressed and released, then mod is released, we will treat that
+     * as if only mod had been pressed and released. */
+    if (seat->modifier_state) {
+        if (seat->modifier_state == shell->binding_modifier) {
+            shell->exposay.mod_pressed = true;
+        } else {
+            shell->exposay.mod_invalid = true;
+        }
+    } else {
+        if (shell->exposay.mod_pressed && !shell->exposay.mod_invalid)
+            exposay_set_state(shell, EXPOSAY_TARGET_CANCEL, seat);
+
+        shell->exposay.mod_invalid = false;
+        shell->exposay.mod_pressed = false;
+    }
+
+    return;
+}
+
+static void
+exposay_cancel(struct weston_keyboard_grab *grab)
+{
+    struct desktop_shell *shell =
+        container_of(grab, struct desktop_shell, exposay.grab_kbd);
+
+    exposay_set_state(shell, EXPOSAY_TARGET_CANCEL, shell->exposay.seat);
+}
+
+static const struct weston_keyboard_grab_interface exposay_kbd_grab = {
+    exposay_key,
+    exposay_modifier,
+    exposay_cancel,
+};
+
+/**
+ * Called when the transition from overview -> inactive has completed.
+ */
+static enum exposay_layout_state
+exposay_set_inactive(struct desktop_shell *shell)
+{
+    struct weston_seat *seat = shell->exposay.seat;
+
+    weston_keyboard_end_grab(seat->keyboard);
+    weston_pointer_end_grab(seat->pointer);
+    if (seat->keyboard->input_method_resource)
+        seat->keyboard->grab = &seat->keyboard->input_method_grab;
+
+    return EXPOSAY_LAYOUT_INACTIVE;
+}
+
+/**
+ * Begins the transition from overview to inactive. */
+static enum exposay_layout_state
+exposay_transition_inactive(struct desktop_shell *shell, int switch_focus)
+{
+    struct exposay_surface *esurface;
+
+    /* Call activate() before we start the animations to avoid
+     * animating back the old state and then immediately transitioning
+     * to the new. */
+    if (switch_focus && shell->exposay.focus_current)
+        activate(shell, shell->exposay.focus_current->surface,
+                 shell->exposay.seat);
+    else if (shell->exposay.focus_prev)
+        activate(shell, shell->exposay.focus_prev->surface,
+                 shell->exposay.seat);
+
+    wl_list_for_each(esurface, &shell->exposay.surface_list, link)
+        exposay_animate_out(esurface);
+    weston_compositor_schedule_repaint(shell->compositor);
+
+    return EXPOSAY_LAYOUT_ANIMATE_TO_INACTIVE;
+}
+
+static enum exposay_layout_state
+exposay_transition_active(struct desktop_shell *shell)
+{
+    struct weston_seat *seat = shell->exposay.seat;
+
+    shell->exposay.workspace = get_current_workspace(shell);
+    shell->exposay.focus_prev = get_default_view (seat->keyboard->focus);
+    shell->exposay.focus_current = get_default_view (seat->keyboard->focus);
+    shell->exposay.clicked = NULL;
+    wl_list_init(&shell->exposay.surface_list);
+
+    lower_fullscreen_layer(shell);
+    shell->exposay.grab_kbd.interface = &exposay_kbd_grab;
+    weston_keyboard_start_grab(seat->keyboard,
+                               &shell->exposay.grab_kbd);
+    weston_keyboard_set_focus(seat->keyboard, NULL);
+
+    shell->exposay.grab_ptr.interface = &exposay_ptr_grab;
+    weston_pointer_start_grab(seat->pointer,
+                              &shell->exposay.grab_ptr);
+    weston_pointer_set_focus(seat->pointer, NULL,
+                     seat->pointer->x, seat->pointer->y);
+
+    return exposay_layout(shell);
+}
+
+static void
+exposay_check_state(struct desktop_shell *shell)
+{
+    enum exposay_layout_state state_new = shell->exposay.state_cur;
+    int do_switch = 0;
+
+    /* Don't do anything whilst animations are running, just store up
+     * target state changes and only act on them when the animations have
+     * completed. */
+    if (exposay_is_animating(shell))
+        return;
+
+    switch (shell->exposay.state_target) {
+    case EXPOSAY_TARGET_OVERVIEW:
+        switch (shell->exposay.state_cur) {
+        case EXPOSAY_LAYOUT_OVERVIEW:
+            goto out;
+        case EXPOSAY_LAYOUT_ANIMATE_TO_OVERVIEW:
+            state_new = EXPOSAY_LAYOUT_OVERVIEW;
+            break;
+        default:
+            state_new = exposay_transition_active(shell);
+            break;
+        }
+        break;
+
+    case EXPOSAY_TARGET_SWITCH:
+        do_switch = 1; /* fallthrough */
+    case EXPOSAY_TARGET_CANCEL:
+        switch (shell->exposay.state_cur) {
+        case EXPOSAY_LAYOUT_INACTIVE:
+            goto out;
+        case EXPOSAY_LAYOUT_ANIMATE_TO_INACTIVE:
+            state_new = exposay_set_inactive(shell);
+            break;
+        default:
+            state_new = exposay_transition_inactive(shell, do_switch);
+            break;
+        }
+
+        break;
+    }
+
+out:
+    shell->exposay.state_cur = state_new;
+}
+
+static void
+exposay_set_state(struct desktop_shell *shell, enum exposay_target_state state,
+                  struct weston_seat *seat)
+{
+    shell->exposay.state_target = state;
+    shell->exposay.seat = seat;
+    exposay_check_state(shell);
+}
+
+void
+exposay_binding(struct weston_seat *seat, enum weston_keyboard_modifier modifier,
+        void *data)
+{
+    struct desktop_shell *shell = data;
+
+    exposay_set_state(shell, EXPOSAY_TARGET_OVERVIEW, seat);
+}
diff --git a/src/ico_input-panel.c b/src/ico_input-panel.c
new file mode 100644 (file)
index 0000000..e58bcac
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+ * Copyright © 2010-2012 Intel Corporation
+ * Copyright © 2011-2012 Collabora, Ltd.
+ * Copyright © 2013 Raspberry Pi Foundation
+ * Copyright © 2013-2014 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ico_ivi_shell.h"
+#include "ico_ivi_shell_private.h"
+#include "desktop-shell-server-protocol.h"
+#include "input-method-server-protocol.h"
+
+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 weston_view *view;
+    struct wl_listener surface_destroy_listener;
+
+    struct weston_output *output;
+    uint32_t panel;
+};
+
+extern int  ico_debug_level;
+
+/* debug log macros         */
+#define uifw_debug(fmt,...)  \
+    { if (ico_debug_level >= 5) {weston_log("DBG>"fmt" (%s:%d)\n",##__VA_ARGS__,__FILE__,__LINE__);} }
+#define uifw_trace(fmt,...)  \
+    { if (ico_debug_level >= 4) {weston_log("TRC>"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__);} }
+
+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 *ipsurf, *next;
+
+    shell->text_input.surface = (struct weston_surface*)data;
+
+    uifw_trace("show_input_panels: Enter(surface=%08x[%d])",
+               (int)data, shell->showing_input_panels);
+
+    if (shell->showing_input_panels)    {
+        uifw_trace("show_input_panels: Leave(already)");
+        return;
+    }
+    shell->showing_input_panels = true;
+
+    /* if ico_window_mgr hook, call hook routine    */
+    if (shell_hook_show_layer)  {
+        (*shell_hook_show_layer)(LAYER_TYPE_INPUTPANEL, 1, data);
+        return;
+    }
+
+    if (!shell->locked)
+        wl_list_insert(&shell->panel_layer.link,
+                   &shell->input_panel_layer.link);
+    wl_list_for_each_safe(ipsurf, next,
+                  &shell->input_panel.surfaces, link) {
+        if (ipsurf->surface->width == 0)
+            continue;
+        uifw_debug("show_input_panels: insert view=%08x surf=%08x",
+                   (int)ipsurf->view, (int)ipsurf->surface);
+        wl_list_remove(&ipsurf->view->layer_link);
+        wl_list_init(&ipsurf->view->layer_link);
+        wl_list_insert(&shell->input_panel_layer.view_list,
+                   &ipsurf->view->layer_link);
+        weston_view_geometry_dirty(ipsurf->view);
+        weston_view_update_transform(ipsurf->view);
+        weston_surface_damage(ipsurf->surface);
+        weston_slide_run(ipsurf->view, ipsurf->surface->height * 0.9,
+                 0, NULL, NULL);
+    }
+    uifw_trace("show_input_panels: Leave");
+}
+
+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_view *view, *next;
+
+    uifw_trace("hide_input_panels: Enter(surface=%08x[%d])",
+               (int)data, shell->showing_input_panels);
+
+    if (!shell->showing_input_panels)   {
+        uifw_trace("hide_input_panels: Leave(not show)");
+        return;
+    }
+    shell->showing_input_panels = false;
+
+    /* if ico_window_mgr hook, call hook routine    */
+    if (shell_hook_show_layer)  {
+        (*shell_hook_show_layer)(LAYER_TYPE_INPUTPANEL, 0, NULL);
+        return;
+    }
+
+    if (!shell->locked)
+        wl_list_remove(&shell->input_panel_layer.link);
+
+    wl_list_for_each_safe(view, next,
+                  &shell->input_panel_layer.view_list, layer_link)
+        weston_view_unmap(view);
+    uifw_trace("hide_input_panels: Leave");
+}
+
+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
+input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
+{
+    struct input_panel_surface *ip_surface = surface->configure_private;
+    struct desktop_shell *shell = ip_surface->shell;
+    struct weston_view *view;
+    float x, y;
+
+    uifw_trace("input_panel_configure: Enter(surface=%08x x/y=%d/%d w/h=%d/%d)",
+               (int)surface, sx, sy, surface->width, surface->height);
+
+    if (surface->width == 0)    {
+        uifw_trace("input_panel_configure: Leave(width==0)");
+        return;
+    }
+    if (ip_surface->panel) {
+        view = get_default_view(shell->text_input.surface);
+        if (view == NULL)   {
+            uifw_trace("input_panel_configure: Leave(no view)");
+            return;
+        }
+        x = view->geometry.x + shell->text_input.cursor_rectangle.x2;
+        y = view->geometry.y + shell->text_input.cursor_rectangle.y2;
+    } else {
+        x = ip_surface->output->x + (ip_surface->output->width - surface->width) / 2;
+        y = ip_surface->output->y + ip_surface->output->height - surface->height;
+        if (! shell_hook_map)  {
+            y -= 132.0f;
+        }
+    }
+
+    weston_view_set_position(ip_surface->view, x, y);
+
+    if (!weston_surface_is_mapped(surface) && shell->showing_input_panels) {
+        wl_list_insert(&shell->input_panel_layer.view_list,
+                   &ip_surface->view->layer_link);
+        weston_view_update_transform(ip_surface->view);
+        weston_surface_damage(surface);
+        weston_slide_run(ip_surface->view, ip_surface->view->surface->height * 0.9, 0, NULL, NULL);
+    }
+
+    if (shell_hook_map)  {
+        int     wx, wy;
+        int     ww, wh;
+        wx = (int)x;
+        wy = (int)y;
+        ww = ip_surface->output->width;
+        wh = ip_surface->output->height;
+        (*shell_hook_map)(surface, &ww, &wh, &wx, &wy);
+    }
+    if (shell_hook_configure)  {
+        (*shell_hook_configure)(surface);
+    }
+    uifw_trace("input_panel_configure: Leave");
+}
+
+static void
+destroy_input_panel_surface(struct input_panel_surface *input_panel_surface)
+{
+    wl_signal_emit(&input_panel_surface->destroy_signal, input_panel_surface);
+
+    wl_list_remove(&input_panel_surface->surface_destroy_listener.link);
+    wl_list_remove(&input_panel_surface->link);
+
+    uifw_trace("destroy_input_panel_surface: Enter(surface=%08x)",
+               (int)input_panel_surface->surface);
+
+    input_panel_surface->surface->configure = NULL;
+    weston_view_destroy(input_panel_surface->view);
+
+    free(input_panel_surface);
+    uifw_trace("destroy_input_panel_surface: Leave");
+}
+
+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;
+    }
+}
+
+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);
+    }
+}
+
+static struct input_panel_surface *
+create_input_panel_surface(struct desktop_shell *shell,
+               struct weston_surface *surface)
+{
+    struct input_panel_surface *input_panel_surface;
+
+    input_panel_surface = calloc(1, sizeof *input_panel_surface);
+    if (!input_panel_surface)
+        return NULL;
+
+    uifw_trace("create_input_panel_surface: Enter(surface=%08x)", (int)surface);
+
+    surface->configure = input_panel_configure;
+    surface->configure_private = input_panel_surface;
+
+    input_panel_surface->shell = shell;
+
+    input_panel_surface->surface = surface;
+    input_panel_surface->view = weston_view_create(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);
+
+    uifw_trace("create_input_panel_surface: Leave(ipsurf=%08x)", (int)input_panel_surface);
+
+    return input_panel_surface;
+}
+
+static void
+input_panel_surface_set_toplevel(struct wl_client *client,
+                 struct wl_resource *resource,
+                 struct wl_resource *output_resource,
+                 uint32_t position)
+{
+    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);
+
+    input_panel_surface->output = wl_resource_get_user_data(output_resource);
+    input_panel_surface->panel = 0;
+}
+
+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;
+
+    wl_list_insert(&shell->input_panel.surfaces,
+               &input_panel_surface->link);
+
+    input_panel_surface->panel = 1;
+}
+
+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
+destroy_input_panel_surface_resource(struct wl_resource *resource)
+{
+    struct input_panel_surface *ipsurf =
+        wl_resource_get_user_data(resource);
+
+    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;
+
+    uifw_trace("input_panel_get_input_panel_surface: Enter");
+
+    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;
+    }
+
+    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);
+
+    /* if ico_window_mgr hook, call hook routine    */
+    if (shell_hook_create)  {
+        (*shell_hook_create)(LAYER_TYPE_INPUTPANEL,
+                             surface, client, (struct shell_surface *)ipsurf);
+    }
+    uifw_trace("input_panel_get_input_panel_surface: Leave");
+}
+
+static const struct wl_input_panel_interface input_panel_implementation = {
+    input_panel_get_input_panel_surface
+};
+
+static void
+unbind_input_panel(struct wl_resource *resource)
+{
+    struct desktop_shell *shell = wl_resource_get_user_data(resource);
+
+    shell->input_panel.binding = NULL;
+}
+
+static void
+bind_input_panel(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_input_panel_interface, 1, 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;
+    }
+
+    wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
+                   "interface object already bound");
+    wl_resource_destroy(resource);
+}
+
+void
+input_panel_destroy(struct desktop_shell *shell)
+{
+    wl_list_remove(&shell->show_input_panel_listener.link);
+    wl_list_remove(&shell->hide_input_panel_listener.link);
+}
+
+int
+input_panel_setup(struct desktop_shell *shell)
+{
+    struct weston_compositor *ec = shell->compositor;
+
+    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);
+
+    wl_list_init(&shell->input_panel.surfaces);
+
+    if (wl_global_create(shell->compositor->wl_display,
+                 &wl_input_panel_interface, 1,
+                 shell, bind_input_panel) == NULL)
+        return -1;
+
+    return 0;
+}
+
+WL_EXPORT   struct weston_view  *
+ico_input_panel_get_view(void *ipsurf)
+{
+    return ((struct input_panel_surface *)ipsurf)->view;
+}
index 7e1699e..17b0fab 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2013 TOYOTA MOTOR CORPORATION.
+ * Copyright © 2013-2014 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
@@ -127,7 +127,7 @@ struct uifw_input_device    {
     int         pend_y;                     /* pending Y coordinate                 */
     uint16_t    node;                       /* display number                       */
     uint16_t    pending;                    /* pending flag                         */
-    struct weston_surface *grab;            /* current grab surface                 */
+    struct weston_view *grab;               /* current grab surface view            */
 };
 
 /* Input Region Table           */
@@ -494,7 +494,7 @@ ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
     wl_fixed_t  fix_x;                      /* wayland X coordinate         */
     wl_fixed_t  fix_y;                      /* wayland Y coordinate         */
     wl_fixed_t  dx, dy;                     /* relative coordinate (dummy)  */
-    struct weston_surface   *grabsave;      /* real grab surface            */
+    struct weston_view  *grabsave;          /* real grab surface view       */
     int         keyboard_active;            /* keyborad active surface flag */
 
 #if 0           /* too many log */
@@ -691,10 +691,10 @@ ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
         case EVENT_MOTION:
             if ((type == ICO_INPUT_MGR_DEVICE_TYPE_TOUCH) &&
                 (pInputMgr->seat->touch))   {
-                if (pInputMgr->seat->num_tp > 10)   {
+                if (pInputMgr->seat->touch->num_tp > 10)   {
                     uifw_debug("ico_mgr_send_input_event: num=%d reset",
-                               pInputMgr->seat->num_tp);
-                    pInputMgr->seat->num_tp = 0;        /* safty gard   */
+                               pInputMgr->seat->touch->num_tp);
+                    pInputMgr->seat->touch->num_tp = 0;     /* safty gard   */
                 }
                 grabsave = pInputMgr->seat->touch->focus;
                 uifw_debug("ico_mgr_send_input_event: MOTION(%d/%d) grab %08x org %08x",
@@ -719,10 +719,10 @@ ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
             uifw_trace("ico_mgr_send_input_event: notify_button(%d,%d)", code, value);
             if (pInputMgr->seat->pointer)   {
                 if (value)  {
-                    dev->grab = weston_compositor_pick_surface(
+                    dev->grab = weston_compositor_pick_view(
                                     pInputMgr->compositor, fix_x, fix_y, &dx, &dy);
                     weston_pointer_set_focus(pInputMgr->seat->pointer, dev->grab, dx, dy);
-                    ico_window_mgr_active_surface(dev->grab);
+                    ico_window_mgr_active_surface(dev->grab->surface);
                 }
                 else    {
                     dev->grab = NULL;
@@ -741,16 +741,16 @@ ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
                 dev->grab = NULL;
                 if (grabsave)   {
                     weston_touch_set_focus(pInputMgr->seat, NULL);
-                    if (pInputMgr->seat->num_tp > 0)   {
+                    if (pInputMgr->seat->touch->num_tp > 0) {
                         uifw_debug("ico_mgr_send_input_event: num=%d reset for reset focuse",
-                                   pInputMgr->seat->num_tp);
-                        pInputMgr->seat->num_tp = 0;
+                                   pInputMgr->seat->touch->num_tp);
+                        pInputMgr->seat->touch->num_tp = 0;
                     }
                 }
             }
             else if (value == ICO_INPUT_MGR_CONTROL_TOUCH_EVENT_DOWN)   {
                 grabsave = pInputMgr->seat->touch->focus;
-                dev->grab = weston_compositor_pick_surface(
+                dev->grab = weston_compositor_pick_view(
                                 pInputMgr->compositor, fix_x, fix_y, &dx, &dy);
                 uifw_trace("ico_mgr_send_input_event: notify_touch(DOWN=%d/%d) "
                            "grab=%08x org=%08x", fix_x/256, fix_y/256,
@@ -758,13 +758,13 @@ ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
                 if (grabsave != dev->grab)  {
                     weston_touch_set_focus(pInputMgr->seat, dev->grab);
                 }
-                if (pInputMgr->seat->num_tp > 0)    {
+                if (pInputMgr->seat->touch->num_tp > 0)    {
                     uifw_debug("ico_mgr_send_input_event: touch_down illegal num, modify");
                     weston_touch_set_focus(pInputMgr->seat, NULL);
-                    pInputMgr->seat->num_tp = 0;
+                    pInputMgr->seat->touch->num_tp = 0;
                 }
                 notify_touch(pInputMgr->seat, ctime, 0, fix_x, fix_y, WL_TOUCH_DOWN);
-                ico_window_mgr_active_surface(dev->grab);
+                ico_window_mgr_active_surface(dev->grab->surface);
             }
             else    {
                 grabsave = pInputMgr->seat->touch->focus;
@@ -773,10 +773,11 @@ ico_mgr_send_input_event(struct wl_client *client, struct wl_resource *resource,
                 if ((grabsave != dev->grab) && (dev->grab != NULL)) {
                     weston_touch_set_focus(pInputMgr->seat, dev->grab);
                 }
-                if ((pInputMgr->seat->num_tp == 0) || (pInputMgr->seat->num_tp > 10))   {
+                if ((pInputMgr->seat->touch->num_tp == 0) ||
+                    (pInputMgr->seat->touch->num_tp > 10))  {
                     uifw_debug("ico_mgr_send_input_event: num=%d reset",
-                               pInputMgr->seat->num_tp);
-                    pInputMgr->seat->num_tp = 1;
+                               pInputMgr->seat->touch->num_tp);
+                    pInputMgr->seat->touch->num_tp = 1;
                 }
                 notify_touch(pInputMgr->seat, ctime, 0, 0, 0, WL_TOUCH_UP);
                 if (grabsave == dev->grab)  grabsave = NULL;
index 8b4d9bd..095128f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2013 TOYOTA MOTOR CORPORATION.
+ * Copyright © 2013-2014 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
index 5efd161..bf95e02 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2013 TOYOTA MOTOR CORPORATION.
+ * Copyright © 2013-2014 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
index fbdd901..e794554 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Copyright © 2010-2012 Intel Corporation
  * Copyright © 2011-2012 Collabora, Ltd.
- * Copyright © 2013 TOYOTA MOTOR CORPORATION.
+ * Copyright © 2013 Raspberry Pi Foundation
+ * Copyright © 2013-2014 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
@@ -24,7 +25,6 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <stdbool.h>
 #include <string.h>
 #include <unistd.h>
 #include <linux/input.h>
 #include <math.h>
 #include <sys/types.h>
 
-#include <wayland-server.h>
-#include <weston/compositor.h>
+#include "ico_ivi_shell.h"
+#include "ico_ivi_shell_private.h"
 #include "desktop-shell-server-protocol.h"
-#include "input-method-server-protocol.h"
 #include "workspaces-server-protocol.h"
 #include <weston/config-parser.h>
-#include "ico_ivi_shell_private.h"
+#include "xdg-shell-server-protocol.h"
 
+#ifndef WESTON_SHELL_CLIENT
+#define WESTON_SHELL_CLIENT "weston-desktop-shell"
+#endif
 #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
-};
+#ifndef static_assert
+#define static_assert(cond, msg)
+#endif
 
 struct focus_state {
     struct weston_seat *seat;
@@ -65,115 +59,17 @@ struct focus_state {
     struct wl_listener surface_destroy_listener;
 };
 
-struct workspace {
-    struct weston_layer layer;
-
-    struct wl_list focus_list;
-    struct wl_listener seat_destroyed_listener;
-};
-
-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 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;
-    enum animation_type startup_animation_type;
+struct shell_output {
+    struct desktop_shell  *shell;
+    struct weston_output  *output;
+    struct wl_listener    destroy_listener;
+    struct wl_list        link;
 };
 
-#if 0           /* move to ico_ivi_shell.h  */
+#if 0           /* move to ico_ivi_shell_private.h  */
 enum shell_surface_type {
     SHELL_SURFACE_NONE,
     SHELL_SURFACE_TOPLEVEL,
-    SHELL_SURFACE_TRANSIENT,
-    SHELL_SURFACE_FULLSCREEN,
-    SHELL_SURFACE_MAXIMIZED,
     SHELL_SURFACE_POPUP,
     SHELL_SURFACE_XWAYLAND
 };
@@ -184,22 +80,66 @@ struct ping_timer {
     uint32_t serial;
 };
 
+/*
+ * Surface stacking and ordering.
+ *
+ * This is handled using several linked lists of surfaces, organised into
+ * ‘layers’. The layers are ordered, and each of the surfaces in one layer are
+ * above all of the surfaces in the layer below. The set of layers is static and
+ * in the following order (top-most first):
+ *  • Lock layer (only ever displayed on its own)
+ *  • Cursor layer
+ *  • Fullscreen layer
+ *  • Panel layer
+ *  • Input panel layer
+ *  • Workspace layers
+ *  • Background layer
+ *
+ * The list of layers may be manipulated to remove whole layers of surfaces from
+ * display. For example, when locking the screen, all layers except the lock
+ * layer are removed.
+ *
+ * A surface’s layer is modified on configuring the surface, in
+ * set_surface_type() (which is only called when the surface’s type change is
+ * _committed_). If a surface’s type changes (e.g. when making a window
+ * fullscreen) its layer changes too.
+ *
+ * In order to allow popup and transient surfaces to be correctly stacked above
+ * their parent surfaces, each surface tracks both its parent surface, and a
+ * linked list of its children. When a surface’s layer is updated, so are the
+ * layers of its children. Note that child surfaces are *not* the same as
+ * subsurfaces — child/parent surfaces are purely for maintaining stacking
+ * order.
+ *
+ * The children_link list of siblings of a surface (i.e. those surfaces which
+ * have the same parent) only contains weston_surfaces which have a
+ * shell_surface. Stacking is not implemented for non-shell_surface
+ * weston_surfaces. This means that the following implication does *not* hold:
+ *     (shsurf->parent != NULL) ⇒ !wl_list_is_empty(shsurf->children_link)
+ */
+
 struct shell_surface {
     struct wl_resource *resource;
     struct wl_signal destroy_signal;
 
     struct weston_surface *surface;
+    struct weston_view *view;
+    int32_t last_width, last_height;
     struct wl_listener surface_destroy_listener;
     struct weston_surface *parent;
+    struct wl_list children_list;  /* child surfaces of this one */
+    struct wl_list children_link;  /* sibling surfaces of this one */
     struct desktop_shell *shell;
 
-    enum shell_surface_type type, next_type;
+    enum shell_surface_type type;
     char *title, *class;
     int32_t saved_x, saved_y;
+    int32_t saved_width, saved_height;
     bool saved_position_valid;
+    bool saved_size_valid;
     bool saved_rotation_valid;
-    char layertype;                 /* surface layer type   */
-    int unresponsive;
+    char layertype;                 /* surface layer type for ico_window_mgr    */
+    int unresponsive, grabbed;
 
     struct {
         struct weston_transform transform;
@@ -222,7 +162,7 @@ struct shell_surface {
         enum wl_shell_surface_fullscreen_method type;
         struct weston_transform transform; /* matrix from x, y */
         uint32_t framerate;
-        struct weston_surface *black_surface;
+        struct weston_view *black_view;
     } fullscreen;
 
     struct ping_timer *ping_timer;
@@ -231,9 +171,17 @@ struct shell_surface {
 
     struct weston_output *fullscreen_output;
     struct weston_output *output;
+    struct weston_output *recommended_output;
     struct wl_list link;
 
     const struct weston_shell_client *client;
+
+    struct {
+        bool maximized;
+        bool fullscreen;
+        bool relative;
+    } state, next_state; /* surface states */
+    bool state_changed;
 };
 
 struct shell_grab {
@@ -256,6 +204,7 @@ struct weston_move_grab {
 
 struct weston_touch_move_grab {
     struct shell_touch_grab base;
+    int active;
     wl_fixed_t dx, dy;
 };
 
@@ -280,15 +229,12 @@ struct shell_seat {
     } 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);
+void
+set_alpha_if_fullscreen(struct shell_surface *shsurf)
+{
+    if (shsurf && shsurf->state.fullscreen)
+        shsurf->fullscreen.black_view->alpha = 0.25;
+}
 
 static struct desktop_shell *
 shell_surface_get_shell(struct shell_surface *shsurf);
@@ -299,13 +245,31 @@ surface_rotate(struct shell_surface *surface, struct weston_seat *seat);
 static void
 shell_fade_startup(struct desktop_shell *shell);
 
+static struct shell_seat *
+get_shell_seat(struct weston_seat *seat);
+
+static void
+shell_surface_update_child_surface_layers(struct shell_surface *shsurf);
+
+static bool
+shell_surface_is_wl_shell_surface(struct shell_surface *shsurf);
+
+static bool
+shell_surface_is_xdg_surface(struct shell_surface *shsurf);
+
+static bool
+shell_surface_is_xdg_popup(struct shell_surface *shsurf);
+
+static void
+shell_surface_set_parent(struct shell_surface *shsurf,
+                         struct weston_surface *parent);
+
 /* shell management table           */
 static struct desktop_shell *_ico_ivi_shell = NULL;
 
 /* shell program path for ico-ivi   */
-static char *shell_exe = NULL;
 #define DEFAULT_DEBUG_LEVEL 4
-static int  ico_debug_level = DEFAULT_DEBUG_LEVEL;  /* Debug Level                  */
+int  ico_debug_level = DEFAULT_DEBUG_LEVEL;  /* Debug Level                  */
 
 /* default display                  */
 static struct weston_output *default_inputpanel = NULL;
@@ -323,42 +287,41 @@ static struct weston_output *default_inputpanel = NULL;
     { 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)(int layertype,
-                                 struct wl_client *client, struct wl_resource *resource,
-                                 struct weston_surface *surface,
-                                 struct shell_surface *shsurf) = NULL;
-static void (*shell_hook_destroy)(struct weston_surface *surface) = NULL;
-static void (*shell_hook_map)(struct weston_surface *surface, int32_t *width,
-                              int32_t *height, int32_t *sx, int32_t *sy) = NULL;
-static void (*shell_hook_configure)(struct weston_surface *surface) = NULL;
-static void (*shell_hook_select)(struct weston_surface *surface) = NULL;
-static char *(*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;
-static void (*shell_hook_show_layer)(int layertype, int show, void *data) = NULL;
-static int (*shell_hook_fullscreen)(int event, struct weston_surface *surface) = NULL;
+WL_EXPORT void (*shell_hook_bind)(struct wl_client *client, void *shell) = NULL;
+WL_EXPORT void (*shell_hook_unbind)(struct wl_client *client) = NULL;
+WL_EXPORT void (*shell_hook_create)(int layertype, struct weston_surface *surface,
+                                    struct wl_client *client,
+                                    struct shell_surface *shsurf) = NULL;
+WL_EXPORT void (*shell_hook_destroy)(struct weston_surface *surface) = NULL;
+WL_EXPORT void (*shell_hook_map)(struct weston_surface *surface, int32_t *width,
+                                 int32_t *height, int32_t *sx, int32_t *sy) = NULL;
+WL_EXPORT void (*shell_hook_configure)(struct weston_surface *surface) = NULL;
+WL_EXPORT void (*shell_hook_select)(struct weston_surface *surface) = NULL;
+WL_EXPORT char *(*shell_hook_title)(struct weston_surface *surface,
+                                    const char *title) = NULL;
+WL_EXPORT void (*shell_hook_move)(struct weston_surface *surface, int *dx, int *dy) = NULL;
+WL_EXPORT void (*shell_hook_show_layer)(int layertype, int show, void *data) = NULL;
+WL_EXPORT int (*shell_hook_fullscreen)(int event, struct weston_surface *surface) = NULL;
 
 static bool
 shell_surface_is_top_fullscreen(struct shell_surface *shsurf)
 {
+    struct desktop_shell *shell;
+    struct weston_view *top_fs_ev;
+
     if (shell_hook_fullscreen)  {
         return (*shell_hook_fullscreen)(SHELL_FULLSCREEN_ISTOP, shsurf->surface);
     }
 
-    struct desktop_shell *shell;
-    struct weston_surface *top_fs_es;
-
     shell = shell_surface_get_shell(shsurf);
 
-    uifw_debug("shell_surface_is_top_fullscreen: ");
-    if (wl_list_empty(&shell->fullscreen_layer.surface_list))
+    if (wl_list_empty(&shell->fullscreen_layer.view_list))
         return false;
 
-    top_fs_es = container_of(shell->fullscreen_layer.surface_list.next,
-                     struct weston_surface,
+    top_fs_ev = container_of(shell->fullscreen_layer.view_list.next,
+                     struct weston_view,
                  layer_link);
-    return (shsurf == get_shell_surface(top_fs_es));
+    return (shsurf == get_shell_surface(top_fs_ev->surface));
 }
 
 static void
@@ -372,6 +335,26 @@ destroy_shell_grab_shsurf(struct wl_listener *listener, void *data)
     grab->shsurf = NULL;
 }
 
+struct weston_view *
+get_default_view(struct weston_surface *surface)
+{
+    struct shell_surface *shsurf;
+    struct weston_view *view;
+
+    if (!surface || wl_list_empty(&surface->views))
+        return NULL;
+
+    shsurf = get_shell_surface(surface);
+    if (shsurf)
+        return shsurf->view;
+
+    wl_list_for_each(view, &surface->views, surface_link)
+        if (weston_view_is_mapped(view))
+            return view;
+
+    return container_of(surface->views.next, struct weston_view, surface_link);
+}
+
 static void
 popup_grab_end(struct weston_pointer *pointer);
 
@@ -397,11 +380,13 @@ shell_grab_start(struct shell_grab *grab,
     wl_signal_add(&shsurf->destroy_signal,
               &grab->shsurf_destroy_listener);
 
+    shsurf->grabbed = 1;
     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,
+        weston_pointer_set_focus(pointer,
+                     get_default_view(shell->grab_surface),
                      wl_fixed_from_int(0),
                      wl_fixed_from_int(0));
     }
@@ -410,8 +395,10 @@ shell_grab_start(struct shell_grab *grab,
 static void
 shell_grab_end(struct shell_grab *grab)
 {
-    if (grab->shsurf)
+    if (grab->shsurf) {
         wl_list_remove(&grab->shsurf_destroy_listener.link);
+        grab->shsurf->grabbed = 0;
+    }
 
     weston_pointer_end_grab(grab->grab.pointer);
 }
@@ -431,23 +418,27 @@ shell_touch_grab_start(struct shell_touch_grab *grab,
               &grab->shsurf_destroy_listener);
 
     grab->touch = touch;
+    shsurf->grabbed = 1;
 
     weston_touch_start_grab(touch, &grab->grab);
     if (shell->child.desktop_shell)
-        weston_touch_set_focus(touch->seat, shell->grab_surface);
+        weston_touch_set_focus(touch->seat,
+                       get_default_view(shell->grab_surface));
 }
 
 static void
 shell_touch_grab_end(struct shell_touch_grab *grab)
 {
-    if (grab->shsurf)
+    if (grab->shsurf) {
         wl_list_remove(&grab->shsurf_destroy_listener.link);
+        grab->shsurf->grabbed = 0;
+    }
 
     weston_touch_end_grab(grab->touch);
 }
 
 static void
-center_on_output(struct weston_surface *surface,
+center_on_output(struct weston_view *view,
          struct weston_output *output);
 
 static enum weston_keyboard_modifier
@@ -469,10 +460,15 @@ get_modifier(char *modifier)
 static enum animation_type
 get_animation_type(char *animation)
 {
+    if (!animation)
+        return ANIMATION_NONE;
+
     if (!strcmp("zoom", animation))
         return ANIMATION_ZOOM;
     else if (!strcmp("fade", animation))
         return ANIMATION_FADE;
+    else if (!strcmp("dim-layer", animation))
+        return ANIMATION_DIM_LAYER;
     else
         return ANIMATION_NONE;
 }
@@ -494,9 +490,21 @@ shell_configuration(struct desktop_shell *shell)
     section = weston_config_get_section(shell->compositor->config,
                         "shell", NULL, NULL);
     weston_config_section_get_string(section,
+                     "client", &s, LIBEXECDIR "/" WESTON_SHELL_CLIENT);
+    shell->client = s;
+    weston_config_section_get_string(section,
                      "binding-modifier", &s, "super");
     shell->binding_modifier = get_modifier(s);
     free(s);
+
+    weston_config_section_get_string(section,
+                     "exposay-modifier", &s, "none");
+    if (strcmp(s, "none") == 0)
+        shell->exposay_modifier = 0;
+    else
+        shell->exposay_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);
@@ -506,14 +514,15 @@ shell_configuration(struct desktop_shell *shell)
     free(s);
     if (shell->startup_animation_type == ANIMATION_ZOOM)
         shell->startup_animation_type = ANIMATION_NONE;
-
+    weston_config_section_get_string(section, "focus-animation", &s, "none");
+    shell->focus_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);
+
+    weston_log("workspaces=%d manager client=<%s>\n", shell->workspaces.num,
+               shell->client ? shell->client : "NULL");
 
     /* get debug level for ivi debug    */
     section = weston_config_get_section(shell->compositor->config, "ivi-option", NULL, NULL);
@@ -524,6 +533,104 @@ shell_configuration(struct desktop_shell *shell)
     }
 }
 
+struct weston_output *
+get_default_output(struct weston_compositor *compositor)
+{
+    /* support multi display, default fullscreen output display */
+    if (default_inputpanel) {
+        return default_inputpanel;
+    }
+    return container_of(compositor->output_list.next,
+                struct weston_output, link);
+}
+
+
+/* no-op func for checking focus surface */
+static void
+focus_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
+{
+}
+
+static struct focus_surface *
+get_focus_surface(struct weston_surface *surface)
+{
+    if (surface->configure == focus_surface_configure)
+        return surface->configure_private;
+    else
+        return NULL;
+}
+
+static bool
+is_focus_surface (struct weston_surface *es)
+{
+    return (es->configure == focus_surface_configure);
+}
+
+static bool
+is_focus_view (struct weston_view *view)
+{
+    return is_focus_surface (view->surface);
+}
+
+static struct focus_surface *
+create_focus_surface(struct weston_compositor *ec,
+             struct weston_output *output)
+{
+    struct focus_surface *fsurf = NULL;
+    struct weston_surface *surface = NULL;
+
+    fsurf = malloc(sizeof *fsurf);
+    if (!fsurf)
+        return NULL;
+
+    fsurf->surface = weston_surface_create(ec);
+    surface = fsurf->surface;
+    if (surface == NULL) {
+        free(fsurf);
+        return NULL;
+    }
+
+    surface->configure = focus_surface_configure;
+    surface->output = output;
+    surface->configure_private = fsurf;
+
+    fsurf->view = weston_view_create(surface);
+    if (fsurf->view == NULL) {
+        weston_surface_destroy(surface);
+        free(fsurf);
+        return NULL;
+    }
+    fsurf->view->output = output;
+
+    weston_surface_set_size(surface, output->width, output->height);
+    weston_view_set_position(fsurf->view, output->x, output->y);
+    weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
+    pixman_region32_fini(&surface->opaque);
+    pixman_region32_init_rect(&surface->opaque, output->x, output->y,
+                  output->width, output->height);
+    pixman_region32_fini(&surface->input);
+    pixman_region32_init(&surface->input);
+
+    wl_list_init(&fsurf->workspace_transform.link);
+
+    return fsurf;
+}
+
+static void
+focus_surface_destroy(struct focus_surface *fsurf)
+{
+    weston_surface_destroy(fsurf->surface);
+    free(fsurf);
+}
+
+static void
+focus_animation_done(struct weston_view_animation *animation, void *data)
+{
+    struct workspace *ws = data;
+
+    ws->focus_animation = NULL;
+}
+
 static void
 focus_state_destroy(struct focus_state *state)
 {
@@ -550,17 +657,19 @@ focus_state_surface_destroy(struct wl_listener *listener, void *data)
                          struct focus_state,
                          surface_destroy_listener);
     struct desktop_shell *shell;
-    struct weston_surface *main_surface;
-    struct weston_surface *surface, *next;
+    struct weston_surface *main_surface, *next;
+    struct weston_view *view;
 
     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)
+    wl_list_for_each(view, &state->ws->layer.view_list, layer_link) {
+        if (view->surface == main_surface)
+            continue;
+        if (is_focus_view(view))
             continue;
 
-        next = surface;
+        next = view->surface;
         break;
     }
 
@@ -568,10 +677,21 @@ focus_state_surface_destroy(struct wl_listener *listener, void *data)
     if (main_surface != state->keyboard_focus)
         next = main_surface;
 
+    shell = state->seat->compositor->shell_interface.shell;
     if (next) {
-        shell = state->seat->compositor->shell_interface.shell;
+        state->keyboard_focus = NULL;
         activate(shell, next, state->seat);
     } else {
+        if (shell->focus_animation_type == ANIMATION_DIM_LAYER) {
+            if (state->ws->focus_animation)
+                weston_view_animation_destroy(state->ws->focus_animation);
+
+            state->ws->focus_animation = weston_fade_run(
+                state->ws->fsurf_front->view,
+                state->ws->fsurf_front->view->alpha, 0.0, 300,
+                focus_animation_done, state->ws);
+        }
+
         wl_list_remove(&state->link);
         focus_state_destroy(state);
     }
@@ -586,6 +706,7 @@ focus_state_create(struct weston_seat *seat, struct workspace *ws)
     if (state == NULL)
         return NULL;
 
+    state->keyboard_focus = NULL;
     state->ws = ws;
     state->seat = seat;
     wl_list_insert(&ws->focus_list, &state->link);
@@ -616,12 +737,30 @@ ensure_focus_state(struct desktop_shell *shell, struct weston_seat *seat)
 }
 
 static void
+focus_state_set_focus(struct focus_state *state,
+              struct weston_surface *surface)
+{
+    if (state->keyboard_focus) {
+        wl_list_remove(&state->surface_destroy_listener.link);
+        wl_list_init(&state->surface_destroy_listener.link);
+    }
+
+    state->keyboard_focus = surface;
+    if (surface)
+        wl_signal_add(&surface->destroy_signal,
+                  &state->surface_destroy_listener);
+}
+
+static void
 restore_focus_state(struct desktop_shell *shell, struct workspace *ws)
 {
     struct focus_state *state, *next;
     struct weston_surface *surface;
 
     wl_list_for_each_safe(state, next, &ws->focus_list, link) {
+        if (state->seat->keyboard == NULL)
+            continue;
+
         surface = state->keyboard_focus;
 
         weston_keyboard_set_focus(state->seat->keyboard, surface);
@@ -633,12 +772,10 @@ replace_focus_state(struct desktop_shell *shell, struct workspace *ws,
             struct weston_seat *seat)
 {
     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;
+            focus_state_set_focus(state, seat->keyboard->focus);
             return;
         }
     }
@@ -652,7 +789,72 @@ drop_focus_state(struct desktop_shell *shell, struct workspace *ws,
 
     wl_list_for_each(state, &ws->focus_list, link)
         if (state->keyboard_focus == surface)
-            state->keyboard_focus = NULL;
+            focus_state_set_focus(state, NULL);
+}
+
+static void
+animate_focus_change(struct desktop_shell *shell, struct workspace *ws,
+             struct weston_view *from, struct weston_view *to)
+{
+    struct weston_output *output;
+    bool focus_surface_created = false;
+
+    /* FIXME: Only support dim animation using two layers */
+    if (from == to || shell->focus_animation_type != ANIMATION_DIM_LAYER)
+        return;
+
+    output = get_default_output(shell->compositor);
+    if (ws->fsurf_front == NULL && (from || to)) {
+        ws->fsurf_front = create_focus_surface(shell->compositor, output);
+        if (ws->fsurf_front == NULL)
+            return;
+        ws->fsurf_front->view->alpha = 0.0;
+
+        ws->fsurf_back = create_focus_surface(shell->compositor, output);
+        if (ws->fsurf_back == NULL) {
+            focus_surface_destroy(ws->fsurf_front);
+            return;
+        }
+        ws->fsurf_back->view->alpha = 0.0;
+
+        focus_surface_created = true;
+    } else {
+        wl_list_remove(&ws->fsurf_front->view->layer_link);
+        wl_list_remove(&ws->fsurf_back->view->layer_link);
+    }
+
+    if (ws->focus_animation) {
+        weston_view_animation_destroy(ws->focus_animation);
+        ws->focus_animation = NULL;
+    }
+
+    if (to)
+        wl_list_insert(&to->layer_link,
+                   &ws->fsurf_front->view->layer_link);
+    else if (from)
+        wl_list_insert(&ws->layer.view_list,
+                   &ws->fsurf_front->view->layer_link);
+
+    if (focus_surface_created) {
+        ws->focus_animation = weston_fade_run(
+            ws->fsurf_front->view,
+            ws->fsurf_front->view->alpha, 0.6, 300,
+            focus_animation_done, ws);
+    } else if (from) {
+        wl_list_insert(&from->layer_link,
+                   &ws->fsurf_back->view->layer_link);
+        ws->focus_animation = weston_stable_fade_run(
+            ws->fsurf_front->view, 0.0,
+            ws->fsurf_back->view, 0.6,
+            focus_animation_done, ws);
+    } else if (to) {
+        wl_list_insert(&ws->layer.view_list,
+                   &ws->fsurf_back->view->layer_link);
+        ws->focus_animation = weston_stable_fade_run(
+            ws->fsurf_front->view, 0.0,
+            ws->fsurf_back->view, 0.6,
+            focus_animation_done, ws);
+    }
 }
 
 static void
@@ -663,6 +865,11 @@ workspace_destroy(struct workspace *ws)
     wl_list_for_each_safe(state, next, &ws->focus_list, link)
         focus_state_destroy(state);
 
+    if (ws->fsurf_front)
+        focus_surface_destroy(ws->fsurf_front);
+    if (ws->fsurf_back)
+        focus_surface_destroy(ws->fsurf_back);
+
     free(ws);
 }
 
@@ -692,6 +899,9 @@ workspace_create(void)
     wl_list_init(&ws->focus_list);
     wl_list_init(&ws->seat_destroyed_listener.link);
     ws->seat_destroyed_listener.notify = seat_destroyed;
+    ws->fsurf_front = NULL;
+    ws->fsurf_back = NULL;
+    ws->focus_animation = NULL;
 
     return ws;
 }
@@ -699,7 +909,7 @@ workspace_create(void)
 static int
 workspace_is_empty(struct workspace *ws)
 {
-    return wl_list_empty(&ws->layer.surface_list);
+    return wl_list_empty(&ws->layer.view_list);
 }
 
 static struct workspace *
@@ -711,7 +921,7 @@ get_workspace(struct desktop_shell *shell, unsigned int index)
     return *pws;
 }
 
-static struct workspace *
+struct workspace *
 get_current_workspace(struct desktop_shell *shell)
 {
     return get_workspace(shell, shell->workspaces.current);
@@ -735,53 +945,59 @@ get_output_height(struct weston_output *output)
 }
 
 static void
-surface_translate(struct weston_surface *surface, double d)
+view_translate(struct workspace *ws, struct weston_view *view, double d)
 {
-    struct shell_surface *shsurf = get_shell_surface(surface);
     struct weston_transform *transform;
 
-    transform = &shsurf->workspace_transform;
+    if (is_focus_view(view)) {
+        struct focus_surface *fsurf = get_focus_surface(view->surface);
+        transform = &fsurf->workspace_transform;
+    } else {
+        struct shell_surface *shsurf = get_shell_surface(view->surface);
+        transform = &shsurf->workspace_transform;
+    }
+
     if (wl_list_empty(&transform->link))
-        wl_list_insert(surface->geometry.transformation_list.prev,
-                   &shsurf->workspace_transform.link);
+        wl_list_insert(view->geometry.transformation_list.prev,
+                   &transform->link);
 
-    weston_matrix_init(&shsurf->workspace_transform.matrix);
-    weston_matrix_translate(&shsurf->workspace_transform.matrix,
+    weston_matrix_init(&transform->matrix);
+    weston_matrix_translate(&transform->matrix,
                 0.0, d, 0.0);
-    weston_surface_geometry_dirty(surface);
+    weston_view_geometry_dirty(view);
 }
 
 static void
 workspace_translate_out(struct workspace *ws, double fraction)
 {
-    struct weston_surface *surface;
+    struct weston_view *view;
     unsigned int height;
     double d;
 
-    wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
-        height = get_output_height(surface->output);
+    wl_list_for_each(view, &ws->layer.view_list, layer_link) {
+        height = get_output_height(view->surface->output);
         d = height * fraction;
 
-        surface_translate(surface, d);
+        view_translate(ws, view, d);
     }
 }
 
 static void
 workspace_translate_in(struct workspace *ws, double fraction)
 {
-    struct weston_surface *surface;
+    struct weston_view *view;
     unsigned int height;
     double d;
 
-    wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
-        height = get_output_height(surface->output);
+    wl_list_for_each(view, &ws->layer.view_list, layer_link) {
+        height = get_output_height(view->surface->output);
 
         if (fraction > 0)
             d = -(height - height * fraction);
         else
             d = height + height * fraction;
 
-        surface_translate(surface, d);
+        view_translate(ws, view, d);
     }
 }
 
@@ -815,16 +1031,23 @@ reverse_workspace_change_animation(struct desktop_shell *shell,
 static void
 workspace_deactivate_transforms(struct workspace *ws)
 {
-    struct weston_surface *surface;
-    struct shell_surface *shsurf;
+    struct weston_view *view;
+    struct weston_transform *transform;
+
+    wl_list_for_each(view, &ws->layer.view_list, layer_link) {
+        if (is_focus_view(view)) {
+            struct focus_surface *fsurf = get_focus_surface(view->surface);
+            transform = &fsurf->workspace_transform;
+        } else {
+            struct shell_surface *shsurf = get_shell_surface(view->surface);
+            transform = &shsurf->workspace_transform;
+        }
 
-    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);
+        if (!wl_list_empty(&transform->link)) {
+            wl_list_remove(&transform->link);
+            wl_list_init(&transform->link);
         }
-        weston_surface_geometry_dirty(surface);
+        weston_view_geometry_dirty(view);
     }
 }
 
@@ -945,12 +1168,13 @@ change_workspace(struct desktop_shell *shell, unsigned int index)
 {
     struct workspace *from;
     struct workspace *to;
+    struct focus_state *state;
 
     if (index == shell->workspaces.current)
         return;
 
     /* Don't change workspace when there is any fullscreen surfaces. */
-    if (!wl_list_empty(&shell->fullscreen_layer.surface_list))
+    if (!wl_list_empty(&shell->fullscreen_layer.view_list))
         return;
 
     from = get_current_workspace(shell);
@@ -971,6 +1195,18 @@ change_workspace(struct desktop_shell *shell, unsigned int index)
 
     restore_focus_state(shell, to);
 
+    if (shell->focus_animation_type != ANIMATION_NONE) {
+        wl_list_for_each(state, &from->focus_list, link)
+            if (state->keyboard_focus)
+                animate_focus_change(shell, from,
+                             get_default_view(state->keyboard_focus), NULL);
+
+        wl_list_for_each(state, &to->focus_list, link)
+            if (state->keyboard_focus)
+                animate_focus_change(shell, to,
+                             NULL, get_default_view(state->keyboard_focus));
+    }
+
     if (workspace_is_empty(to) && workspace_is_empty(from))
         update_workspace(shell, index, from, to);
     else
@@ -982,7 +1218,7 @@ change_workspace(struct desktop_shell *shell, unsigned int index)
 static bool
 workspace_has_only(struct workspace *ws, struct weston_surface *surface)
 {
-    struct wl_list *list = &ws->layer.surface_list;
+    struct wl_list *list = &ws->layer.view_list;
     struct wl_list *e;
 
     if (wl_list_empty(list))
@@ -993,44 +1229,51 @@ workspace_has_only(struct workspace *ws, struct weston_surface *surface)
     if (e->next != list)
         return false;
 
-    return container_of(e, struct weston_surface, layer_link) == surface;
+    return container_of(e, struct weston_view, layer_link)->surface == surface;
 }
 
 static void
 move_surface_to_workspace(struct desktop_shell *shell,
-              struct weston_surface *surface,
-              uint32_t workspace)
+                          struct shell_surface *shsurf,
+                          uint32_t workspace)
 {
     struct workspace *from;
     struct workspace *to;
     struct weston_seat *seat;
     struct weston_surface *focus;
-
-    assert(weston_surface_get_main_surface(surface) == surface);
+    struct weston_view *view;
 
     if (workspace == shell->workspaces.current)
         return;
 
+    view = get_default_view(shsurf->surface);
+    if (!view)
+        return;
+
+    assert(weston_surface_get_main_surface(view->surface) == view->surface);
+
     if (workspace >= shell->workspaces.num)
         workspace = shell->workspaces.num - 1;
 
     from = get_current_workspace(shell);
     to = get_workspace(shell, workspace);
 
-    wl_list_remove(&surface->layer_link);
-    wl_list_insert(&to->layer.surface_list, &surface->layer_link);
+    wl_list_remove(&view->layer_link);
+    wl_list_insert(&to->layer.view_list, &view->layer_link);
 
-    drop_focus_state(shell, from, surface);
+    shell_surface_update_child_surface_layers(shsurf);
+
+    drop_focus_state(shell, from, view->surface);
     wl_list_for_each(seat, &shell->compositor->seat_list, link) {
         if (!seat->keyboard)
             continue;
 
         focus = weston_surface_get_main_surface(seat->keyboard->focus);
-        if (focus == surface)
+        if (focus == view->surface)
             weston_keyboard_set_focus(seat->keyboard, NULL);
     }
 
-    weston_surface_damage_below(surface);
+    weston_view_damage_below(view);
 }
 
 static void
@@ -1039,21 +1282,28 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell,
                   unsigned int index)
 {
     struct weston_surface *surface;
+    struct weston_view *view;
     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)
+    view = get_default_view(surface);
+    if (view == NULL ||
+        index == shell->workspaces.current ||
+        is_focus_view(view))
         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);
+    wl_list_remove(&view->layer_link);
+    wl_list_insert(&to->layer.view_list, &view->layer_link);
+
+    shsurf = get_shell_surface(surface);
+    if (shsurf != NULL)
+        shell_surface_update_child_surface_layers(shsurf);
 
     replace_focus_state(shell, to, seat);
     drop_focus_state(shell, from, surface);
@@ -1078,8 +1328,8 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell,
         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))
+        if (shsurf != NULL &&
+            wl_list_empty(&shsurf->workspace_transform.link))
             wl_list_insert(&shell->workspaces.anim_sticky_list,
                        &shsurf->workspace_transform.link);
 
@@ -1090,7 +1340,7 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell,
 
     state = ensure_focus_state(shell, seat);
     if (state != NULL)
-        state->keyboard_focus = surface;
+        focus_state_set_focus(state, surface);
 }
 
 static void
@@ -1103,9 +1353,14 @@ workspace_manager_move_surface(struct wl_client *client,
     struct weston_surface *surface =
         wl_resource_get_user_data(surface_resource);
     struct weston_surface *main_surface;
+    struct shell_surface *shell_surface;
 
     main_surface = weston_surface_get_main_surface(surface);
-    move_surface_to_workspace(shell, main_surface, workspace);
+    shell_surface = get_shell_surface(main_surface);
+    if (shell_surface == NULL)
+        return;
+
+    move_surface_to_workspace(shell, shell_surface, workspace);
 }
 
 static const struct workspace_manager_interface workspace_manager_implementation = {
@@ -1157,7 +1412,10 @@ touch_move_grab_up(struct weston_touch_grab *grab, uint32_t time, int touch_id)
         (struct weston_touch_move_grab *) container_of(
             grab, struct shell_touch_grab, grab);
 
-    if (grab->touch->seat->num_tp == 0) {
+    if (touch_id == 0)
+        move->active = 0;
+
+    if (grab->touch->num_tp == 0) {
         shell_touch_grab_end(&move->base);
         free(move);
     }
@@ -1173,13 +1431,17 @@ touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
     int dx = wl_fixed_to_int(grab->touch->grab_x + move->dx);
     int dy = wl_fixed_to_int(grab->touch->grab_y + move->dy);
 
-    if (!shsurf)
+    if (!shsurf || !move->active)
         return;
 
     es = shsurf->surface;
 
-    weston_surface_configure(es, dx, dy,
-                 es->geometry.width, es->geometry.height);
+    /* ico-ivi-shell hook move      */
+    if (shell_hook_move)    {
+        (*shell_hook_move)(es, &dx, &dy);
+    }
+
+    weston_view_set_position(shsurf->view, dx, dy);
 
     weston_compositor_schedule_repaint(es->compositor);
 }
@@ -1210,16 +1472,19 @@ surface_touch_move(struct shell_surface *shsurf, struct weston_seat *seat)
     if (!shsurf)
         return -1;
 
-    if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
+    if (shsurf->state.fullscreen)
+        return 0;
+    if (shsurf->grabbed)
         return 0;
 
     move = malloc(sizeof *move);
     if (!move)
         return -1;
 
-    move->dx = wl_fixed_from_double(shsurf->surface->geometry.x) -
+    move->active = 1;
+    move->dx = wl_fixed_from_double(shsurf->view->geometry.x) -
             seat->touch->grab_x;
-    move->dy = wl_fixed_from_double(shsurf->surface->geometry.y) -
+    move->dy = wl_fixed_from_double(shsurf->view->geometry.y) -
             seat->touch->grab_y;
 
     shell_touch_grab_start(&move->base, &touch_move_grab_interface, shsurf,
@@ -1234,28 +1499,24 @@ noop_grab_focus(struct weston_pointer_grab *grab)
 }
 
 static void
-move_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
+move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
+         wl_fixed_t x, wl_fixed_t y)
 {
     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);
+    int dx, dy;
+
+    weston_pointer_move(pointer, x, y);
+    dx = wl_fixed_to_int(pointer->x + move->dx);
+    dy = wl_fixed_to_int(pointer->y + move->dy);
 
     if (!shsurf)
         return;
 
-    es = shsurf->surface;
-
-    /* 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_view_set_position(shsurf->view, dx, dy);
 
-    weston_compositor_schedule_repaint(es->compositor);
+    weston_compositor_schedule_repaint(shsurf->surface->compositor);
 }
 
 static void
@@ -1299,16 +1560,18 @@ surface_move(struct shell_surface *shsurf, struct weston_seat *seat)
     if (!shsurf)
         return -1;
 
-    if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
+    if (shsurf->grabbed)
+        return 0;
+    if (shsurf->state.fullscreen || shsurf->state.maximized)
         return 0;
 
     move = malloc(sizeof *move);
     if (!move)
         return -1;
 
-    move->dx = wl_fixed_from_double(shsurf->surface->geometry.x) -
+    move->dx = wl_fixed_from_double(shsurf->view->geometry.x) -
             seat->pointer->grab_x;
-    move->dy = wl_fixed_from_double(shsurf->surface->geometry.y) -
+    move->dy = wl_fixed_from_double(shsurf->view->geometry.y) -
             seat->pointer->grab_y;
 
     shell_grab_start(&move->base, &move_grab_interface, shsurf,
@@ -1318,29 +1581,38 @@ surface_move(struct shell_surface *shsurf, struct weston_seat *seat)
 }
 
 static void
-shell_surface_move(struct wl_client *client, struct wl_resource *resource,
-           struct wl_resource *seat_resource, uint32_t serial)
+common_surface_move(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;
 
     if (seat->pointer &&
+        seat->pointer->focus &&
         seat->pointer->button_count > 0 &&
         seat->pointer->grab_serial == serial) {
-        surface = weston_surface_get_main_surface(seat->pointer->focus);
+        surface = weston_surface_get_main_surface(seat->pointer->focus->surface);
         if ((surface == shsurf->surface) &&
             (surface_move(shsurf, seat) < 0))
             wl_resource_post_no_memory(resource);
     } else if (seat->touch &&
+           seat->touch->focus &&
            seat->touch->grab_serial == serial) {
-        surface = weston_surface_get_main_surface(seat->touch->focus);
+        surface = weston_surface_get_main_surface(seat->touch->focus->surface);
         if ((surface == shsurf->surface) &&
             (surface_touch_move(shsurf, seat) < 0))
             wl_resource_post_no_memory(resource);
     }
 }
 
+static void
+shell_surface_move(struct wl_client *client, struct wl_resource *resource,
+           struct wl_resource *seat_resource, uint32_t serial)
+{
+    common_surface_move(resource, seat_resource, serial);
+}
+
 struct weston_resize_grab {
     struct shell_grab base;
     uint32_t edges;
@@ -1348,7 +1620,8 @@ struct weston_resize_grab {
 };
 
 static void
-resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
+resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
+           wl_fixed_t x, wl_fixed_t y)
 {
     struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
     struct weston_pointer *pointer = grab->pointer;
@@ -1357,14 +1630,16 @@ resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
     wl_fixed_t from_x, from_y;
     wl_fixed_t to_x, to_y;
 
+    weston_pointer_move(pointer, x, 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);
+    weston_view_from_global_fixed(shsurf->view,
+                      pointer->grab_x, pointer->grab_y,
+                      &from_x, &from_y);
+    weston_view_from_global_fixed(shsurf->view,
+                      pointer->x, pointer->y, &to_x, &to_y);
 
     width = resize->width;
     if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) {
@@ -1380,8 +1655,6 @@ resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
         height += wl_fixed_to_int(to_y - from_y);
     }
 
-    uifw_debug("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);
 }
@@ -1392,8 +1665,11 @@ send_configure(struct weston_surface *surface,
 {
     struct shell_surface *shsurf = get_shell_surface(surface);
 
+    assert(shsurf);
+
     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);
 }
@@ -1444,15 +1720,15 @@ surface_subsurfaces_boundingbox(struct weston_surface *surface, int32_t *x,
     struct weston_subsurface *subsurface;
 
     pixman_region32_init_rect(&region, 0, 0,
-                              surface->geometry.width,
-                              surface->geometry.height);
+                              surface->width,
+                              surface->height);
 
     wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
         pixman_region32_union_rect(&region, &region,
                                    subsurface->position.x,
                                    subsurface->position.y,
-                                   subsurface->surface->geometry.width,
-                                   subsurface->surface->geometry.height);
+                                   subsurface->surface->width,
+                                   subsurface->surface->height);
     }
 
     box = pixman_region32_extents(&region);
@@ -1474,8 +1750,7 @@ surface_resize(struct shell_surface *shsurf,
 {
     struct weston_resize_grab *resize;
 
-    if (shsurf->type == SHELL_SURFACE_FULLSCREEN ||
-        shsurf->type == SHELL_SURFACE_MAXIMIZED)
+    if (shsurf->state.fullscreen || shsurf->state.maximized)
         return 0;
 
     if (edges == 0 || edges > 15 ||
@@ -1497,28 +1772,39 @@ surface_resize(struct shell_surface *shsurf,
 }
 
 static void
-shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
-             struct wl_resource *seat_resource, uint32_t serial,
-             uint32_t edges)
+common_surface_resize(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)
+    if (shsurf->state.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)
+        seat->pointer->focus == NULL)
         return;
 
-    if (surface_resize(shsurf, seat, edges) < 0)
+    surface = weston_surface_get_main_surface(seat->pointer->focus->surface);
+    if (surface != shsurf->surface)
+        return;
+
+    if (surface_resize(shsurf, seat, edges) < 0)
         wl_resource_post_no_memory(resource);
 }
 
 static void
+shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
+             struct wl_resource *seat_resource, uint32_t serial,
+             uint32_t edges)
+{
+    common_surface_resize(resource, seat_resource, serial, edges);
+}
+
+static void
 end_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer);
 
 static void
@@ -1526,20 +1812,22 @@ 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;
+    struct weston_view *view;
     wl_fixed_t sx, sy;
 
-    surface = weston_compositor_pick_surface(pointer->seat->compositor,
-                         pointer->x, pointer->y,
-                         &sx, &sy);
+    view = weston_compositor_pick_view(pointer->seat->compositor,
+                       pointer->x, pointer->y,
+                       &sx, &sy);
 
-    if (!grab->shsurf || grab->shsurf->surface != surface)
+    if (!grab->shsurf || grab->shsurf->surface != view->surface)
         end_busy_cursor(grab->shsurf, pointer);
 }
 
 static void
-busy_cursor_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
+busy_cursor_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
+            wl_fixed_t x, wl_fixed_t y)
 {
+    weston_pointer_move(grab->pointer, x, y);
 }
 
 static void
@@ -1623,7 +1911,8 @@ ping_timeout_handler(void *data)
     shsurf->unresponsive = 1;
 
     wl_list_for_each(seat, &shsurf->surface->compositor->seat_list, link)
-        if (seat->pointer->focus == shsurf->surface)
+        if (seat->pointer && seat->pointer->focus &&
+            seat->pointer->focus->surface == shsurf->surface)
             set_busy_cursor(shsurf, seat->pointer);
 
     return 1;
@@ -1655,7 +1944,12 @@ ping_handler(struct weston_surface *surface, uint32_t serial)
             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);
+        if (shell_surface_is_wl_shell_surface(shsurf))
+            wl_shell_surface_send_ping(shsurf->resource, serial);
+        else if (shell_surface_is_xdg_surface(shsurf))
+            xdg_surface_send_ping(shsurf->resource, serial);
+        else if (shell_surface_is_xdg_popup(shsurf))
+            xdg_popup_send_ping(shsurf->resource, serial);
     }
 }
 
@@ -1663,22 +1957,22 @@ static void
 handle_pointer_focus(struct wl_listener *listener, void *data)
 {
     struct weston_pointer *pointer = data;
-    struct weston_surface *surface = pointer->focus;
+    struct weston_view *view = pointer->focus;
     struct weston_compositor *compositor;
     struct shell_surface *shsurf;
     uint32_t serial;
 
-    if (!surface)
+    if (!view)
         return;
 
-    compositor = surface->compositor;
-    shsurf = get_shell_surface(surface);
+    compositor = view->surface->compositor;
+    shsurf = get_shell_surface(view->surface);
 
     if (shsurf && shsurf->unresponsive) {
         set_busy_cursor(shsurf, pointer);
     } else {
         serial = wl_display_next_serial(compositor->wl_display);
-        ping_handler(surface, serial);
+        ping_handler(view->surface, serial);
     }
 }
 
@@ -1696,12 +1990,26 @@ create_pointer_focus_listener(struct weston_seat *seat)
 }
 
 static void
-shell_surface_pong(struct wl_client *client, struct wl_resource *resource,
-                            uint32_t serial)
+xdg_surface_set_transient_for(struct wl_client *client,
+                             struct wl_resource *resource,
+                             struct wl_resource *parent_resource)
 {
     struct shell_surface *shsurf = wl_resource_get_user_data(resource);
-    struct weston_seat *seat;
+    struct weston_surface *parent;
+
+    if (parent_resource)
+        parent = wl_resource_get_user_data(parent_resource);
+    else
+        parent = NULL;
+
+    shell_surface_set_parent(shsurf, parent);
+}
+
+static void
+surface_pong(struct shell_surface *shsurf, uint32_t serial)
+{
     struct weston_compositor *ec = shsurf->surface->compositor;
+    struct weston_seat *seat;
 
     if (shsurf->ping_timer == NULL)
         /* Just ignore unsolicited pong. */
@@ -1718,6 +2026,16 @@ shell_surface_pong(struct wl_client *client, struct wl_resource *resource,
 }
 
 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);
+
+    surface_pong(shsurf, serial);
+
+}
+
+static void
 set_title(struct shell_surface *shsurf, const char *title)
 {
     char    *p;
@@ -1755,17 +2073,6 @@ shell_surface_set_class(struct wl_client *client,
     shsurf->class = strdup(class);
 }
 
-static struct weston_output *
-get_default_output(struct weston_compositor *compositor)
-{
-    /* support multi display, default fullscreen output display */
-    if (default_inputpanel) {
-        return default_inputpanel;
-    }
-    return container_of(compositor->output_list.next,
-                struct weston_output, link);
-}
-
 static void
 restore_output_mode(struct weston_output *output)
 {
@@ -1786,139 +2093,172 @@ restore_all_output_modes(struct weston_compositor *compositor)
         restore_output_mode(output);
 }
 
-static void
-shell_unset_fullscreen(struct shell_surface *shsurf)
+static int
+get_output_panel_height(struct desktop_shell *shell,
+            struct weston_output *output)
 {
-    struct workspace *ws;
+    struct weston_view *view;
+    int panel_height = 0;
 
-    uifw_debug("shell_unset_fullscreen: ");
+    if (!output)
+        return 0;
 
-    /* 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;
+    wl_list_for_each(view, &shell->panel_layer.view_list, layer_link) {
+        if (view->surface->output == output) {
+            panel_height = view->surface->height;
+            break;
+        }
     }
 
-    ws = get_current_workspace(shsurf->shell);
-    wl_list_remove(&shsurf->surface->layer_link);
-    wl_list_insert(&ws->layer.surface_list, &shsurf->surface->layer_link);
+    return panel_height;
 }
 
-static void
-shell_unset_maximized(struct shell_surface *shsurf)
+/* The surface will be inserted into the list immediately after the link
+ * returned by this function (i.e. will be stacked immediately above the
+ * returned link). */
+static struct wl_list *
+shell_surface_calculate_layer_link (struct shell_surface *shsurf)
 {
     struct workspace *ws;
+    struct weston_view *parent;
 
-    uifw_debug("shell_unset_maximized: ");
+    switch (shsurf->type) {
+    case SHELL_SURFACE_POPUP:
+    case SHELL_SURFACE_TOPLEVEL:
+        if (shsurf->state.fullscreen) {
+            return &shsurf->shell->fullscreen_layer.view_list;
+        } else if (shsurf->parent) {
+            /* Move the surface to its parent layer so
+             * that surfaces which are transient for
+             * fullscreen surfaces don't get hidden by the
+             * fullscreen surfaces. */
+
+            /* TODO: Handle a parent with multiple views */
+            parent = get_default_view(shsurf->parent);
+            if (parent)
+                return parent->layer_link.prev;
+        }
+        break;
 
-    /* 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);
+    case SHELL_SURFACE_XWAYLAND:
+        return &shsurf->shell->fullscreen_layer.view_list;
 
-    if (shsurf->saved_rotation_valid) {
-        wl_list_insert(&shsurf->surface->geometry.transformation_list,
-                           &shsurf->rotation.transform.link);
-        shsurf->saved_rotation_valid = false;
+    case SHELL_SURFACE_NONE:
+    default:
+        /* Go to the fallback, below. */
+        break;
     }
 
+    /* Move the surface to a normal workspace layer so that surfaces
+     * which were previously fullscreen or transient are no longer
+     * rendered on top. */
     ws = get_current_workspace(shsurf->shell);
-    wl_list_remove(&shsurf->surface->layer_link);
-    wl_list_insert(&ws->layer.surface_list, &shsurf->surface->layer_link);
+    return &ws->layer.view_list;
 }
 
-static int
-reset_shell_surface_type(struct shell_surface *surface)
+static void
+shell_surface_update_child_surface_layers (struct shell_surface *shsurf)
 {
-    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;
-    }
+    struct shell_surface *child;
 
-    surface->type = SHELL_SURFACE_NONE;
-    return 0;
+    /* Move the child layers to the same workspace as shsurf. They will be
+     * stacked above shsurf. */
+    wl_list_for_each_reverse(child, &shsurf->children_list, children_link) {
+        if (shsurf->view->layer_link.prev != &child->view->layer_link) {
+            weston_view_geometry_dirty(child->view);
+            wl_list_remove(&child->view->layer_link);
+            wl_list_insert(shsurf->view->layer_link.prev,
+                           &child->view->layer_link);
+            weston_view_geometry_dirty(child->view);
+            weston_surface_damage(child->surface);
+
+            /* Recurse. We don’t expect this to recurse very far (if
+             * at all) because that would imply we have transient
+             * (or popup) children of transient surfaces, which
+             * would be unusual. */
+            shell_surface_update_child_surface_layers(child);
+        }
+    }
 }
 
+/* Update the surface’s layer. Mark both the old and new views as having dirty
+ * geometry to ensure the changes are redrawn.
+ *
+ * If any child surfaces exist and are mapped, ensure they’re in the same layer
+ * as this surface. */
 static void
-set_surface_type(struct shell_surface *shsurf)
+shell_surface_update_layer(struct shell_surface *shsurf)
 {
-    struct weston_surface *surface = shsurf->surface;
-    struct weston_surface *pes = shsurf->parent;
+    struct wl_list *new_layer_link;
 
-    reset_shell_surface_type(shsurf);
+    new_layer_link = shell_surface_calculate_layer_link(shsurf);
 
-    shsurf->type = shsurf->next_type;
-    shsurf->next_type = SHELL_SURFACE_NONE;
+    if (new_layer_link == &shsurf->view->layer_link)
+        return;
 
-    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;
+    weston_view_geometry_dirty(shsurf->view);
+    wl_list_remove(&shsurf->view->layer_link);
+    wl_list_insert(new_layer_link, &shsurf->view->layer_link);
+    weston_view_geometry_dirty(shsurf->view);
+    weston_surface_damage(shsurf->surface);
 
-    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;
-        }
-        if (shsurf->type == SHELL_SURFACE_FULLSCREEN)   {
-            uifw_debug("set_surface_type: set fullscreen");
-            if (shell_hook_fullscreen)  {
-                (*shell_hook_fullscreen)(SHELL_FULLSCREEN_SET, surface);
-            }
-        }
-        break;
+    shell_surface_update_child_surface_layers(shsurf);
+}
 
-    case SHELL_SURFACE_XWAYLAND:
-        weston_surface_set_position(surface, shsurf->transient.x,
-                        shsurf->transient.y);
-        break;
+static void
+shell_surface_set_parent(struct shell_surface *shsurf,
+                         struct weston_surface *parent)
+{
+    shsurf->parent = parent;
 
-    default:
-        break;
+    wl_list_remove(&shsurf->children_link);
+    wl_list_init(&shsurf->children_link);
+
+    /* Insert into the parent surface’s child list. */
+    if (parent != NULL) {
+        struct shell_surface *parent_shsurf = get_shell_surface(parent);
+        if (parent_shsurf != NULL)
+            wl_list_insert(&parent_shsurf->children_list,
+                           &shsurf->children_link);
     }
 }
 
 static void
+shell_surface_set_output(struct shell_surface *shsurf,
+                         struct weston_output *output)
+{
+    struct weston_surface *es = shsurf->surface;
+
+    /* get the default output, if the client set it as NULL
+       check whether the ouput is available */
+    if (output)
+        shsurf->output = output;
+    else if (es->output)
+        shsurf->output = es->output;
+    else
+        shsurf->output = get_default_output(es->compositor);
+}
+
+static void
+surface_clear_next_states(struct shell_surface *shsurf)
+{
+    shsurf->next_state.maximized = false;
+    shsurf->next_state.fullscreen = false;
+
+    if ((shsurf->next_state.maximized != shsurf->state.maximized) ||
+        (shsurf->next_state.fullscreen != shsurf->state.fullscreen))
+        shsurf->state_changed = true;
+}
+
+static void
 set_toplevel(struct shell_surface *shsurf)
 {
-       shsurf->next_type = SHELL_SURFACE_TOPLEVEL;
+    shell_surface_set_parent(shsurf, NULL);
+    surface_clear_next_states(shsurf);
+    shsurf->type = SHELL_SURFACE_TOPLEVEL;
+
+    /* The layer_link is updated in set_surface_type(),
+     * called from configure. */
 }
 
 static void
@@ -1934,12 +2274,22 @@ 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;
+    assert(parent != NULL);
+
+    shell_surface_set_parent(shsurf, parent);
+
+    surface_clear_next_states(shsurf);
+
     shsurf->transient.x = x;
     shsurf->transient.y = y;
     shsurf->transient.flags = flags;
-    shsurf->next_type = SHELL_SURFACE_TRANSIENT;
+
+    shsurf->next_state.relative = true;
+    shsurf->state_changed = true;
+    shsurf->type = SHELL_SURFACE_TOPLEVEL;
+
+    /* The layer_link is updated in set_surface_type(),
+     * called from configure. */
 }
 
 static void
@@ -1955,144 +2305,369 @@ shell_surface_set_transient(struct wl_client *client,
     set_transient(shsurf, parent, x, y, flags);
 }
 
-static struct desktop_shell *
-shell_surface_get_shell(struct shell_surface *shsurf)
+static void
+set_fullscreen(struct shell_surface *shsurf,
+           uint32_t method,
+           uint32_t framerate,
+           struct weston_output *output)
 {
-    return shsurf->shell;
-}
+    shell_surface_set_output(shsurf, output);
 
-static int
-get_output_panel_height(struct desktop_shell *shell,
-            struct weston_output *output)
-{
-    struct weston_surface *surface;
-    int panel_height = 0;
+    shsurf->fullscreen_output = shsurf->output;
+    shsurf->fullscreen.type = method;
+    shsurf->fullscreen.framerate = framerate;
 
-    if (!output)
-        return 0;
+    shsurf->next_state.fullscreen = true;
+    shsurf->state_changed = true;
+    shsurf->type = SHELL_SURFACE_TOPLEVEL;
 
-    wl_list_for_each(surface, &shell->panel_layer.surface_list, layer_link) {
-        if (surface->output == output) {
-            panel_height = surface->geometry.height;
-            break;
-        }
+    if (shell_hook_fullscreen)  {
+        (*shell_hook_fullscreen)(SHELL_FULLSCREEN_SET, shsurf->surface);
+        return;
     }
 
-    return panel_height;
+    shsurf->client->send_configure(shsurf->surface, 0,
+                       shsurf->output->width,
+                       shsurf->output->height);
+
+    /* The layer_link is updated in set_surface_type(),
+     * called from configure. */
 }
 
 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;
+weston_view_set_initial_position(struct weston_view *view,
+                 struct desktop_shell *shell);
 
-    /* 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);
+static void
+unset_fullscreen(struct shell_surface *shsurf)
+{
+    /* Unset the fullscreen output, driver configuration and transforms. */
+    if (shsurf->fullscreen.type == WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER &&
+        shell_surface_is_top_fullscreen(shsurf)) {
+        restore_output_mode(shsurf->fullscreen_output);
     }
-    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;
+    shsurf->fullscreen_output = NULL;
 
-    uifw_debug("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->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
+    shsurf->fullscreen.framerate = 0;
 
-    shsurf->next_type = SHELL_SURFACE_MAXIMIZED;
-}
+    if (shell_hook_fullscreen)  {
+        (*shell_hook_fullscreen)(SHELL_FULLSCREEN_UNSET, shsurf->surface);
+    }
 
-static void
-black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height);
+    wl_list_remove(&shsurf->fullscreen.transform.link);
+    wl_list_init(&shsurf->fullscreen.transform.link);
 
-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;
+    if (shsurf->fullscreen.black_view)
+        weston_surface_destroy(shsurf->fullscreen.black_view->surface);
+    shsurf->fullscreen.black_view = NULL;
 
-    uifw_debug("create_black_surface: fullscreen");
-    surface = weston_surface_create(ec);
-    if (surface == NULL) {
-        weston_log("no memory\n");
-        return NULL;
-    }
+    if (shsurf->saved_position_valid)
+        weston_view_set_position(shsurf->view,
+                     shsurf->saved_x, shsurf->saved_y);
+    else
+        weston_view_set_initial_position(shsurf->view, shsurf->shell);
 
-    surface->configure = black_surface_configure;
-    surface->configure_private = fs_surface;
-    uifw_debug("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);
+    if (shsurf->saved_rotation_valid) {
+        wl_list_insert(&shsurf->view->geometry.transformation_list,
+                       &shsurf->rotation.transform.link);
+        shsurf->saved_rotation_valid = false;
+    }
 
-    return surface;
+    /* Layer is updated in set_surface_type(). */
 }
 
-/* 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)
+shell_surface_set_fullscreen(struct wl_client *client,
+                 struct wl_resource *resource,
+                 uint32_t method,
+                 uint32_t framerate,
+                 struct wl_resource *output_resource)
 {
-    uifw_debug("shell_configure_fullscreen: ");
+    struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+    struct weston_output *output;
 
-    if (shell_hook_fullscreen)  {
-        (*shell_hook_fullscreen)(SHELL_FULLSCREEN_CONF, shsurf->surface);
-        return;
-    }
+    if (output_resource)
+        output = wl_resource_get_user_data(output_resource);
+    else
+        output = NULL;
 
-    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;
+    shell_surface_set_parent(shsurf, NULL);
 
-    if (shsurf->fullscreen.type != WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER)
-        restore_output_mode(output);
+    surface_clear_next_states(shsurf);
+    set_fullscreen(shsurf, method, framerate, output);
+}
 
-    if (!shsurf->fullscreen.black_surface)
-        shsurf->fullscreen.black_surface =
-            create_black_surface(surface->compositor,
-                         surface,
-                         output->x, output->y,
-                         output->width,
-                         output->height);
+static void
+set_popup(struct shell_surface *shsurf,
+          struct weston_surface *parent,
+          struct weston_seat *seat,
+          uint32_t serial,
+          int32_t x,
+          int32_t y)
+{
+    assert(parent != NULL);
 
-    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;
+    shsurf->popup.shseat = get_shell_seat(seat);
+    shsurf->popup.serial = serial;
+    shsurf->popup.x = x;
+    shsurf->popup.y = y;
 
-    surface_subsurfaces_boundingbox(surface, &surf_x, &surf_y,
+    shsurf->type = SHELL_SURFACE_POPUP;
+}
+
+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);
+    struct weston_surface *parent =
+        wl_resource_get_user_data(parent_resource);
+
+    shell_surface_set_parent(shsurf, parent);
+
+    surface_clear_next_states(shsurf);
+    set_popup(shsurf,
+              parent,
+              wl_resource_get_user_data(seat_resource),
+              serial, x, y);
+}
+
+static void
+set_maximized(struct shell_surface *shsurf,
+              struct weston_output *output)
+{
+    struct desktop_shell *shell;
+    uint32_t edges = 0, panel_height = 0;
+
+    shell_surface_set_output(shsurf, output);
+
+    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;
+
+    shsurf->client->send_configure(shsurf->surface, edges,
+                                   shsurf->output->width,
+                                   shsurf->output->height - panel_height);
+
+    shsurf->next_state.maximized = true;
+    shsurf->state_changed = true;
+    shsurf->type = SHELL_SURFACE_TOPLEVEL;
+}
+
+static void
+unset_maximized(struct shell_surface *shsurf)
+{
+    /* undo all maximized things here */
+    shsurf->output = get_default_output(shsurf->surface->compositor);
+
+    if (shsurf->saved_position_valid)
+        weston_view_set_position(shsurf->view,
+                     shsurf->saved_x, shsurf->saved_y);
+    else
+        weston_view_set_initial_position(shsurf->view, shsurf->shell);
+
+    if (shsurf->saved_rotation_valid) {
+        wl_list_insert(&shsurf->view->geometry.transformation_list,
+                   &shsurf->rotation.transform.link);
+        shsurf->saved_rotation_valid = false;
+    }
+
+    /* Layer is updated in set_surface_type(). */
+}
+
+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_output *output;
+
+    if (output_resource)
+        output = wl_resource_get_user_data(output_resource);
+    else
+        output = NULL;
+
+    shell_surface_set_parent(shsurf, NULL);
+
+    surface_clear_next_states(shsurf);
+    set_maximized(shsurf, output);
+}
+
+/* This is only ever called from set_surface_type(), so there’s no need to
+ * update layer_links here, since they’ll be updated when we return. */
+static int
+reset_surface_type(struct shell_surface *surface)
+{
+    if (surface->state.fullscreen)
+        unset_fullscreen(surface);
+    if (surface->state.maximized)
+        unset_maximized(surface);
+
+    return 0;
+}
+
+static void
+set_full_output(struct shell_surface *shsurf)
+{
+    shsurf->saved_x = shsurf->view->geometry.x;
+    shsurf->saved_y = shsurf->view->geometry.y;
+    shsurf->saved_width = shsurf->surface->width;
+    shsurf->saved_height = shsurf->surface->height;
+    shsurf->saved_size_valid = true;
+    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_view_geometry_dirty(shsurf->view);
+        shsurf->saved_rotation_valid = true;
+    }
+}
+
+static void
+set_surface_type(struct shell_surface *shsurf)
+{
+    struct weston_surface *pes = shsurf->parent;
+    struct weston_view *pev = get_default_view(pes);
+
+    reset_surface_type(shsurf);
+
+    shsurf->state = shsurf->next_state;
+    shsurf->state_changed = false;
+
+    switch (shsurf->type) {
+    case SHELL_SURFACE_TOPLEVEL:
+        if (shsurf->state.maximized || shsurf->state.fullscreen) {
+            set_full_output(shsurf);
+        } else if (shsurf->state.relative && pev) {
+            weston_view_set_position(shsurf->view,
+                         pev->geometry.x + shsurf->transient.x,
+                         pev->geometry.y + shsurf->transient.y);
+        }
+        break;
+
+    case SHELL_SURFACE_XWAYLAND:
+        weston_view_set_position(shsurf->view, shsurf->transient.x,
+                     shsurf->transient.y);
+        break;
+
+    case SHELL_SURFACE_POPUP:
+    case SHELL_SURFACE_NONE:
+    default:
+        break;
+    }
+
+    /* Update the surface’s layer. */
+    shell_surface_update_layer(shsurf);
+}
+
+static struct desktop_shell *
+shell_surface_get_shell(struct shell_surface *shsurf)
+{
+    return shsurf->shell;
+}
+
+static void
+black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy);
+
+static struct weston_view *
+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;
+    struct weston_view *view;
+
+    surface = weston_surface_create(ec);
+    if (surface == NULL) {
+        weston_log("no memory\n");
+        return NULL;
+    }
+    view = weston_view_create(surface);
+    if (surface == NULL) {
+        weston_log("no memory\n");
+        weston_surface_destroy(surface);
+        return NULL;
+    }
+
+    surface->configure = black_surface_configure;
+    surface->configure_private = fs_surface;
+    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);
+
+    weston_surface_set_size(surface, w, h);
+    weston_view_set_position(view, x, y);
+
+    return view;
+}
+
+static void
+shell_ensure_fullscreen_black_view(struct shell_surface *shsurf)
+{
+    struct weston_output *output = shsurf->fullscreen_output;
+
+    assert(shsurf->state.fullscreen);
+
+    if (!shsurf->fullscreen.black_view)
+        shsurf->fullscreen.black_view =
+            create_black_surface(shsurf->surface->compositor,
+                                 shsurf->surface,
+                                 output->x, output->y,
+                                 output->width,
+                                 output->height);
+
+    weston_view_geometry_dirty(shsurf->fullscreen.black_view);
+    wl_list_remove(&shsurf->fullscreen.black_view->layer_link);
+    wl_list_insert(&shsurf->view->layer_link,
+                   &shsurf->fullscreen.black_view->layer_link);
+    weston_view_geometry_dirty(shsurf->fullscreen.black_view);
+    weston_surface_damage(shsurf->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 (shell_hook_fullscreen)  {
+        (*shell_hook_fullscreen)(SHELL_FULLSCREEN_CONF, shsurf->surface);
+    }
+
+    if (shsurf->fullscreen.type != WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER)
+        restore_output_mode(output);
+
+    shell_ensure_fullscreen_black_view(shsurf);
+
+    surface_subsurfaces_boundingbox(shsurf->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);
+            center_on_output(shsurf->view, 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);
+            weston_view_set_position(shsurf->view,
+                         output->x - surf_x,
+                         output->y - surf_y);
             break;
         }
 
@@ -2101,8 +2676,9 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
 
         output_aspect = (float) output->width /
             (float) output->height;
-        surface_aspect = (float) surface->geometry.width /
-            (float) surface->geometry.height;
+        /* XXX: Use surf_width and surf_height here? */
+        surface_aspect = (float) surface->width /
+            (float) surface->height;
         if (output_aspect < surface_aspect)
             scale = (float) output->width /
                 (float) surf_width;
@@ -2112,145 +2688,64 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
 
         weston_matrix_scale(matrix, scale, scale, 1);
         wl_list_remove(&shsurf->fullscreen.transform.link);
-        wl_list_insert(&surface->geometry.transformation_list,
+        wl_list_insert(&shsurf->view->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);
+        weston_view_set_position(shsurf->view, 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,
+                surf_width * surface->buffer_viewport.scale,
+                surf_height * surface->buffer_viewport.scale,
                 shsurf->fullscreen.framerate};
 
-            if (weston_output_switch_mode(output, &mode, surface->buffer_scale,
+            if (weston_output_switch_mode(output, &mode, surface->buffer_viewport.scale,
                     WESTON_MODE_SWITCH_SET_TEMPORARY) == 0) {
-                weston_surface_set_position(surface,
-                                output->x - surf_x,
-                                output->y - surf_y);
-                uifw_debug("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);
+                weston_view_set_position(shsurf->view,
+                             output->x - surf_x,
+                             output->y - surf_y);
+                shsurf->fullscreen.black_view->surface->width = output->width;
+                shsurf->fullscreen.black_view->surface->height = output->height;
+                weston_view_set_position(shsurf->fullscreen.black_view,
+                             output->x - surf_x,
+                             output->y - surf_y);
                 break;
             } else {
                 restore_output_mode(output);
-                center_on_output(surface, output);
+                center_on_output(shsurf->view, output);
             }
         }
         break;
     case WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL:
-        center_on_output(surface, output);
+        center_on_output(shsurf->view, output);
         break;
     default:
         break;
     }
 }
 
-/* make the fullscreen and black surface at the top */
-static void
-shell_stack_fullscreen(struct shell_surface *shsurf)
-{
-    uifw_debug("shell_stack_fullscreen: ");
-
-    if (shell_hook_fullscreen)  {
-        (*shell_hook_fullscreen)(SHELL_FULLSCREEN_STACK, shsurf->surface);
-        return;
-    }
-
-    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)
 {
-    uifw_debug("shell_map_fullscreen: ");
-    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;
-
-    uifw_debug("set_fullscreen: ");
-
-    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;
-
-    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;
-
-    uifw_debug("shell_surface_set_fullscreen: ");
-
-    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 */
+    surface_clear_next_states(shsurf);
     shsurf->transient.x = x;
     shsurf->transient.y = y;
     shsurf->transient.flags = flags;
-    shsurf->next_type = SHELL_SURFACE_XWAYLAND;
+
+    shell_surface_set_parent(shsurf, NULL);
+
+    shsurf->type = SHELL_SURFACE_XWAYLAND;
+    shsurf->state_changed = true;
 }
 
 static const struct weston_pointer_grab_interface popup_grab_interface;
@@ -2319,18 +2814,19 @@ static void
 popup_grab_focus(struct weston_pointer_grab *grab)
 {
     struct weston_pointer *pointer = grab->pointer;
-    struct weston_surface *surface;
+    struct weston_view *view;
     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);
+    view = weston_compositor_pick_view(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);
+    if (view && view->surface->resource &&
+        wl_resource_get_client(view->surface->resource) == client) {
+        weston_pointer_set_focus(pointer, view, sx, sy);
     } else {
         weston_pointer_set_focus(pointer, NULL,
                      wl_fixed_from_int(0),
@@ -2339,16 +2835,19 @@ popup_grab_focus(struct weston_pointer_grab *grab)
 }
 
 static void
-popup_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
+popup_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
+          wl_fixed_t x, wl_fixed_t y)
 {
     struct weston_pointer *pointer = grab->pointer;
     struct wl_resource *resource;
     wl_fixed_t sx, sy;
 
+    weston_pointer_move(pointer, x, y);
+
     wl_resource_for_each(resource, &pointer->focus_resource_list) {
-        weston_surface_from_global_fixed(pointer->focus,
-                         pointer->x, pointer->y,
-                         &sx, &sy);
+        weston_view_from_global_fixed(pointer->focus,
+                          pointer->x, pointer->y,
+                          &sx, &sy);
         wl_pointer_send_motion(resource, time, sx, sy);
     }
 }
@@ -2396,6 +2895,16 @@ static const struct weston_pointer_grab_interface popup_grab_interface = {
 };
 
 static void
+shell_surface_send_popup_done(struct shell_surface *shsurf)
+{
+    if (shell_surface_is_wl_shell_surface(shsurf))
+        wl_shell_surface_send_popup_done(shsurf->resource);
+    else if (shell_surface_is_xdg_popup(shsurf))
+        xdg_popup_send_popup_done(shsurf->resource,
+                      shsurf->popup.serial);
+}
+
+static void
 popup_grab_end(struct weston_pointer *pointer)
 {
     struct weston_pointer_grab *grab = pointer->grab;
@@ -2411,7 +2920,7 @@ popup_grab_end(struct weston_pointer *pointer)
         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);
+            shell_surface_send_popup_done(shsurf);
             shsurf->popup.shseat = NULL;
             if (prev) {
                 wl_list_init(&prev->popup.grab_link);
@@ -2461,41 +2970,23 @@ 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;
+    struct weston_view *parent_view = get_default_view(shsurf->parent);
 
-    es->output = parent->output;
+    shsurf->surface->output = parent_view->output;
+    shsurf->view->output = parent_view->output;
 
-    weston_surface_set_transform_parent(es, parent);
-    weston_surface_set_position(es, shsurf->popup.x, shsurf->popup.y);
-    weston_surface_update_transform(es);
+    weston_view_set_transform_parent(shsurf->view, parent_view);
+    weston_view_set_position(shsurf->view, shsurf->popup.x, shsurf->popup.y);
+    weston_view_update_transform(shsurf->view);
 
     if (shseat->seat->pointer->grab_serial == shsurf->popup.serial) {
         add_popup_grab(shsurf, shseat);
     } else {
-        wl_shell_surface_send_popup_done(shsurf->resource);
+        shell_surface_send_popup_done(shsurf);
         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,
@@ -2512,13 +3003,15 @@ static const struct wl_shell_surface_interface shell_surface_implementation = {
 static void
 destroy_shell_surface(struct shell_surface *shsurf)
 {
-    wl_signal_emit(&shsurf->destroy_signal, shsurf);
+    struct shell_surface *child, *next;
 
     /* if ico_window_mgr hook, call hook routine    */
     if (shell_hook_destroy)  {
         (*shell_hook_destroy)(shsurf->surface);
     }
 
+    wl_signal_emit(&shsurf->destroy_signal, shsurf);
+
     if (!wl_list_empty(&shsurf->popup.grab_link)) {
         remove_popup_grab(shsurf);
     }
@@ -2527,8 +3020,8 @@ destroy_shell_surface(struct shell_surface *shsurf)
         shell_surface_is_top_fullscreen(shsurf))
         restore_output_mode (shsurf->fullscreen_output);
 
-    if (shsurf->fullscreen.black_surface)
-        weston_surface_destroy(shsurf->fullscreen.black_surface);
+    if (shsurf->fullscreen.black_view)
+        weston_surface_destroy(shsurf->fullscreen.black_view->surface);
 
     /* As destroy_resource() use wl_list_for_each_safe(),
      * we can always remove the listener.
@@ -2538,6 +3031,14 @@ destroy_shell_surface(struct shell_surface *shsurf)
     ping_timer_destroy(shsurf);
     free(shsurf->title);
 
+    weston_view_destroy(shsurf->view);
+
+    wl_list_remove(&shsurf->children_link);
+    wl_list_for_each_safe(child, next, &shsurf->children_list, children_link) {
+        wl_list_remove(&child->children_link);
+        child->parent = NULL;
+    }
+
     wl_list_remove(&shsurf->link);
     free(shsurf);
 }
@@ -2564,9 +3065,11 @@ shell_handle_surface_destroy(struct wl_listener *listener, void *data)
 }
 
 static void
-shell_surface_configure(struct weston_surface *, int32_t, int32_t, int32_t, int32_t);
+shell_surface_configure(struct weston_surface *, int32_t, int32_t);
+static void
+shell_surface_output_destroyed(struct weston_surface *);
 
-static struct shell_surface *
+struct shell_surface *
 get_shell_surface(struct weston_surface *surface)
 {
     if (surface->configure == shell_surface_configure)
@@ -2575,9 +3078,9 @@ get_shell_surface(struct weston_surface *surface)
         return NULL;
 }
 
-static  struct shell_surface *
-create_shell_surface(void *shell, struct weston_surface *surface,
-             const struct weston_shell_client *client)
+static struct shell_surface *
+create_common_surface(void *shell, struct weston_surface *surface,
+              const struct weston_shell_client *client)
 {
     struct shell_surface *shsurf;
 
@@ -2592,57 +3095,458 @@ create_shell_surface(void *shell, struct weston_surface *surface,
         return NULL;
     }
 
+    shsurf->view = weston_view_create(surface);
+    if (!shsurf->view) {
+        weston_log("no memory to allocate shell surface\n");
+        free(shsurf);
+        return NULL;
+    }
+
     surface->configure = shell_surface_configure;
     surface->configure_private = shsurf;
+    surface->output_destroyed = shell_surface_output_destroyed;
+
+    shsurf->shell = (struct desktop_shell *) shell;
+    shsurf->unresponsive = 0;
+    shsurf->saved_position_valid = false;
+    shsurf->saved_size_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_view = NULL;
+    shsurf->ping_timer = NULL;
+
+    /* set default color and shader because weston original bug(some time crash weston) */
+    weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
+
+    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);
+
+    wl_list_init(&shsurf->children_link);
+    wl_list_init(&shsurf->children_list);
+    shsurf->parent = NULL;
+
+    shsurf->type = SHELL_SURFACE_NONE;
+
+    shsurf->client = client;
+
+    return shsurf;
+}
+
+static struct shell_surface *
+create_shell_surface(void *shell, struct weston_surface *surface,
+             const struct weston_shell_client *client)
+{
+    return create_common_surface(shell, surface, client);
+}
+
+static struct weston_view *
+get_primary_view(void *shell, struct shell_surface *shsurf)
+{
+    return shsurf->view;
+}
+
+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;
+    }
+
+    /* if ico_window_mgr hook, call hook routine    */
+    shsurf->layertype = LAYER_TYPE_PANEL;
+    if (shell_hook_create)  {
+        (*shell_hook_create)(LAYER_TYPE_PANEL, surface, client, shsurf);
+    }
+
+    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);
+}
+
+static bool
+shell_surface_is_wl_shell_surface(struct shell_surface *shsurf)
+{
+    return wl_resource_instance_of(shsurf->resource,
+                       &wl_shell_surface_interface,
+                       &shell_surface_implementation);
+}
+
+static const struct wl_shell_interface shell_implementation = {
+    shell_get_shell_surface
+};
+
+/****************************
+ * xdg-shell implementation */
+
+static void
+xdg_surface_destroy(struct wl_client *client,
+            struct wl_resource *resource)
+{
+    wl_resource_destroy(resource);
+}
+
+static void
+xdg_surface_pong(struct wl_client *client,
+         struct wl_resource *resource,
+         uint32_t serial)
+{
+    struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+
+    surface_pong(shsurf, serial);
+}
+
+static void
+xdg_surface_set_app_id(struct wl_client *client,
+               struct wl_resource *resource,
+               const char *app_id)
+{
+    struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+
+    free(shsurf->class);
+    shsurf->class = strdup(app_id);
+}
+
+static void
+xdg_surface_set_title(struct wl_client *client,
+            struct wl_resource *resource, const char *title)
+{
+    struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+
+    set_title(shsurf, title);
+}
+
+static void
+xdg_surface_move(struct wl_client *client, struct wl_resource *resource,
+         struct wl_resource *seat_resource, uint32_t serial)
+{
+    common_surface_move(resource, seat_resource, serial);
+}
+
+static void
+xdg_surface_resize(struct wl_client *client, struct wl_resource *resource,
+           struct wl_resource *seat_resource, uint32_t serial,
+           uint32_t edges)
+{
+    common_surface_resize(resource, seat_resource, serial, edges);
+}
+
+static void
+xdg_surface_set_output(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_output *output;
+
+    if (output_resource)
+        output = wl_resource_get_user_data(output_resource);
+    else
+        output = NULL;
+
+    shsurf->recommended_output = output;
+}
+
+static void
+xdg_surface_set_fullscreen(struct wl_client *client,
+               struct wl_resource *resource)
+{
+    struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+
+    if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
+        return;
+
+    if (!shsurf->next_state.fullscreen)
+        set_fullscreen(shsurf,
+                   WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+                   0, shsurf->recommended_output);
+}
+
+static void
+xdg_surface_unset_fullscreen(struct wl_client *client,
+                 struct wl_resource *resource)
+{
+    struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+    int32_t width, height;
+
+    if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
+        return;
+
+    if (!shsurf->next_state.fullscreen)
+        return;
+
+    shsurf->next_state.fullscreen = false;
+    shsurf->state_changed = true;
+
+    if (shsurf->saved_size_valid) {
+        width = shsurf->saved_width;
+        height = shsurf->saved_height;
+        shsurf->saved_size_valid = false;
+    } else {
+        width = shsurf->surface->width;
+        height = shsurf->surface->height;
+    }
+
+    if (shell_hook_fullscreen)  {
+        (*shell_hook_fullscreen)(SHELL_FULLSCREEN_UNSET, shsurf->surface);
+    }
+
+    shsurf->client->send_configure(shsurf->surface, 0, width, height);
+}
+
+static void
+xdg_surface_set_maximized(struct wl_client *client,
+              struct wl_resource *resource)
+{
+    struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+
+    if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
+        return;
+
+    if (!shsurf->next_state.maximized)
+        set_maximized(shsurf, NULL);
+}
+
+static void
+xdg_surface_unset_maximized(struct wl_client *client,
+                struct wl_resource *resource)
+{
+    struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+    int32_t width, height;
+
+    if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
+        return;
+
+    if (!shsurf->next_state.maximized)
+        return;
+
+    shsurf->next_state.maximized = false;
+    shsurf->state_changed = true;
+
+    if (shsurf->saved_size_valid) {
+        width = shsurf->saved_width;
+        height = shsurf->saved_height;
+        shsurf->saved_size_valid = false;
+    } else {
+        width = shsurf->surface->width;
+        height = shsurf->surface->height;
+    }
+
+    shsurf->client->send_configure(shsurf->surface, 0, width, height);
+}
+
+static const struct xdg_surface_interface xdg_surface_implementation = {
+    xdg_surface_destroy,
+    xdg_surface_set_transient_for,
+    xdg_surface_set_title,
+    xdg_surface_set_app_id,
+    xdg_surface_pong,
+    xdg_surface_move,
+    xdg_surface_resize,
+    xdg_surface_set_output,
+    xdg_surface_set_fullscreen,
+    xdg_surface_unset_fullscreen,
+    xdg_surface_set_maximized,
+    xdg_surface_unset_maximized,
+    NULL /* set_minimized */
+};
+
+static void
+xdg_send_configure(struct weston_surface *surface,
+           uint32_t edges, int32_t width, int32_t height)
+{
+    struct shell_surface *shsurf = get_shell_surface(surface);
+
+    assert(shsurf);
+
+    xdg_surface_send_configure(shsurf->resource, edges, width, height);
+}
+
+static const struct weston_shell_client xdg_client = {
+    xdg_send_configure
+};
+
+static void
+xdg_use_unstable_version(struct wl_client *client,
+             struct wl_resource *resource,
+             int32_t version)
+{
+    if (version > 1) {
+        wl_resource_post_error(resource,
+                       1,
+                       "xdg-shell:: version not implemented yet.");
+        return;
+    }
+}
+
+static struct shell_surface *
+create_xdg_surface(void *shell, struct weston_surface *surface,
+           const struct weston_shell_client *client)
+{
+    struct shell_surface *shsurf;
+
+    shsurf = create_common_surface(shell, surface, client);
+    shsurf->type = SHELL_SURFACE_TOPLEVEL;
+
+    return shsurf;
+}
+
+static void
+xdg_get_xdg_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_xdg_surface(shell, surface, &xdg_client);
+    if (!shsurf) {
+        wl_resource_post_error(surface_resource,
+                       WL_DISPLAY_ERROR_INVALID_OBJECT,
+                       "surface->configure already set");
+        return;
+    }
+
+    /* if ico_window_mgr hook, call hook routine    */
+    shsurf->layertype = LAYER_TYPE_PANEL;
+    if (shell_hook_create)  {
+        (*shell_hook_create)(LAYER_TYPE_PANEL, surface, client, shsurf);
+    }
+
+    shsurf->resource =
+        wl_resource_create(client,
+                   &xdg_surface_interface, 1, id);
+    wl_resource_set_implementation(shsurf->resource,
+                       &xdg_surface_implementation,
+                       shsurf, shell_destroy_shell_surface);
+}
 
-    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;
+static bool
+shell_surface_is_xdg_surface(struct shell_surface *shsurf)
+{
+    return wl_resource_instance_of(shsurf->resource,
+                       &xdg_surface_interface,
+                       &xdg_surface_implementation);
+}
 
-    /* set default color and shader because weston original bug(some time crash weston) */
-    weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1);
+/* xdg-popup implementation */
 
-    wl_list_init(&shsurf->fullscreen.transform.link);
+static void
+xdg_popup_destroy(struct wl_client *client,
+          struct wl_resource *resource)
+{
+    wl_resource_destroy(resource);
+}
 
-    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);
+static void
+xdg_popup_pong(struct wl_client *client,
+           struct wl_resource *resource,
+           uint32_t serial)
+{
+    struct shell_surface *shsurf = wl_resource_get_user_data(resource);
 
-    /* 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);
+    surface_pong(shsurf, serial);
+}
 
-    /* empty when not in use */
-    wl_list_init(&shsurf->rotation.transform.link);
-    weston_matrix_init(&shsurf->rotation.rotation);
+static const struct xdg_popup_interface xdg_popup_implementation = {
+    xdg_popup_destroy,
+    xdg_popup_pong
+};
 
-    wl_list_init(&shsurf->workspace_transform.link);
+static void
+xdg_popup_send_configure(struct weston_surface *surface,
+             uint32_t edges, int32_t width, int32_t height)
+{
+}
 
-    shsurf->type = SHELL_SURFACE_NONE;
-    shsurf->next_type = SHELL_SURFACE_NONE;
+static const struct weston_shell_client xdg_popup_client = {
+    xdg_popup_send_configure
+};
 
-    shsurf->client = client;
+static struct shell_surface *
+create_xdg_popup(void *shell, struct weston_surface *surface,
+         const struct weston_shell_client *client,
+         struct weston_surface *parent,
+         struct shell_seat *seat,
+         uint32_t serial,
+         int32_t x, int32_t y)
+{
+    struct shell_surface *shsurf;
+
+    shsurf = create_common_surface(shell, surface, client);
+    shsurf->type = SHELL_SURFACE_POPUP;
+    shsurf->popup.shseat = seat;
+    shsurf->popup.serial = serial;
+    shsurf->popup.x = x;
+    shsurf->popup.y = y;
+    shell_surface_set_parent(shsurf, parent);
 
     return shsurf;
 }
 
 static void
-shell_get_shell_surface_layertype(int layertype, struct wl_client *client,
-                                  struct wl_resource *resource,
-                                  uint32_t id,
-                                  struct wl_resource *surface_resource)
+xdg_get_xdg_popup(struct wl_client *client,
+          struct wl_resource *resource,
+          uint32_t id,
+          struct wl_resource *surface_resource,
+          struct wl_resource *parent_resource,
+          struct wl_resource *seat_resource,
+          uint32_t serial,
+          int32_t x, int32_t y, uint32_t flags)
 {
     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;
+    struct weston_surface *parent;
+    struct shell_seat *seat;
 
     if (get_shell_surface(surface)) {
         wl_resource_post_error(surface_resource,
@@ -2651,41 +3555,91 @@ shell_get_shell_surface_layertype(int layertype, struct wl_client *client,
         return;
     }
 
-    shsurf = create_shell_surface(shell, surface, &shell_client);
+    if (!parent_resource) {
+        wl_resource_post_error(surface_resource,
+                       WL_DISPLAY_ERROR_INVALID_OBJECT,
+                       "xdg_shell::get_xdg_popup requires a parent shell surface");
+    }
+
+    parent = wl_resource_get_user_data(parent_resource);
+    seat = get_shell_seat(wl_resource_get_user_data(seat_resource));;
+
+    shsurf = create_xdg_popup(shell, surface, &xdg_popup_client,
+                  parent, seat, serial, x, y);
     if (!shsurf) {
         wl_resource_post_error(surface_resource,
                        WL_DISPLAY_ERROR_INVALID_OBJECT,
                        "surface->configure already set");
         return;
     }
-    shsurf->layertype = layertype;
-    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    */
+    shsurf->layertype = LAYER_TYPE_PANEL;
     if (shell_hook_create)  {
-        (*shell_hook_create)(layertype, client, resource, surface, shsurf);
+        (*shell_hook_create)(LAYER_TYPE_PANEL, surface, client, shsurf);
     }
+
+    shsurf->resource =
+        wl_resource_create(client,
+                   &xdg_popup_interface, 1, id);
+    wl_resource_set_implementation(shsurf->resource,
+                       &xdg_popup_implementation,
+                       shsurf, shell_destroy_shell_surface);
 }
 
-static void
-shell_get_shell_surface(struct wl_client *client,
-            struct wl_resource *resource,
-            uint32_t id,
-            struct wl_resource *surface_resource)
+static bool
+shell_surface_is_xdg_popup(struct shell_surface *shsurf)
 {
-    shell_get_shell_surface_layertype(LAYER_TYPE_PANEL,
-                                      client, resource, id, surface_resource);
+    return wl_resource_instance_of(shsurf->resource,
+                       &xdg_popup_interface,
+                       &xdg_popup_implementation);
 }
 
-static const struct wl_shell_interface shell_implementation = {
-    shell_get_shell_surface
+static const struct xdg_shell_interface xdg_implementation = {
+    xdg_use_unstable_version,
+    xdg_get_xdg_surface,
+    xdg_get_xdg_popup
 };
 
+static int
+xdg_shell_unversioned_dispatch(const void *implementation,
+                   void *_target, uint32_t opcode,
+                   const struct wl_message *message,
+                   union wl_argument *args)
+{
+    struct wl_resource *resource = _target;
+    struct desktop_shell *shell = wl_resource_get_user_data(resource);
+
+    if (opcode != 0) {
+        wl_resource_post_error(resource,
+                       WL_DISPLAY_ERROR_INVALID_OBJECT,
+                       "must call use_unstable_version first");
+        return 0;
+    }
+
+#define XDG_SERVER_VERSION 1
+
+    static_assert(XDG_SERVER_VERSION == XDG_SHELL_VERSION_CURRENT,
+              "shell implementation doesn't match protocol version");
+
+    if (args[0].i != XDG_SERVER_VERSION) {
+        wl_resource_post_error(resource,
+                       WL_DISPLAY_ERROR_INVALID_OBJECT,
+                       "incompatible version, server is %d "
+                       "client wants %d",
+                       XDG_SERVER_VERSION, args[0].i);
+        return 0;
+    }
+
+    wl_resource_set_implementation(resource, &xdg_implementation,
+                       shell, NULL);
+
+    return 1;
+}
+
+/* end of xdg-shell implementation */
+/***********************************/
+
 static void
 shell_fade(struct desktop_shell *shell, enum fade_type type);
 
@@ -2727,7 +3681,6 @@ launch_screensaver(struct desktop_shell *shell)
         return;
     }
 
-    uifw_trace("launch_screensaver: launch %s", shell->screensaver.path);
     weston_client_launch(shell->compositor,
                &shell->screensaver.process,
                shell->screensaver.path,
@@ -2744,41 +3697,39 @@ terminate_screensaver(struct desktop_shell *shell)
 }
 
 static void
-configure_static_surface(struct weston_surface *es, struct weston_layer *layer, int32_t width, int32_t height)
+configure_static_view(struct weston_view *ev, struct weston_layer *layer)
 {
-    struct weston_surface *s, *next;
-
-    if (width == 0)
-        return;
+    struct weston_view *v, *next;
 
-    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;
+    wl_list_for_each_safe(v, next, &layer->view_list, layer_link) {
+        if (v->output == ev->output && v != ev) {
+            weston_view_unmap(v);
+            v->surface->configure = NULL;
         }
     }
 
-    uifw_debug("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);
+    weston_view_set_position(ev, ev->output->x, ev->output->y);
 
-    if (wl_list_empty(&es->layer_link)) {
-        wl_list_insert(&layer->surface_list, &es->layer_link);
-        weston_compositor_schedule_repaint(es->compositor);
+    if (wl_list_empty(&ev->layer_link)) {
+        wl_list_insert(&layer->view_list, &ev->layer_link);
+        weston_compositor_schedule_repaint(ev->surface->compositor);
     }
 
     /* if ico_window_mgr hook, call hook routine    */
     if (shell_hook_configure)  {
-        (*shell_hook_configure)(es);
+        (*shell_hook_configure)(ev->surface);
     }
 }
 
 static void
-background_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
+background_configure(struct weston_surface *es, int32_t sx, int32_t sy)
 {
     struct desktop_shell *shell = es->configure_private;
+    struct weston_view *view;
+
+    view = container_of(es->views.next, struct weston_view, surface_link);
 
-    configure_static_surface(es, &shell->background_layer, width, height);
+    configure_static_view(view, &shell->background_layer);
 }
 
 static void
@@ -2790,6 +3741,7 @@ desktop_shell_set_background(struct wl_client *client,
     struct desktop_shell *shell = wl_resource_get_user_data(resource);
     struct weston_surface *surface =
         wl_resource_get_user_data(surface_resource);
+    struct weston_view *view, *next;
 
     if (surface->configure) {
         wl_resource_post_error(surface_resource,
@@ -2798,11 +3750,14 @@ desktop_shell_set_background(struct wl_client *client,
         return;
     }
 
+    wl_list_for_each_safe(view, next, &surface->views, surface_link)
+        weston_view_destroy(view);
+    view = weston_view_create(surface);
+
     surface->configure = background_configure;
     surface->configure_private = shell;
     surface->output = wl_resource_get_user_data(output_resource);
-    uifw_debug("desktop_shell_set_background: send %08x 0 w/h=%d/%d",
-               (int)surface, surface->output->width, surface->output->height);
+    view->output = surface->output;
     desktop_shell_send_configure(resource, 0,
                      surface_resource,
                      surface->output->width,
@@ -2810,11 +3765,14 @@ desktop_shell_set_background(struct wl_client *client,
 }
 
 static void
-panel_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
+panel_configure(struct weston_surface *es, int32_t sx, int32_t sy)
 {
     struct desktop_shell *shell = es->configure_private;
+    struct weston_view *view;
+
+    view = container_of(es->views.next, struct weston_view, surface_link);
 
-    configure_static_surface(es, &shell->panel_layer, width, height);
+    configure_static_view(view, &shell->panel_layer);
 }
 
 static void
@@ -2826,6 +3784,7 @@ desktop_shell_set_panel(struct wl_client *client,
     struct desktop_shell *shell = wl_resource_get_user_data(resource);
     struct weston_surface *surface =
         wl_resource_get_user_data(surface_resource);
+    struct weston_view *view, *next;
 
     if (surface->configure) {
         wl_resource_post_error(surface_resource,
@@ -2834,11 +3793,14 @@ desktop_shell_set_panel(struct wl_client *client,
         return;
     }
 
+    wl_list_for_each_safe(view, next, &surface->views, surface_link)
+        weston_view_destroy(view);
+    view = weston_view_create(surface);
+
     surface->configure = panel_configure;
     surface->configure_private = shell;
     surface->output = wl_resource_get_user_data(output_resource);
-    uifw_debug("desktop_shell_set_panel: send %08x 0 w/h=%d/%d",
-               (int)surface, surface->output->width, surface->output->height);
+    view->output = surface->output;
     desktop_shell_send_configure(resource, 0,
                      surface_resource,
                      surface->output->width,
@@ -2846,22 +3808,22 @@ desktop_shell_set_panel(struct wl_client *client,
 }
 
 static void
-lock_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
+lock_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
 {
     struct desktop_shell *shell = surface->configure_private;
+    struct weston_view *view;
+
+    view = container_of(surface->views.next, struct weston_view, surface_link);
 
-    if (width == 0)
+    if (surface->width == 0)
         return;
 
-    uifw_debug("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));
+    center_on_output(view, 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);
+        wl_list_insert(&shell->lock_layer.view_list,
+                   &view->layer_link);
+        weston_view_update_transform(view);
         shell_fade(shell, FADE_IN);
     }
 }
@@ -2896,6 +3858,7 @@ desktop_shell_set_lock_surface(struct wl_client *client,
     wl_signal_add(&surface->destroy_signal,
               &shell->lock_surface_listener);
 
+    weston_view_create(surface);
     surface->configure = lock_surface_configure;
     surface->configure_private = shell;
 }
@@ -2912,8 +3875,7 @@ resume_desktop(struct desktop_shell *shell)
                &shell->fullscreen_layer.link);
     wl_list_insert(&shell->fullscreen_layer.link,
                &shell->panel_layer.link);
-    if ((! shell_hook_configure) &&
-        (shell->showing_input_panels)) {
+    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,
@@ -2949,6 +3911,7 @@ desktop_shell_set_grab_surface(struct wl_client *client,
     struct desktop_shell *shell = wl_resource_get_user_data(resource);
 
     shell->grab_surface = wl_resource_get_user_data(surface_resource);
+    weston_view_create(shell->grab_surface);
 }
 
 static void
@@ -2983,28 +3946,79 @@ get_shell_surface_type(struct weston_surface *surface)
 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 *focus;
     struct weston_surface *surface;
     struct shell_surface *shsurf;
 
+    if (seat->pointer->focus == NULL)
+        return;
+
+    focus = seat->pointer->focus->surface;
+
     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)
+    if (shsurf == NULL || shsurf->state.fullscreen ||
+        shsurf->state.maximized)
         return;
 
     surface_move(shsurf, (struct weston_seat *) seat);
 }
 
 static void
+maximize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
+{
+    struct weston_surface *focus = seat->pointer->focus->surface;
+    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)
+        return;
+
+    if (!shell_surface_is_xdg_surface(shsurf))
+        return;
+
+    if (shsurf->state.maximized)
+        xdg_surface_send_request_unset_maximized(shsurf->resource);
+    else
+        xdg_surface_send_request_set_maximized(shsurf->resource);
+}
+
+static void
+fullscreen_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
+{
+    struct weston_surface *focus = seat->pointer->focus->surface;
+    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)
+        return;
+
+    if (!shell_surface_is_xdg_surface(shsurf))
+        return;
+
+    if (shsurf->state.fullscreen)
+        xdg_surface_send_request_unset_fullscreen(shsurf->resource);
+    else
+        xdg_surface_send_request_set_fullscreen(shsurf->resource);
+}
+
+static void
 touch_move_binding(struct weston_seat *seat, uint32_t time, void *data)
 {
-    struct weston_surface *focus =
-        (struct weston_surface *) seat->touch->focus;
+    struct weston_surface *focus = seat->touch->focus->surface;
     struct weston_surface *surface;
     struct shell_surface *shsurf;
 
@@ -3013,8 +4027,8 @@ touch_move_binding(struct weston_seat *seat, uint32_t time, void *data)
         return;
 
     shsurf = get_shell_surface(surface);
-    if (shsurf == NULL || shsurf->type == SHELL_SURFACE_FULLSCREEN ||
-        shsurf->type == SHELL_SURFACE_MAXIMIZED)
+    if (shsurf == NULL || shsurf->state.fullscreen ||
+        shsurf->state.maximized)
         return;
 
     surface_touch_move(shsurf, (struct weston_seat *) seat);
@@ -3023,37 +4037,41 @@ touch_move_binding(struct weston_seat *seat, uint32_t time, void *data)
 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 *focus;
     struct weston_surface *surface;
     uint32_t edges = 0;
     int32_t x, y;
     struct shell_surface *shsurf;
 
+    if (seat->pointer->focus == NULL)
+        return;
+
+    focus = seat->pointer->focus->surface;
+
     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)
+    if (shsurf == NULL || shsurf->state.fullscreen ||
+        shsurf->state.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);
+    weston_view_from_global(shsurf->view,
+                wl_fixed_to_int(seat->pointer->grab_x),
+                wl_fixed_to_int(seat->pointer->grab_y),
+                &x, &y);
 
-    if (x < surface->geometry.width / 3)
+    if (x < shsurf->surface->width / 3)
         edges |= WL_SHELL_SURFACE_RESIZE_LEFT;
-    else if (x < 2 * surface->geometry.width / 3)
+    else if (x < 2 * shsurf->surface->width / 3)
         edges |= 0;
     else
         edges |= WL_SHELL_SURFACE_RESIZE_RIGHT;
 
-    if (y < surface->geometry.height / 3)
+    if (y < shsurf->surface->height / 3)
         edges |= WL_SHELL_SURFACE_RESIZE_TOP;
-    else if (y < 2 * surface->geometry.height / 3)
+    else if (y < 2 * shsurf->surface->height / 3)
         edges |= 0;
     else
         edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM;
@@ -3067,8 +4085,7 @@ surface_opacity_binding(struct weston_seat *seat, uint32_t time, uint32_t axis,
 {
     float step = 0.005;
     struct shell_surface *shsurf;
-    struct weston_surface *focus =
-        (struct weston_surface *) seat->pointer->focus;
+    struct weston_surface *focus = seat->pointer->focus->surface;
     struct weston_surface *surface;
 
     /* XXX: broken for windows containing sub-surfaces */
@@ -3080,14 +4097,14 @@ surface_opacity_binding(struct weston_seat *seat, uint32_t time, uint32_t axis,
     if (!shsurf)
         return;
 
-    surface->alpha -= wl_fixed_to_double(value) * step;
+    shsurf->view->alpha -= wl_fixed_to_double(value) * step;
 
-    if (surface->alpha > 1.0)
-        surface->alpha = 1.0;
-    if (surface->alpha < step)
-        surface->alpha = step;
+    if (shsurf->view->alpha > 1.0)
+        shsurf->view->alpha = 1.0;
+    if (shsurf->view->alpha < step)
+        shsurf->view->alpha = step;
 
-    weston_surface_geometry_dirty(surface);
+    weston_view_geometry_dirty(shsurf->view);
     weston_surface_damage(surface);
 }
 
@@ -3123,13 +4140,12 @@ do_zoom(struct weston_seat *seat, uint32_t time, uint32_t key, uint32_t axis,
             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++;
+                weston_output_activate_zoom(output);
             }
 
             output->zoom.spring_z.target = output->zoom.level;
 
-            weston_output_update_zoom(output, output->zoom.type);
+            weston_output_update_zoom(output);
         }
     }
 }
@@ -3158,29 +4174,29 @@ terminate_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
 }
 
 static void
-rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
+rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
+           wl_fixed_t x, wl_fixed_t y)
 {
     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;
 
+    weston_pointer_move(pointer, x, y);
+
     if (!shsurf)
         return;
 
-    surface = shsurf->surface;
-
-    cx = 0.5f * surface->geometry.width;
-    cy = 0.5f * surface->geometry.height;
+    cx = 0.5f * shsurf->surface->width;
+    cy = 0.5f * shsurf->surface->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);
+    weston_view_geometry_dirty(shsurf->view);
 
     if (r > 20.0f) {
         struct weston_matrix *matrix =
@@ -3196,7 +4212,7 @@ rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
         weston_matrix_translate(matrix, cx, cy, 0.0f);
 
         wl_list_insert(
-            &shsurf->surface->geometry.transformation_list,
+            &shsurf->view->geometry.transformation_list,
             &shsurf->rotation.transform.link);
     } else {
         wl_list_init(&shsurf->rotation.transform.link);
@@ -3206,14 +4222,14 @@ rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
 
     /* 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;
+    cposx = shsurf->view->geometry.x + cx;
+    cposy = shsurf->view->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);
+        weston_view_set_position(shsurf->view,
+                     shsurf->view->geometry.x + dposx,
+                     shsurf->view->geometry.y + dposy);
     }
 
     /* Repaint implies weston_surface_update_transform(), which
@@ -3270,10 +4286,10 @@ surface_rotate(struct shell_surface *surface, struct weston_seat *seat)
     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);
+    weston_view_to_global_float(surface->view,
+                    surface->surface->width * 0.5f,
+                    surface->surface->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;
@@ -3300,48 +4316,61 @@ 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 *focus;
     struct weston_surface *base_surface;
     struct shell_surface *surface;
 
+    if (seat->pointer->focus == NULL)
+        return;
+
+    focus = seat->pointer->focus->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)
+    if (surface == NULL || surface->state.fullscreen ||
+        surface->state.maximized)
         return;
 
     surface_rotate(surface, seat);
 }
 
-static void
+/* Move all fullscreen layers down to the current workspace in a non-reversible
+ * manner. This should be used when implementing shell-wide overlays, such as
+ * the alt-tab switcher, which need to de-promote fullscreen layers. */
+void
 lower_fullscreen_layer(struct desktop_shell *shell)
 {
+    struct workspace *ws;
+    struct weston_view *view, *prev;
+
     if (shell_hook_fullscreen)  {
         (*shell_hook_fullscreen)(SHELL_FULLSCREEN_HIDEALL, NULL);
         return;
     }
 
-    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);
+    wl_list_for_each_reverse_safe(view, prev,
+                      &shell->fullscreen_layer.view_list,
+                      layer_link) {
+        wl_list_remove(&view->layer_link);
+        wl_list_insert(&ws->layer.view_list, &view->layer_link);
+        weston_view_damage_below(view);
+        weston_surface_damage(view->surface);
+    }
 }
 
-static void
+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;
+    struct weston_surface *old_es;
+    struct shell_surface *shsurf;
 
     main_surface = weston_surface_get_main_surface(es);
 
@@ -3351,32 +4380,35 @@ activate(struct desktop_shell *shell, struct weston_surface *es,
     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);
+    old_es = state->keyboard_focus;
+    focus_state_set_focus(state, es);
+
+    shsurf = get_shell_surface(main_surface);
+    assert(shsurf);
 
     /* if ico_window_mgr hook, not change surface stack */
     if (shell_hook_select)  {
         return;
     }
 
-    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:
+    if (shsurf->state.fullscreen)
+        shell_configure_fullscreen(shsurf);
+    else
         restore_all_output_modes(shell->compositor);
+
+    if (shell->focus_animation_type != ANIMATION_NONE) {
         ws = get_current_workspace(shell);
-        weston_surface_restack(main_surface, &ws->layer.surface_list);
-        break;
+        animate_focus_change(shell, ws, get_default_view(old_es), get_default_view(es));
     }
+
+    /* Update the surface’s layer. This brings it to the top of the stacking
+     * order as appropriate. */
+    shell_surface_update_layer(shsurf);
 }
 
 /* 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)
+black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
 {
 }
 
@@ -3422,9 +4454,10 @@ click_to_activate_binding(struct weston_seat *seat, uint32_t time, uint32_t butt
 {
     if (seat->pointer->grab != &seat->pointer->default_grab)
         return;
+    if (seat->pointer->focus == NULL)
+        return;
 
-    activate_binding(seat, data,
-             (struct weston_surface *) seat->pointer->focus);
+    activate_binding(seat, data, seat->pointer->focus->surface);
 }
 
 static void
@@ -3432,9 +4465,10 @@ touch_to_activate_binding(struct weston_seat *seat, uint32_t time, void *data)
 {
     if (seat->touch->grab != &seat->touch->default_grab)
         return;
+    if (seat->touch->focus == NULL)
+        return;
 
-    activate_binding(seat, data,
-             (struct weston_surface *) seat->touch->focus);
+    activate_binding(seat, data, seat->touch->focus->surface);
 }
 
 static void
@@ -3455,8 +4489,7 @@ lock(struct desktop_shell *shell)
 
     wl_list_remove(&shell->panel_layer.link);
     wl_list_remove(&shell->fullscreen_layer.link);
-    if ((! shell_hook_configure) &&
-        (shell->showing_input_panels))
+    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,
@@ -3491,7 +4524,7 @@ unlock(struct desktop_shell *shell)
 }
 
 static void
-shell_fade_done(struct weston_surface_animation *animation, void *data)
+shell_fade_done(struct weston_view_animation *animation, void *data)
 {
     struct desktop_shell *shell = data;
 
@@ -3499,34 +4532,42 @@ shell_fade_done(struct weston_surface_animation *animation, void *data)
 
     switch (shell->fade.type) {
     case FADE_IN:
-        weston_surface_destroy(shell->fade.surface);
-        shell->fade.surface = NULL;
+        weston_surface_destroy(shell->fade.view->surface);
+        shell->fade.view = NULL;
         break;
     case FADE_OUT:
         lock(shell);
         break;
+    default:
+        break;
     }
 }
 
-static struct weston_surface *
+static struct weston_view *
 shell_fade_create_surface(struct desktop_shell *shell)
 {
     struct weston_compositor *compositor = shell->compositor;
     struct weston_surface *surface;
+    struct weston_view *view;
 
     surface = weston_surface_create(compositor);
     if (!surface)
         return NULL;
 
-    uifw_debug("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);
+    view = weston_view_create(surface);
+    if (!view) {
+        weston_surface_destroy(surface);
+        return NULL;
+    }
+
+    weston_surface_set_size(surface, 8192, 8192);
+    weston_view_set_position(view, 0, 0);
     weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
-    wl_list_insert(&compositor->fade_layer.surface_list,
-               &surface->layer_link);
+    wl_list_insert(&compositor->fade_layer.view_list,
+               &view->layer_link);
     pixman_region32_init(&surface->input);
 
-    return surface;
+    return view;
 }
 
 static void
@@ -3548,22 +4589,31 @@ shell_fade(struct desktop_shell *shell, enum fade_type type)
 
     shell->fade.type = type;
 
-    if (shell->fade.surface == NULL) {
-        shell->fade.surface = shell_fade_create_surface(shell);
-        if (!shell->fade.surface)
+    if (shell->fade.view == NULL) {
+        shell->fade.view = shell_fade_create_surface(shell);
+        if (!shell->fade.view)
             return;
 
-        shell->fade.surface->alpha = 1.0 - tint;
-        weston_surface_update_transform(shell->fade.surface);
+        shell->fade.view->alpha = 1.0 - tint;
+        weston_view_update_transform(shell->fade.view);
     }
 
-    if (shell->fade.animation)
+    if (shell->fade.view->output == NULL) {
+        /* If the black view gets a NULL output, we lost the
+         * last output and we'll just cancel the fade.  This
+         * happens when you close the last window under the
+         * X11 or Wayland backends. */
+        shell->locked = false;
+        weston_surface_destroy(shell->fade.view->surface);
+        shell->fade.view = NULL;
+    } else if (shell->fade.animation) {
         weston_fade_update(shell->fade.animation, tint);
-    else
+    } else {
         shell->fade.animation =
-            weston_fade_run(shell->fade.surface,
+            weston_fade_run(shell->fade.view,
                     1.0 - tint, tint, 300.0,
                     shell_fade_done, shell);
+    }
 }
 
 static void
@@ -3574,8 +4624,8 @@ do_shell_fade_startup(void *data)
     if (shell->startup_animation_type == ANIMATION_FADE)
         shell_fade(shell, FADE_IN);
     else if (shell->startup_animation_type == ANIMATION_NONE) {
-        weston_surface_destroy(shell->fade.surface);
-        shell->fade.surface = NULL;
+        weston_surface_destroy(shell->fade.view->surface);
+        shell->fade.view = NULL;
     }
 }
 
@@ -3613,18 +4663,18 @@ shell_fade_init(struct desktop_shell *shell)
 
     struct wl_event_loop *loop;
 
-    if (shell->fade.surface != NULL) {
+    if (shell->fade.view != NULL) {
         weston_log("%s: warning: fade surface already exists\n",
                __func__);
         return;
     }
 
-    shell->fade.surface = shell_fade_create_surface(shell);
-    if (!shell->fade.surface)
+    shell->fade.view = shell_fade_create_surface(shell);
+    if (!shell->fade.view)
         return;
 
-    weston_surface_update_transform(shell->fade.surface);
-    weston_surface_damage(shell->fade.surface);
+    weston_view_update_transform(shell->fade.view);
+    weston_surface_damage(shell->fade.view->surface);
 
     loop = wl_display_get_event_loop(shell->compositor->wl_display);
     shell->fade.startup_timer =
@@ -3637,6 +4687,11 @@ idle_handler(struct wl_listener *listener, void *data)
 {
     struct desktop_shell *shell =
         container_of(listener, struct desktop_shell, idle_listener);
+    struct weston_seat *seat;
+
+    wl_list_for_each(seat, &shell->compositor->seat_list, link)
+        if (seat->pointer)
+            popup_grab_end(seat->pointer);
 
     shell_fade(shell, FADE_OUT);
     /* lock() is called from shell_fade_done() */
@@ -3652,106 +4707,22 @@ wake_handler(struct wl_listener *listener, void *data)
 }
 
 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;
-
-    uifw_debug("show_input_panels: input.surface=%08x", (int)shell->text_input.surface);
-
-    shell->showing_input_panels = true;
-
-    /* if ico_window_mgr hook, call hook routine    */
-    if (shell_hook_show_layer)  {
-        (*shell_hook_show_layer)(LAYER_TYPE_INPUTPANEL, 1, data);
-        return;
-    }
-    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;
-        if (! shell_hook_configure) {
-            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;
-
-    uifw_debug("hide_input_panels: input.surface=%08x", (int)shell->text_input.surface);
-
-    shell->showing_input_panels = false;
-
-    /* if ico_window_mgr hook, call hook routine    */
-    if (shell_hook_show_layer)  {
-        (*shell_hook_show_layer)(LAYER_TYPE_INPUTPANEL, 0, NULL);
-        return;
-    }
-
-    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)
+center_on_output(struct weston_view *view, 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);
+    surface_subsurfaces_boundingbox(view->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_debug("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);
+    weston_view_set_position(view, x, y);
 }
 
 static void
-weston_surface_set_initial_position (struct weston_surface *surface,
-                     struct desktop_shell *shell)
+weston_view_set_initial_position(struct weston_view *view,
+                 struct desktop_shell *shell)
 {
     struct weston_compositor *compositor = shell->compositor;
     int ix = 0, iy = 0;
@@ -3781,9 +4752,8 @@ weston_surface_set_initial_position (struct weston_surface *surface,
     }
 
     if (!target_output) {
-        weston_surface_set_position(surface, 10 + random() % 400,
-                       10 + random() % 400);
-        uifw_debug("weston_surface_set_initial_position: no tagret");
+        weston_view_set_position(view, 10 + random() % 400,
+                     10 + random() % 400);
         return;
     }
 
@@ -3792,140 +4762,119 @@ weston_surface_set_initial_position (struct weston_surface *surface,
      * output.
      */
     panel_height = get_output_panel_height(shell, target_output);
-    range_x = target_output->width - surface->geometry.width;
+    range_x = target_output->width - view->surface->width;
     range_y = (target_output->height - panel_height) -
-          surface->geometry.height;
+          view->surface->height;
 
-    if (range_x > 0)    {
+    if (range_x > 0)
         dx = random() % range_x;
-    }
-    else    {
+    else
         dx = 0;
-    }
-    if (range_y > 0)    {
+
+    if (range_y > 0)
         dy = panel_height + random() % range_y;
-    }
-    else    {
+    else
         dy = panel_height;
-    }
+
     x = target_output->x + dx;
     y = target_output->y + dy;
 
-    weston_surface_set_position (surface, x, y);
+    weston_view_set_position(view, 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)
+map(struct desktop_shell *shell, struct shell_surface *shsurf,
+    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 type=%d",
-               (int)surface, sx, sy, width, height, (int)surface_type);
-
-    surface->geometry.width = width;
-    surface->geometry.height = height;
-    weston_surface_geometry_dirty(surface);
-
     /* initial positioning, see also configure() */
-
-    switch (surface_type) {
+    switch (shsurf->type) {
     case SHELL_SURFACE_TOPLEVEL:
-        uifw_debug("map: surface TOPLEVEL");
-        weston_surface_set_initial_position(surface, shell);
-        break;
-    case SHELL_SURFACE_FULLSCREEN:
-        uifw_debug("map: surface FULLSCREEN");
-        center_on_output(surface, shsurf->fullscreen_output);
-        shell_map_fullscreen(shsurf);
-        break;
-    case SHELL_SURFACE_MAXIMIZED:
-        uifw_debug("map: 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);
+        if (shsurf->state.fullscreen) {
+            center_on_output(shsurf->view, shsurf->fullscreen_output);
+            shell_map_fullscreen(shsurf);
+        } else if (shsurf->state.maximized) {
+            /* use surface configure to set the geometry */
+            panel_height = get_output_panel_height(shell, shsurf->output);
+            surface_subsurfaces_boundingbox(shsurf->surface,
+                            &surf_x, &surf_y, NULL, NULL);
+            weston_view_set_position(shsurf->view,
+                         shsurf->output->x - surf_x,
+                         shsurf->output->y +
+                         panel_height - surf_y);
+        } else if (!shsurf->state.relative) {
+            weston_view_set_initial_position(shsurf->view, shell);
+        }
         break;
     case SHELL_SURFACE_POPUP:
-        uifw_debug("map: surface POPUP");
         shell_map_popup(shsurf);
         break;
     case SHELL_SURFACE_NONE:
-        uifw_debug("map: surface NONE");
         if (shsurf->layertype == LAYER_TYPE_INPUTPANEL) {
-            weston_surface_set_initial_position(surface, shell);
+            weston_view_set_initial_position(shsurf->view, shell);
         }
         else    {
-            weston_surface_set_position(surface,
-                            surface->geometry.x + sx,
-                            surface->geometry.y + sy);
+            weston_view_set_position(shsurf->view,
+                         shsurf->view->geometry.x + sx,
+                         shsurf->view->geometry.y + sy);
         }
         break;
+    case SHELL_SURFACE_XWAYLAND:
     default:
-        uifw_debug("map: surface unknown type(%d)", surface_type);
         ;
     }
-
-    /* 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;
+
+    /* Surface stacking order, see also activate(). */
+    shell_surface_update_layer(shsurf);
+
+    if (shsurf->type != SHELL_SURFACE_NONE) {
+        weston_view_update_transform(shsurf->view);
+        if (shsurf->state.maximized) {
+            shsurf->surface->output = shsurf->output;
+            shsurf->view->output = shsurf->output;
+        }
     }
 
-    if (surface_type != SHELL_SURFACE_NONE) {
-        weston_surface_update_transform(surface);
-        if (surface_type == SHELL_SURFACE_MAXIMIZED)
-            surface->output = shsurf->output;
+    if ((shsurf->type == SHELL_SURFACE_XWAYLAND || shsurf->state.relative) &&
+        shsurf->transient.flags == WL_SHELL_SURFACE_TRANSIENT_INACTIVE) {
     }
 
-    switch (surface_type) {
+    switch (shsurf->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);
-        }
+        if (shsurf->state.relative &&
+            shsurf->transient.flags == WL_SHELL_SURFACE_TRANSIENT_INACTIVE)
+            break;
+        if (shell->locked)
+            break;
+        wl_list_for_each(seat, &compositor->seat_list, link)
+            activate(shell, shsurf->surface, seat);
         break;
+    case SHELL_SURFACE_POPUP:
+    case SHELL_SURFACE_NONE:
     default:
         break;
     }
 
-    if (surface_type == SHELL_SURFACE_TOPLEVEL)
+    if (shsurf->type == SHELL_SURFACE_TOPLEVEL &&
+        !shsurf->state.maximized && !shsurf->state.fullscreen)
     {
         switch (shell->win_animation_type) {
         case ANIMATION_FADE:
-            weston_fade_run(surface, 0.0, 1.0, 300.0, NULL, NULL);
+            weston_fade_run(shsurf->view, 0.0, 1.0, 300.0, NULL, NULL);
             break;
         case ANIMATION_ZOOM:
-            weston_zoom_run(surface, 0.5, 1.0, NULL, NULL);
+            weston_zoom_run(shsurf->view, 0.5, 1.0, NULL, NULL);
             break;
+        case ANIMATION_NONE:
         default:
             break;
         }
@@ -3933,55 +4882,48 @@ map(struct desktop_shell *shell, struct weston_surface *surface,
 
     /* if ico_window_mgr hook, call hook routine    */
     if (shell_hook_map)  {
-        sx = surface->geometry.x;
-        sy = surface->geometry.y;
-        (*shell_hook_map)(surface, &width, &height, &sx, &sy);
+        sx = shsurf->view->geometry.x;
+        sy = shsurf->view->geometry.y;
+        (*shell_hook_map)(shsurf->surface,
+                          &shsurf->surface->width, &shsurf->surface->height, &sx, &sy);
     }
     if (shell_hook_configure)  {
-        (*shell_hook_configure)(surface);           /* send event to manager    */
+        (*shell_hook_configure)(shsurf->surface);   /* 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)
+      float x, float y)
 {
-    enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
     struct shell_surface *shsurf;
-    int32_t surf_x, surf_y;
+    struct weston_view *view;
+    int32_t mx, my, 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);
+    assert(shsurf);
 
-    switch (surface_type) {
-    case SHELL_SURFACE_FULLSCREEN:
-        shell_stack_fullscreen(shsurf);
+    if (shsurf->state.fullscreen)
         shell_configure_fullscreen(shsurf);
-        break;
-    case SHELL_SURFACE_MAXIMIZED:
+    else if (shsurf->state.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;
+        mx = shsurf->output->x - surf_x;
+        my = shsurf->output->y +
+             get_output_panel_height(shell,shsurf->output) - surf_y;
+        weston_view_set_position(shsurf->view, mx, my);
+    } else {
+        weston_view_set_position(shsurf->view, x, y);
     }
 
     /* XXX: would a fullscreen surface need the same handling? */
     if (surface->output) {
-        weston_surface_update_transform(surface);
+        wl_list_for_each(view, &surface->views, surface_link)
+            weston_view_update_transform(view);
 
-        if (surface_type == SHELL_SURFACE_MAXIMIZED)
+        if (shsurf->state.maximized)
             surface->output = shsurf->output;
     }
 
@@ -3992,47 +4934,60 @@ configure(struct desktop_shell *shell, struct weston_surface *surface,
 }
 
 static void
-shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
+shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
 {
     struct shell_surface *shsurf = get_shell_surface(es);
-    struct desktop_shell *shell = shsurf->shell;
-
+    struct desktop_shell *shell;
     int type_changed = 0;
 
+    assert(shsurf);
+
+    shell = shsurf->shell;
+
     if (!weston_surface_is_mapped(es) &&
         !wl_list_empty(&shsurf->popup.grab_link)) {
         remove_popup_grab(shsurf);
     }
 
-    if (width == 0)
+    if (es->width == 0)
         return;
 
-    if (shsurf->next_type != SHELL_SURFACE_NONE &&
-        shsurf->type != shsurf->next_type) {
+    if (shsurf->state_changed) {
         set_surface_type(shsurf);
         type_changed = 1;
     }
 
     if (!weston_surface_is_mapped(es)) {
-        map(shell, es, width, height, sx, sy);
+        map(shell, shsurf, sx, sy);
     } else if (type_changed || sx != 0 || sy != 0 ||
-           es->geometry.width != width ||
-           es->geometry.height != height) {
+           shsurf->last_width != es->width ||
+           shsurf->last_height != es->height) {
+        shsurf->last_width = es->width;
+        shsurf->last_height = es->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);
+        weston_view_to_global_float(shsurf->view, 0, 0, &from_x, &from_y);
+        weston_view_to_global_float(shsurf->view, sx, sy, &to_x, &to_y);
         configure(shell, es,
-              es->geometry.x + to_x - from_x,
-              es->geometry.y + to_y - from_y,
-              width, height);
+              shsurf->view->geometry.x + to_x - from_x,
+              shsurf->view->geometry.y + to_y - from_y);
     }
 }
 
+static void
+shell_surface_output_destroyed(struct weston_surface *es)
+{
+    struct shell_surface *shsurf = get_shell_surface(es);
+
+    assert(shsurf);
+
+    shsurf->saved_position_valid = false;
+    shsurf->next_state.maximized = false;
+    shsurf->next_state.fullscreen = false;
+    shsurf->state_changed = true;
+}
+
 static void launch_desktop_shell_process(void *data);
 
 static void
@@ -4054,36 +5009,50 @@ desktop_shell_sigchld(struct weston_process *process, int status)
 
     shell->child.deathcount++;
     if (shell->child.deathcount > 5) {
-        weston_log("%s died, giving up.\n", shell_exe);
+        weston_log("%s died, giving up.\n", shell->client);
         return;
     }
 
-    weston_log("%s died, respawning...\n", shell_exe);
+    weston_log("%s died, respawning...\n", shell->client);
     launch_desktop_shell_process(shell);
     shell_fade_startup(shell);
 }
 
 static void
+desktop_shell_client_destroy(struct wl_listener *listener, void *data)
+{
+    struct desktop_shell *shell;
+
+    shell = container_of(listener, struct desktop_shell,
+                 child.client_destroy_listener);
+
+    shell->child.client = NULL;
+}
+
+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] == ' '))   {
+    /* if shell client(ex. desktop-shell) not exsit, not launch */
+    if ((shell->client == NULL) || (shell->client[0] == 0) || (shell->client[0] == ' ')) {
         weston_log("no shell program\n");
     }
     else    {
-        uifw_trace("launch_desktop_shell_process: launch %s", shell_exe);
+        uifw_trace("launch_desktop_shell_process: launch %s", shell->client);
         shell->child.client = weston_client_launch(shell->compositor,
-                                                   &shell->child.process,
-                                                   shell_exe,
-                                                   desktop_shell_sigchld);
+                             &shell->child.process,
+                             shell->client,
+                             desktop_shell_sigchld);
 
         if (!shell->child.client)
-            weston_log("not able to start %s\n", shell_exe);
+            weston_log("not able to start %s\n", shell->client);
         else
-            weston_log("shell %s started\n", shell_exe);
+            weston_log("shell %s started\n", shell->client);
+        shell->child.client_destroy_listener.notify =
+            desktop_shell_client_destroy;
+        wl_client_add_destroy_listener(shell->child.client,
+                           &shell->child.client_destroy_listener);
     }
 }
 
@@ -4105,13 +5074,31 @@ bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 }
 
 static void
+bind_xdg_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, &xdg_shell_interface, 1, id);
+    if (resource)
+        wl_resource_set_dispatcher(resource,
+                       xdg_shell_unversioned_dispatch,
+                       NULL, 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);
+        (*shell_hook_unbind)(wl_resource_get_client(resource));
     }
 
     if (shell->locked)
@@ -4142,7 +5129,6 @@ bind_desktop_shell(struct wl_client *client,
 
         return;
     }
-weston_log("bind_desktop_shell: client=%08x shell=%08x\n", (int)client, (int)shell->child.client);
 
     wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
                    "permission to bind desktop_shell denied");
@@ -4150,23 +5136,25 @@ weston_log("bind_desktop_shell: client=%08x shell=%08x\n", (int)client, (int)she
 }
 
 static void
-screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
+screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
 {
     struct desktop_shell *shell = surface->configure_private;
+    struct weston_view *view;
 
-    if (width == 0)
+    if (surface->width == 0)
         return;
 
     /* XXX: starting weston-screensaver beforehand does not work */
     if (!shell->locked)
         return;
 
-    center_on_output(surface, surface->output);
+    view = container_of(surface->views.next, struct weston_view, surface_link);
+    center_on_output(view, 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);
+    if (wl_list_empty(&view->layer_link)) {
+        wl_list_insert(shell->lock_layer.view_list.prev,
+                   &view->layer_link);
+        weston_view_update_transform(view);
         wl_event_source_timer_update(shell->screensaver.timer,
                          shell->screensaver.duration);
         shell_fade(shell, FADE_IN);
@@ -4183,6 +5171,12 @@ screensaver_set_surface(struct wl_client *client,
     struct weston_surface *surface =
         wl_resource_get_user_data(surface_resource);
     struct weston_output *output = wl_resource_get_user_data(output_resource);
+    struct weston_view *view, *next;
+
+    /* Make sure we only have one view */
+    wl_list_for_each_safe(view, next, &surface->views, surface_link)
+        weston_view_destroy(view);
+    weston_view_create(surface);
 
     surface->configure = screensaver_configure;
     surface->configure_private = shell;
@@ -4223,282 +5217,6 @@ bind_screensaver(struct wl_client *client,
     wl_resource_destroy(resource);
 }
 
-static void
-input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
-{
-    struct input_panel_surface *ip_surface = surface->configure_private;
-    struct desktop_shell *shell = ip_surface->shell;
-    float x, y;
-    uint32_t show_surface = 0;
-
-    if (width == 0) {
-        uifw_debug("input_panel_configure: configure %08x width=0, Skip", (int)surface);
-        return;
-    }
-    if (!weston_surface_is_mapped(surface)) {
-        if (!shell->showing_input_panels)   {
-            uifw_debug("input_panel_configure: configure %08x not show, Skip", (int)surface);
-            return;
-        }
-        show_surface = 1;
-    }
-
-    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 (! shell_hook_map)  {
-            y -= 132.0f;
-        }
-    }
-
-    uifw_debug("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) {
-        /* if ico_window_mgr hook, call hook routine    */
-        if (! shell_hook_configure)  {
-            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);
-    }
-
-    /* if ico_window_mgr hook, call hook routine    */
-    /* set default color and shader because weston original bug(some time crash weston) */
-    weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1);
-    if (shell_hook_map)  {
-        int     wx, wy;
-        wx = (int)x;
-        wy = (int)y;
-        (*shell_hook_map)(surface, &width, &height, &wx, &wy);
-    }
-    if (shell_hook_configure)  {
-        (*shell_hook_configure)(surface);
-    }
-}
-
-static void
-destroy_input_panel_surface(struct input_panel_surface *input_panel_surface)
-{
-    uifw_debug("destroy_input_panel_surface: ");
-    if (shell_hook_create)  {
-        return;
-    }
-
-    wl_signal_emit(&input_panel_surface->destroy_signal, input_panel_surface);
-
-    wl_list_remove(&input_panel_surface->surface_destroy_listener.link);
-    wl_list_remove(&input_panel_surface->link);
-
-    input_panel_surface->surface->configure = NULL;
-
-    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;
-    }
-}
-
-static void
-input_panel_handle_surface_destroy(struct wl_listener *listener, void *data)
-{
-    uifw_debug("input_panel_handle_surface_destroy: ");
-    if (shell_hook_create)  {
-        return;
-    }
-
-    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);
-    }
-}
-
-static struct input_panel_surface *
-create_input_panel_surface(struct desktop_shell *shell,
-               struct weston_surface *surface)
-{
-    uifw_debug("create_input_panel_surface: ");
-    if (shell_hook_create)  {
-        return NULL;
-    }
-
-    struct input_panel_surface *input_panel_surface;
-
-    input_panel_surface = calloc(1, sizeof *input_panel_surface);
-    if (!input_panel_surface)
-        return NULL;
-
-    surface->configure = input_panel_configure;
-    surface->configure_private = input_panel_surface;
-
-    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;
-}
-
-static void
-input_panel_surface_set_toplevel(struct wl_client *client,
-                 struct wl_resource *resource,
-                 struct wl_resource *output_resource,
-                 uint32_t position)
-{
-    uifw_debug("input_panel_surface_set_toplevel: ");
-    if (shell_hook_create)  {
-        return;
-    }
-
-    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);
-
-    input_panel_surface->output = wl_resource_get_user_data(output_resource);
-    input_panel_surface->panel = 0;
-}
-
-static void
-input_panel_surface_set_overlay_panel(struct wl_client *client,
-                      struct wl_resource *resource)
-{
-    uifw_debug("input_panel_surface_set_overlay_panel: ");
-    if (shell_hook_create)  {
-        return;
-    }
-
-    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);
-
-    input_panel_surface->panel = 1;
-}
-
-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
-destroy_input_panel_surface_resource(struct wl_resource *resource)
-{
-    struct input_panel_surface *ipsurf =
-        wl_resource_get_user_data(resource);
-
-    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)
-{
-    if (shell_hook_create)  {
-        uifw_debug("input_panel_get_input_panel_surface: weston_surface=%08x",
-                   (int)wl_resource_get_user_data(surface_resource));
-
-        shell_get_shell_surface_layertype(LAYER_TYPE_INPUTPANEL,
-                                          client, resource, id, surface_resource);
-    }
-    else    {
-        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;
-        }
-        uifw_debug("input_panel_get_input_panel_surface: weston_surface=%08x", (int)surface);
-
-        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);
-    }
-}
-
-static const struct wl_input_panel_interface input_panel_implementation = {
-    input_panel_get_input_panel_surface
-};
-
-static void
-unbind_input_panel(struct wl_resource *resource)
-{
-    struct desktop_shell *shell = wl_resource_get_user_data(resource);
-
-    shell->input_panel.binding = NULL;
-}
-
-static void
-bind_input_panel(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_input_panel_interface, 1, 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;
-    }
-
-    wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
-                   "interface object already bound");
-    wl_resource_destroy(resource);
-}
-
 struct switcher {
     struct desktop_shell *shell;
     struct weston_surface *current;
@@ -4509,33 +5227,30 @@ struct switcher {
 static void
 switcher_next(struct switcher *switcher)
 {
-    struct weston_surface *surface;
+    struct weston_view *view;
     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:
+    wl_list_for_each(view, &ws->layer.view_list, layer_link) {
+        shsurf = get_shell_surface(view->surface);
+        if (shsurf &&
+            shsurf->type == SHELL_SURFACE_TOPLEVEL &&
+            shsurf->parent == NULL) {
             if (first == NULL)
-                first = surface;
+                first = view->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;
+                next = view->surface;
+            prev = view->surface;
+            view->alpha = 0.25;
+            weston_view_geometry_dirty(view);
+            weston_surface_damage(view->surface);
         }
 
-        if (is_black_surface(surface, NULL)) {
-            surface->alpha = 0.25;
-            weston_surface_geometry_dirty(surface);
-            weston_surface_damage(surface);
+        if (is_black_surface(view->surface, NULL)) {
+            view->alpha = 0.25;
+            weston_view_geometry_dirty(view);
+            weston_surface_damage(view->surface);
         }
     }
 
@@ -4549,11 +5264,12 @@ switcher_next(struct switcher *switcher)
     wl_signal_add(&next->destroy_signal, &switcher->listener);
 
     switcher->current = next;
-    next->alpha = 1.0;
+    wl_list_for_each(view, &next->views, surface_link)
+        view->alpha = 1.0;
 
     shsurf = get_shell_surface(switcher->current);
-    if (shsurf && shsurf->type ==SHELL_SURFACE_FULLSCREEN)
-        shsurf->fullscreen.black_surface->alpha = 1.0;
+    if (shsurf && shsurf->state.fullscreen)
+        shsurf->fullscreen.black_view->alpha = 1.0;
 }
 
 static void
@@ -4568,13 +5284,16 @@ switcher_handle_surface_destroy(struct wl_listener *listener, void *data)
 static void
 switcher_destroy(struct switcher *switcher)
 {
-    struct weston_surface *surface;
+    struct weston_view *view;
     struct weston_keyboard *keyboard = switcher->grab.keyboard;
     struct workspace *ws = get_current_workspace(switcher->shell);
 
-    wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
-        surface->alpha = 1.0;
-        weston_surface_damage(surface);
+    wl_list_for_each(view, &ws->layer.view_list, layer_link) {
+        if (is_focus_view(view))
+            continue;
+
+        view->alpha = 1.0;
+        weston_surface_damage(view->surface);
     }
 
     if (switcher->current)
@@ -4911,25 +5630,91 @@ workspace_move_surface_down_binding(struct weston_seat *seat, uint32_t time,
 }
 
 static void
+handle_output_destroy(struct wl_listener *listener, void *data)
+{
+    struct shell_output *output_listener =
+        container_of(listener, struct shell_output, destroy_listener);
+
+    wl_list_remove(&output_listener->destroy_listener.link);
+    wl_list_remove(&output_listener->link);
+    free(output_listener);
+}
+
+static void
+create_shell_output(struct desktop_shell *shell,
+                    struct weston_output *output)
+{
+    struct shell_output *shell_output;
+
+    shell_output = zalloc(sizeof *shell_output);
+    if (shell_output == NULL)
+        return;
+
+    shell_output->output = output;
+    shell_output->shell = shell;
+    shell_output->destroy_listener.notify = handle_output_destroy;
+    wl_signal_add(&output->destroy_signal,
+              &shell_output->destroy_listener);
+    wl_list_insert(shell->output_list.prev, &shell_output->link);
+}
+
+static void
+handle_output_create(struct wl_listener *listener, void *data)
+{
+    struct desktop_shell *shell =
+        container_of(listener, struct desktop_shell, output_create_listener);
+    struct weston_output *output = (struct weston_output *)data;
+
+    create_shell_output(shell, output);
+}
+
+static void
+setup_output_destroy_handler(struct weston_compositor *ec,
+                            struct desktop_shell *shell)
+{
+    struct weston_output *output;
+
+    wl_list_init(&shell->output_list);
+    wl_list_for_each(output, &ec->output_list, link)
+        create_shell_output(shell, output);
+
+    shell->output_create_listener.notify = handle_output_create;
+    wl_signal_add(&ec->output_created_signal,
+                &shell->output_create_listener);
+}
+
+static void
 shell_destroy(struct wl_listener *listener, void *data)
 {
     struct desktop_shell *shell =
         container_of(listener, struct desktop_shell, destroy_listener);
     struct workspace **ws;
+    struct shell_output *shell_output, *tmp;
 
+    /* Force state to unlocked so we don't try to fade */
+    shell->locked = false;
     if (shell->child.client)
         wl_client_destroy(shell->child.client);
 
     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);
+
+    input_panel_destroy(shell);
+
+    wl_list_for_each_safe(shell_output, tmp, &shell->output_list, link) {
+        wl_list_remove(&shell_output->destroy_listener.link);
+        wl_list_remove(&shell_output->link);
+        free(shell_output);
+    }
+
+    wl_list_remove(&shell->output_create_listener.link);
 
     wl_array_for_each(ws, &shell->workspaces.array)
         workspace_destroy(*ws);
     wl_array_release(&shell->workspaces.array);
 
     free(shell->screensaver.path);
+    free(shell->client);
     free(shell);
 }
 
@@ -4962,11 +5747,18 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
                       zoom_key_binding, NULL);
     weston_compositor_add_key_binding(ec, KEY_PAGEDOWN, mod,
                       zoom_key_binding, NULL);
+    weston_compositor_add_key_binding(ec, KEY_M, mod | MODIFIER_SHIFT,
+                      maximize_binding, NULL);
+    weston_compositor_add_key_binding(ec, KEY_F, mod | MODIFIER_SHIFT,
+                      fullscreen_binding, NULL);
     weston_compositor_add_button_binding(ec, BTN_LEFT, mod, move_binding,
                          shell);
     weston_compositor_add_touch_binding(ec, mod, touch_move_binding, shell);
     weston_compositor_add_button_binding(ec, BTN_MIDDLE, mod,
                          resize_binding, shell);
+    weston_compositor_add_button_binding(ec, BTN_LEFT,
+                         mod | MODIFIER_SHIFT,
+                         resize_binding, shell);
 
     if (ec->capabilities & WESTON_CAP_ROTATION_ANY)
         weston_compositor_add_button_binding(ec, BTN_RIGHT, mod,
@@ -4995,6 +5787,10 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
                       workspace_move_surface_down_binding,
                       shell);
 
+    if (shell->exposay_modifier)
+        weston_compositor_add_modifier_binding(ec, shell->exposay_modifier,
+                               exposay_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;
@@ -5036,15 +5832,11 @@ module_init(struct weston_compositor *ec,
     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.get_primary_view = get_primary_view;
     ec->shell_interface.set_toplevel = set_toplevel;
     ec->shell_interface.set_transient = set_transient;
     ec->shell_interface.set_fullscreen = set_fullscreen;
@@ -5053,8 +5845,6 @@ module_init(struct weston_compositor *ec,
     ec->shell_interface.resize = surface_resize;
     ec->shell_interface.set_title = set_title;
 
-    wl_list_init(&shell->input_panel.surfaces);
-
     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);
@@ -5064,8 +5854,14 @@ module_init(struct weston_compositor *ec,
     wl_array_init(&shell->workspaces.array);
     wl_list_init(&shell->workspaces.client_list);
 
+    if (input_panel_setup(shell) < 0)
+        return -1;
+
     shell_configuration(shell);
 
+    shell->exposay.state_cur = EXPOSAY_LAYOUT_INACTIVE;
+    shell->exposay.state_target = EXPOSAY_TARGET_CANCEL;
+
     for (i = 0; i < shell->workspaces.num; i++) {
         pws = wl_array_add(&shell->workspaces.array, sizeof *pws);
         if (pws == NULL)
@@ -5085,6 +5881,10 @@ module_init(struct weston_compositor *ec,
                   shell, bind_shell) == NULL)
         return -1;
 
+    if (wl_global_create(ec->wl_display, &xdg_shell_interface, 1,
+                  shell, bind_xdg_shell) == NULL)
+        return -1;
+
     if (wl_global_create(ec->wl_display,
                  &desktop_shell_interface, 2,
                  shell, bind_desktop_shell) == NULL)
@@ -5094,16 +5894,14 @@ module_init(struct weston_compositor *ec,
                  shell, bind_screensaver) == NULL)
         return -1;
 
-    if (wl_global_create(ec->wl_display, &wl_input_panel_interface, 1,
-                  shell, bind_input_panel) == NULL)
-        return -1;
-
     if (wl_global_create(ec->wl_display, &workspace_manager_interface, 1,
                  shell, bind_workspace_manager) == NULL)
         return -1;
 
     shell->child.deathstamp = weston_compositor_get_time();
 
+    setup_output_destroy_handler(ec, shell);
+
     loop = wl_display_get_event_loop(ec->wl_display);
     wl_event_loop_add_idle(loop, launch_desktop_shell_process, shell);
 
@@ -5230,19 +6028,6 @@ ico_ivi_shell_layertype(struct weston_surface *surface)
 
 /*--------------------------------------------------------------------------*/
 /**
- * @brief   ivi_shell_set_surface_initial_position: initialize surface position
- *
- * @param[in]   surface     weston surface
- * @return      none
- */
-/*--------------------------------------------------------------------------*/
-WL_EXPORT void
-ivi_shell_set_surface_initial_position(struct weston_surface *surface)
-{
-    weston_surface_set_initial_position (surface, _ico_ivi_shell);
-}
-/*--------------------------------------------------------------------------*/
-/**
  * @brief   ivi_shell_set_default_display: set default display
  *
  * @param[in]   inputpanel  default display of input panel surface
@@ -5293,9 +6078,8 @@ ico_ivi_shell_hook_unbind(void (*hook_unbind)(struct wl_client *client))
 /*--------------------------------------------------------------------------*/
 WL_EXPORT void
 ico_ivi_shell_hook_create(void (*hook_create)(int layertype,
-                                              struct wl_client *client,
-                                              struct wl_resource *resource,
                                               struct weston_surface *surface,
+                                              struct wl_client *client,
                                               struct shell_surface *shsurf))
 {
     shell_hook_create = hook_create;
diff --git a/src/ico_ivi_shell.h b/src/ico_ivi_shell.h
new file mode 100644 (file)
index 0000000..fe437b8
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Copyright © 2010-2012 Intel Corporation
+ * Copyright © 2011-2012 Collabora, Ltd.
+ * Copyright © 2013 Raspberry Pi Foundation
+ * Copyright © 2013-2014 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.
+ */
+
+#include <stdbool.h>
+
+#include <weston/compositor.h>
+
+enum animation_type {
+    ANIMATION_NONE,
+
+    ANIMATION_ZOOM,
+    ANIMATION_FADE,
+    ANIMATION_DIM_LAYER,
+};
+
+enum fade_type {
+    FADE_IN,
+    FADE_OUT
+};
+
+enum exposay_target_state {
+    EXPOSAY_TARGET_OVERVIEW, /* show all windows */
+    EXPOSAY_TARGET_CANCEL, /* return to normal, same focus */
+    EXPOSAY_TARGET_SWITCH, /* return to normal, switch focus */
+};
+
+enum exposay_layout_state {
+    EXPOSAY_LAYOUT_INACTIVE = 0, /* normal desktop */
+    EXPOSAY_LAYOUT_ANIMATE_TO_INACTIVE, /* in transition to normal */
+    EXPOSAY_LAYOUT_OVERVIEW, /* show all windows */
+    EXPOSAY_LAYOUT_ANIMATE_TO_OVERVIEW, /* in transition to all windows */
+};
+
+struct focus_surface {
+    struct weston_surface *surface;
+    struct weston_view *view;
+    struct weston_transform workspace_transform;
+};
+
+struct workspace {
+    struct weston_layer layer;
+
+    struct wl_list focus_list;
+    struct wl_listener seat_destroyed_listener;
+
+    struct focus_surface *fsurf_front;
+    struct focus_surface *fsurf_back;
+    struct weston_view_animation *focus_animation;
+};
+
+struct desktop_shell {
+    struct weston_compositor *compositor;
+
+    struct wl_listener idle_listener;
+    struct wl_listener wake_listener;
+    struct wl_listener destroy_listener;
+    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;
+        struct wl_listener client_destroy_listener;
+
+        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_view *view;
+        struct weston_view_animation *animation;
+        enum fade_type type;
+        struct wl_event_source *startup_timer;
+    } fade;
+
+    struct exposay {
+        /* XXX: Make these exposay_surfaces. */
+        struct weston_view *focus_prev;
+        struct weston_view *focus_current;
+        struct weston_view *clicked;
+        struct workspace *workspace;
+        struct weston_seat *seat;
+        struct wl_list surface_list;
+
+        struct weston_keyboard_grab grab_kbd;
+        struct weston_pointer_grab grab_ptr;
+
+                enum exposay_target_state state_target;
+                enum exposay_layout_state state_cur;
+        int in_flight; /* number of animations still running */
+
+        int num_surfaces;
+        int grid_size;
+        int surface_size;
+
+        int hpadding_outer;
+        int vpadding_outer;
+        int padding_inner;
+
+        int row_current;
+        int column_current;
+
+        bool mod_pressed;
+        bool mod_invalid;
+    } exposay;
+
+    uint32_t binding_modifier;
+    uint32_t exposay_modifier;
+    enum animation_type win_animation_type;
+    enum animation_type startup_animation_type;
+    enum animation_type focus_animation_type;
+
+    struct wl_listener output_create_listener;
+    struct wl_list output_list;
+
+    char *client;
+};
+
+void
+set_alpha_if_fullscreen(struct shell_surface *shsurf);
+
+struct weston_output *
+get_default_output(struct weston_compositor *compositor);
+
+struct weston_view *
+get_default_view(struct weston_surface *surface);
+
+struct shell_surface *
+get_shell_surface(struct weston_surface *surface);
+
+struct workspace *
+get_current_workspace(struct desktop_shell *shell);
+
+void
+lower_fullscreen_layer(struct desktop_shell *shell);
+
+void
+activate(struct desktop_shell *shell, struct weston_surface *es,
+     struct weston_seat *seat);
+
+void
+exposay_binding(struct weston_seat *seat,
+        enum weston_keyboard_modifier modifier,
+        void *data);
+int
+input_panel_setup(struct desktop_shell *shell);
+void
+input_panel_destroy(struct desktop_shell *shell);
index 03c346a..c2d4729 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2013 TOYOTA MOTOR CORPORATION.
+ * Copyright © 2013-2014 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
@@ -24,7 +24,7 @@
 /**
  * @brief   Public functions in ico_ivi_shell Weston plugin
  *
- * @date    Jul-26-2013
+ * @date    Jan-30-2014
  */
 
 #ifndef _ICO_IVI_SHELL_PRIVATE_H_
@@ -38,9 +38,6 @@ struct shell_surface;
 enum shell_surface_type {
     SHELL_SURFACE_NONE,
     SHELL_SURFACE_TOPLEVEL,
-    SHELL_SURFACE_TRANSIENT,
-    SHELL_SURFACE_FULLSCREEN,
-    SHELL_SURFACE_MAXIMIZED,
     SHELL_SURFACE_POPUP,
     SHELL_SURFACE_XWAYLAND
 };
@@ -60,7 +57,7 @@ enum shell_surface_type {
 enum shell_fullscreen_control   {
     SHELL_FULLSCREEN_ISTOP,
     SHELL_FULLSCREEN_SET,
-    SHELL_FULLSCREEN_STACK,
+    SHELL_FULLSCREEN_UNSET,
     SHELL_FULLSCREEN_CONF,
     SHELL_FULLSCREEN_HIDEALL
 };
@@ -74,15 +71,14 @@ 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);
 int ico_ivi_shell_layertype(struct weston_surface *surface);
-void ivi_shell_set_surface_initial_position(struct weston_surface *surface);
 void ivi_shell_set_default_display(struct weston_output *inputpanel);
 
 /* Prototypr for hook routine           */
 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)(int layertype, struct wl_client *client,
-                            struct wl_resource *resource, struct weston_surface *surface,
-                            struct shell_surface *shsurf));
+void ico_ivi_shell_hook_create(void (*hook_create)(int layertype,
+                            struct weston_surface *surface,
+                            struct wl_client *client, struct shell_surface *shsurf));
 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));
@@ -95,5 +91,22 @@ void ico_ivi_shell_hook_move(void (*hook_move)(struct weston_surface *surface,
 void ico_ivi_shell_hook_show_layer(void (*hook_show)(int layertype, int show, void *data));
 void ico_ivi_shell_hook_fullscreen(int (*hook_fullscreen)
                             (int event, struct weston_surface *surface));
+struct weston_view *ico_input_panel_get_view(void *ipsurf);
+
+/* hook functions           */
+extern void (*shell_hook_bind)(struct wl_client *client, void *shell);
+extern void (*shell_hook_unbind)(struct wl_client *client);
+extern void (*shell_hook_create)(int layertype, struct weston_surface *surface,
+                                 struct wl_client *client,
+                                 struct shell_surface *shsurf);
+extern void (*shell_hook_destroy)(struct weston_surface *surface);
+extern void (*shell_hook_map)(struct weston_surface *surface, int32_t *width,
+                              int32_t *height, int32_t *sx, int32_t *sy);
+extern void (*shell_hook_configure)(struct weston_surface *surface);
+extern void (*shell_hook_select)(struct weston_surface *surface);
+extern char *(*shell_hook_title)(struct weston_surface *surface, const char *title); 
+extern void (*shell_hook_move)(struct weston_surface *surface, int *dx, int *dy);
+extern void (*shell_hook_show_layer)(int layertype, int show, void *data);
+extern int (*shell_hook_fullscreen)(int event, struct weston_surface *surface);
 
 #endif  /*_ICO_IVI_SHELL_PRIVATE_H_*/
index 3ef9346..ce081cd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2013 TOYOTA MOTOR CORPORATION.
+ * Copyright © 2013-2014 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
index 699a655..32c09f3 100644 (file)
@@ -1 +1 @@
-#define ICO_PLUIGN_VERSION  "0.9.12 (Jan-22-2014)"
+#define ICO_PLUIGN_VERSION  "0.9.14 (Feb-07-2014)"
index 5e53bf6..5a4658f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2013 TOYOTA MOTOR CORPORATION.
+ * Copyright © 2013-2014 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
@@ -429,6 +429,7 @@ static void
 animation_end(struct uifw_win_surface *usurf, const int disp)
 {
     struct animation_data   *animadata;
+    struct weston_view      *ev;
 
     usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_NONE;
     animadata = (struct animation_data *)usurf->animation.animadata;
@@ -436,6 +437,7 @@ animation_end(struct uifw_win_surface *usurf, const int disp)
     if (animation_count > 0)    {
         animation_count --;
     }
+    ev = ico_ivi_get_primary_view(usurf);
 
     if (animadata)  {
         if (animadata->end_function)    {
@@ -446,7 +448,7 @@ animation_end(struct uifw_win_surface *usurf, const int disp)
             wl_list_remove(&animadata->transform.link);
             animadata->transform_set = 0;
         }
-        weston_surface_geometry_dirty(usurf->surface);
+        weston_view_geometry_dirty(ev);
     }
     if (disp)   {
         usurf->restrain_configure = 0;
@@ -460,7 +462,7 @@ animation_end(struct uifw_win_surface *usurf, const int disp)
             ico_window_mgr_set_visible(usurf, 1);
             weston_surface_damage(usurf->surface);
         }
-        weston_surface_geometry_dirty(usurf->surface);
+        weston_view_geometry_dirty(ev);
         ico_window_mgr_restack_layer(usurf);
     }
     usurf->animation.visible = ANIMA_NOCONTROL_AT_END;
@@ -516,6 +518,7 @@ animation_slide(struct weston_animation *animation,
 {
     struct uifw_win_surface *usurf;
     struct weston_surface   *es;
+    struct weston_view      *ev;
     int         dwidth, dheight;
     int         par;
     int         x;
@@ -531,6 +534,7 @@ animation_slide(struct weston_animation *animation,
         }
         return;
     }
+    ev = ico_ivi_get_primary_view(usurf);
     par = usurf->animation.current;
 
     uifw_debug("animation_slide: %08x count=%d %d%% anima=%d state=%d",
@@ -594,11 +598,11 @@ animation_slide(struct weston_animation *animation,
 
     uifw_debug("animation_slide: %08x %d%% %d/%d(target %d/%d)",
                usurf->surfaceid, par, x, y, usurf->x, usurf->y);
-    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_geometry_dirty(es);
+    ev->geometry.x = usurf->node_tbl->disp_x + x;
+    ev->geometry.y = usurf->node_tbl->disp_y + y;
+    if ((ev->output) && (es->buffer_ref.buffer) &&
+        (es->width > 0) && (es->height > 0))    {
+        weston_view_geometry_dirty(ev);
         weston_surface_damage(es);
     }
     if (par >= 100) {
@@ -628,6 +632,7 @@ animation_wipe(struct weston_animation *animation,
 {
     struct uifw_win_surface *usurf;
     struct weston_surface   *es;
+    struct weston_view      *ev;
     int         par;
     int         x;
     int         y;
@@ -644,6 +649,7 @@ animation_wipe(struct weston_animation *animation,
         }
         return;
     }
+    ev = ico_ivi_get_primary_view(usurf);
     par = usurf->animation.current;
 
     uifw_debug("animation_wipe: %08x count=%d %d%% anima=%d state=%d",
@@ -707,12 +713,12 @@ animation_wipe(struct weston_animation *animation,
         }
     }
 
-    es->geometry.x = usurf->node_tbl->disp_x + x;
-    es->geometry.y = usurf->node_tbl->disp_y + y;
-    es->geometry.width = width;
-    es->geometry.height = height;
-    if ((es->output) && (es->buffer_ref.buffer))    {
-        weston_surface_geometry_dirty(es);
+    ev->geometry.x = usurf->node_tbl->disp_x + x;
+    ev->geometry.y = usurf->node_tbl->disp_y + y;
+    es->width = width;
+    es->height = height;
+    if ((ev->output) && (es->buffer_ref.buffer))    {
+        weston_view_geometry_dirty(ev);
         weston_surface_damage(es);
     }
     if (par >= 100) {
@@ -742,6 +748,7 @@ animation_swing(struct weston_animation *animation,
 {
     struct uifw_win_surface *usurf;
     struct weston_surface   *es;
+    struct weston_view      *ev;
     struct animation_data   *animadata;
     int         par;
     int         x;
@@ -766,13 +773,14 @@ animation_swing(struct weston_animation *animation,
 
     animadata = (struct animation_data *)usurf->animation.animadata;
     es = usurf->surface;
+    ev = ico_ivi_get_primary_view(usurf);
     par = usurf->animation.current;
     if (animation->frame_counter == 1)  {
         if (animadata->transform_set == 0)  {
             animadata->transform_set = 1;
             weston_matrix_init(&animadata->transform.matrix);
             wl_list_init(&animadata->transform.link);
-            wl_list_insert(&es->geometry.transformation_list,
+            wl_list_insert(&ev->geometry.transformation_list,
                            &animadata->transform.link);
         }
         animadata->end_function = animation_swing_end;
@@ -834,8 +842,8 @@ animation_swing(struct weston_animation *animation,
         }
     }
 
-    es->geometry.x = usurf->node_tbl->disp_x + x;
-    es->geometry.y = usurf->node_tbl->disp_y + y;
+    ev->geometry.x = usurf->node_tbl->disp_x + x;
+    ev->geometry.y = usurf->node_tbl->disp_y + y;
     weston_matrix_init(&animadata->transform.matrix);
     weston_matrix_translate(&animadata->transform.matrix,
                             -0.5f * usurf->width, -0.5f * usurf->height, 0);
@@ -843,8 +851,8 @@ animation_swing(struct weston_animation *animation,
     weston_matrix_translate(&animadata->transform.matrix,
                             0.5f * usurf->width, 0.5f * usurf->height, 0);
 
-    if ((es->output) && (es->buffer_ref.buffer))    {
-        weston_surface_geometry_dirty(es);
+    if ((ev->output) && (es->buffer_ref.buffer))    {
+        weston_view_geometry_dirty(ev);
         weston_surface_damage(es);
     }
     if (par >= 100) {
@@ -871,13 +879,15 @@ animation_swing_end(struct weston_animation *animation)
 {
     struct uifw_win_surface *usurf;
     struct weston_surface   *es;
+    struct weston_view      *ev;
 
     usurf = container_of(animation, struct uifw_win_surface, animation.animation);
     if (usurf && usurf->surface)    {
         es = usurf->surface;
-        es->alpha = 1.0;
+        ev = ico_ivi_get_primary_view(usurf);
+        ev->alpha = 1.0;
 
-        if ((es->output) && (es->buffer_ref.buffer))    {
+        if ((ev->output) && (es->buffer_ref.buffer))    {
             weston_surface_damage(es);
         }
     }
@@ -900,6 +910,7 @@ animation_fade(struct weston_animation *animation,
     struct uifw_win_surface *usurf;
     struct animation_data   *animadata;
     struct weston_surface   *es;
+    struct weston_view      *ev;
     int         par;
 
     usurf = container_of(animation, struct uifw_win_surface, animation.animation);
@@ -915,13 +926,14 @@ animation_fade(struct weston_animation *animation,
 
     animadata = (struct animation_data *)usurf->animation.animadata;
     es = usurf->surface;
+    ev = ico_ivi_get_primary_view(usurf);
     par = usurf->animation.current;
     if (animation->frame_counter == 1)  {
         if (animadata->transform_set == 0)  {
             animadata->transform_set = 1;
             weston_matrix_init(&animadata->transform.matrix);
             wl_list_init(&animadata->transform.link);
-            wl_list_insert(&es->geometry.transformation_list,
+            wl_list_insert(&ev->geometry.transformation_list,
                            &animadata->transform.link);
         }
         animadata->end_function = animation_fade_end;
@@ -937,20 +949,20 @@ animation_fade(struct weston_animation *animation,
 
     if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_SHOW)    {
         /* fade in                  */
-        es->alpha = ((float)par) / 100.0f;
+        ev->alpha = ((float)par) / 100.0f;
     }
     else if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_HIDE)    {
         /* fade out                 */
-        es->alpha = 1.0f - (((float)par) / 100.0f);
+        ev->alpha = 1.0f - (((float)par) / 100.0f);
     }
     else    {
         /* fade move/resize         */
         if ((par >= 50) || (usurf->animation.ahalf))    {
-            es->alpha = ((float)(par*2 - 100)) / 100.0f;
+            ev->alpha = ((float)(par*2 - 100)) / 100.0f;
             if (usurf->animation.ahalf == 0)    {
                 uifw_trace("animation_fade: fade move chaneg to show");
                 usurf->animation.ahalf = 1;
-                es->alpha = 0.0;
+                ev->alpha = 0.0;
                 ico_window_mgr_set_weston_surface(usurf, usurf->x, usurf->y,
                                                   usurf->width, usurf->height);
                 ico_window_mgr_change_surface(usurf,
@@ -959,18 +971,18 @@ animation_fade(struct weston_animation *animation,
             }
         }
         else    {
-            es->alpha = 1.0f - (((float)(par*2)) / 100.0f);
+            ev->alpha = 1.0f - (((float)(par*2)) / 100.0f);
         }
     }
-    if (es->alpha < 0.0)        es->alpha = 0.0;
-    else if (es->alpha > 1.0)   es->alpha = 1.0;
+    if (ev->alpha < 0.0)        ev->alpha = 0.0;
+    else if (ev->alpha > 1.0)   ev->alpha = 1.0;
 
     uifw_debug("animation_fade: %08x count=%d %d%% alpha=%1.2f anima=%d state=%d",
                usurf->surfaceid, animation->frame_counter, par,
-               es->alpha, usurf->animation.anima, usurf->animation.state);
+               ev->alpha, usurf->animation.anima, usurf->animation.state);
 
-    if ((es->output) && (es->buffer_ref.buffer) &&
-        (es->geometry.width > 0) && (es->geometry.height > 0)) {
+    if ((ev->output) && (es->buffer_ref.buffer) &&
+        (es->width > 0) && (es->height > 0))    {
         weston_surface_damage(es);
     }
     if (par >= 100) {
@@ -997,14 +1009,16 @@ animation_fade_end(struct weston_animation *animation)
 {
     struct uifw_win_surface *usurf;
     struct weston_surface   *es;
+    struct weston_view      *ev;
 
     usurf = container_of(animation, struct uifw_win_surface, animation.animation);
     if (usurf && usurf->surface)    {
         es = usurf->surface;
-        es->alpha = 1.0;
+        ev = ico_ivi_get_primary_view(usurf);
+        ev->alpha = 1.0;
 
-        if ((es->output) && (es->buffer_ref.buffer) &&
-            (es->geometry.width > 0) && (es->geometry.height > 0)) {
+        if ((ev->output) && (es->buffer_ref.buffer) &&
+            (es->width > 0) && (es->height > 0))    {
             weston_surface_damage(es);
         }
     }
@@ -1027,6 +1041,7 @@ animation_zoom(struct weston_animation *animation,
     struct uifw_win_surface *usurf;
     struct animation_data   *animadata;
     struct weston_surface   *es;
+    struct weston_view      *ev;
     int         par;
     float       scalex, scaley;
     float       fu, fa, fp;
@@ -1045,13 +1060,14 @@ animation_zoom(struct weston_animation *animation,
 
     animadata = (struct animation_data *)usurf->animation.animadata;
     es = usurf->surface;
+    ev = ico_ivi_get_primary_view(usurf);
     par = usurf->animation.current;
     if (animation->frame_counter == 1)  {
         if (animadata->transform_set == 0)  {
             animadata->transform_set = 1;
             weston_matrix_init(&animadata->transform.matrix);
             wl_list_init(&animadata->transform.link);
-            wl_list_insert(&es->geometry.transformation_list,
+            wl_list_insert(&ev->geometry.transformation_list,
                            &animadata->transform.link);
         }
         animadata->end_function = animation_zoom_end;
@@ -1113,9 +1129,9 @@ animation_zoom(struct weston_animation *animation,
                (int)(usurf->height * scaley), usurf->height,
                usurf->animation.anima, usurf->animation.state);
 
-    if ((es->output) && (es->buffer_ref.buffer) &&
-        (es->geometry.width > 0) && (es->geometry.height > 0)) {
-        weston_surface_geometry_dirty(es);
+    if ((ev->output) && (es->buffer_ref.buffer) &&
+        (es->width > 0) && (es->height > 0))    {
+        weston_view_geometry_dirty(ev);
         weston_surface_damage(es);
     }
     if (par >= 100) {
@@ -1142,14 +1158,16 @@ animation_zoom_end(struct weston_animation *animation)
 {
     struct uifw_win_surface *usurf;
     struct weston_surface   *es;
+    struct weston_view      *ev;
 
     usurf = container_of(animation, struct uifw_win_surface, animation.animation);
     if (usurf && usurf->surface)    {
         es = usurf->surface;
-        es->alpha = 1.0;
+        ev = ico_ivi_get_primary_view(usurf);
+        ev->alpha = 1.0;
 
-        if ((es->output) && (es->buffer_ref.buffer) &&
-            (es->geometry.width > 0) && (es->geometry.height > 0)) {
+        if ((ev->output) && (es->buffer_ref.buffer) &&
+            (es->width > 0) && (es->height > 0))    {
             weston_surface_damage(es);
         }
     }
index 11b35c2..11f634f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2013 TOYOTA MOTOR CORPORATION.
+ * Copyright © 2013-2014 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
@@ -252,9 +252,9 @@ static pid_t win_mgr_get_ppid(pid_t pid);
                                             /* get appid from pid                   */
 static void win_mgr_get_client_appid(struct uifw_client *uclient);
                                             /* create new surface                   */
-static void win_mgr_register_surface(
-                    int layertype, struct wl_client *client, struct wl_resource *resource,
-                    struct weston_surface *surface, struct shell_surface *shsurf);
+static void win_mgr_register_surface(int layertype, struct weston_surface *surface,
+                                     struct wl_client *client,
+                                     struct shell_surface *shsurf);
                                             /* surface destroy                      */
 static void win_mgr_destroy_surface(struct weston_surface *surface);
                                             /* map new surface                      */
@@ -358,6 +358,9 @@ static int ico_win_mgr_send_to_mgr(const int event, struct uifw_win_surface *usu
 static int win_mgr_set_scale(struct uifw_win_surface *usurf);
                                             /* convert animation name to Id value   */
 static int ico_get_animation_name(const char *animation);
+                                            /* read surface pixels                  */
+static int ico_read_surface_pixels(struct weston_surface *es, pixman_format_code_t format,
+                                   void *pixels, int x, int y, int width, int height);
                                             /* hook for animation                   */
 static int  (*win_mgr_hook_animation)(const int op, void *data) = NULL;
                                             /* hook for input region                */
@@ -536,6 +539,145 @@ ico_ivi_get_mynode(void)
 
 /*--------------------------------------------------------------------------*/
 /**
+ * @brief   ico_ivi_surface_buffer_width: get surface buffer width
+ *
+ * @param[in]   es          weston surface
+ * @return      buffer width(if surface has no buffer, return 0)
+ */
+/*--------------------------------------------------------------------------*/
+WL_EXPORT   int
+ico_ivi_surface_buffer_width(struct weston_surface *es)
+{
+    int v;
+
+    if (! es->buffer_ref.buffer)    {
+        return 0;
+    }
+    if (es->buffer_viewport.viewport_set)   {
+        return es->buffer_viewport.dst_width;
+    }
+    switch (es->buffer_viewport.transform) {
+    case WL_OUTPUT_TRANSFORM_90:
+    case WL_OUTPUT_TRANSFORM_270:
+    case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+    case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+        v = es->buffer_ref.buffer->height;
+        break;
+    default:
+        v = es->buffer_ref.buffer->width;
+        break;
+    }
+    return (v / es->buffer_viewport.scale);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ivi_surface_buffer_height: get surface buffer height
+ *
+ * @param[in]   es          weston surface
+ * @return      buffer height(if surface has no buffer, return 0)
+ */
+/*--------------------------------------------------------------------------*/
+WL_EXPORT   int
+ico_ivi_surface_buffer_height(struct weston_surface *es)
+{
+    int v;
+
+    if (! es->buffer_ref.buffer)    {
+        return 0;
+    }
+    if (es->buffer_viewport.viewport_set)   {
+        return es->buffer_viewport.dst_height;
+    }
+    switch (es->buffer_viewport.transform) {
+    case WL_OUTPUT_TRANSFORM_90:
+    case WL_OUTPUT_TRANSFORM_270:
+    case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+    case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+        v = es->buffer_ref.buffer->width;
+        break;
+    default:
+        v = es->buffer_ref.buffer->height;
+        break;
+    }
+    return (v / es->buffer_viewport.scale);
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ivi_surface_buffer_size: get surface buffer size
+ *
+ * @param[in]   es          weston surface
+ * @param[out]  width       buffer width
+ * @param[out]  height      buffer height
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+WL_EXPORT   void
+ico_ivi_surface_buffer_size(struct weston_surface *es, int *width, int *height)
+{
+    if (! es->buffer_ref.buffer)    {
+        *width = 0;
+        *height = 0;
+    }
+    else if (es->buffer_viewport.viewport_set)  {
+        *width = es->buffer_viewport.dst_width;
+        *height = es->buffer_viewport.dst_height;
+    }
+    else    {
+        switch (es->buffer_viewport.transform) {
+        case WL_OUTPUT_TRANSFORM_90:
+        case WL_OUTPUT_TRANSFORM_270:
+        case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+        case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+            *width = es->buffer_ref.buffer->height;
+            *height = es->buffer_ref.buffer->width;
+            break;
+        default:
+            *width = es->buffer_ref.buffer->width;
+            *height = es->buffer_ref.buffer->height;
+            break;
+        }
+        *width = *width / es->buffer_viewport.scale;
+        *height = *height / es->buffer_viewport.scale;
+    }
+}
+
+/*--------------------------------------------------------------------------*/
+/**
+ * @brief   ico_ivi_surface_buffer_size: get surface buffer size
+ *
+ * @param[in]   es          weston surface
+ * @param[out]  width       buffer width
+ * @param[out]  height      buffer height
+ * @return      nothing
+ */
+/*--------------------------------------------------------------------------*/
+WL_EXPORT   struct weston_view *
+ico_ivi_get_primary_view(struct uifw_win_surface *usurf)
+{
+    struct weston_view  *ev;
+
+    if (usurf->layertype == LAYER_TYPE_INPUTPANEL)  {
+        ev = ico_input_panel_get_view((void *)(usurf->shsurf));
+    }
+    else    {
+        ev = (*_ico_win_mgr->compositor->shell_interface.get_primary_view)
+                                                            (NULL, usurf->shsurf);
+    }
+    if (! ev)   {
+        uifw_error("ico_ivi_get_primary_view: usurf=%08x(%x) surface=%08x has no view",
+                   (int)usurf, usurf->surfaceid, (int)usurf->surface);
+    }
+    else    {
+        uifw_debug("ico_ivi_get_primary_view: %08x[%d] view=%08x view->surf=%08x",
+                   usurf->surfaceid, usurf->layertype, (int)ev, (int)ev->surface);
+    }
+    return ev;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
  * @brief   ico_window_mgr_set_weston_surface: set weston surface
  *
  * @param[in]   usurf       UIFW surface
@@ -551,17 +693,17 @@ ico_window_mgr_set_weston_surface(struct uifw_win_surface *usurf,
                                   int x, int y, int width, int height)
 {
     struct weston_surface *es = usurf->surface;
+    struct weston_view  *ev;
     int     buf_width, buf_height;
 
-    if (es == NULL) {
+    if ((es == NULL) || (usurf->shsurf == NULL))    {
         uifw_trace("ico_window_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);
+        ico_ivi_surface_buffer_size(es, &buf_width, &buf_height);
         if ((width <= 0) || (height <= 0))    {
             width = buf_width;
             usurf->width = buf_width;
@@ -584,9 +726,11 @@ ico_window_mgr_set_weston_surface(struct uifw_win_surface *usurf,
             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);
+        ev = ico_ivi_get_primary_view(usurf);
+        if ((ev != NULL) &&
+            (((int)ev->geometry.x != x) || ((int)ev->geometry.y != y) ||
+             (es->width != width) || (es->height != height)))   {
+            weston_view_damage_below(ev);
             win_mgr_surface_configure(usurf, x, y, width, height);
         }
         weston_surface_damage(es);
@@ -1212,20 +1356,81 @@ ico_get_animation_name(const char *animation)
 
 /*--------------------------------------------------------------------------*/
 /**
+ * @brief   ico_read_surface_pixels: read surface pixel image
+ *                                   this function inport from weston 1.3.1(by Tizen)
+ *
+ * @param[in]   es      weston surface
+ * @param[in]   format  pixel format
+ * @param[out]  pixels  pixel read buffer
+ * @param[in]   x       X coordinate
+ * @param[in]   y       Y coordinate
+ * @param[in]   width   width
+ * @param[in]   height  height
+ * @return      success(=0) or error(-1)
+ */
+/*--------------------------------------------------------------------------*/
+static int
+ico_read_surface_pixels(struct weston_surface *es, pixman_format_code_t format,
+                        void *pixels, int x, int y, int width, int height)
+{
+    struct weston_buffer *buffer = es->buffer_ref.buffer;
+    struct uifw_gl_surface_state *gs = es->renderer_state;
+    GLenum gl_format;
+    int size;
+    struct wl_shm_buffer *shm_buffer = NULL;
+    GLuint fbo;
+
+    switch (format) {
+    case PIXMAN_a8r8g8b8:
+        gl_format = GL_BGRA_EXT;
+        break;
+    case PIXMAN_a8b8g8r8:
+        gl_format = GL_RGBA;
+        break;
+    default:
+        return -1;
+    }
+
+    if (buffer) {
+        shm_buffer = wl_shm_buffer_get(buffer->resource);
+    }
+    if (shm_buffer) {
+        size = buffer->width * 4 * buffer->height;
+        memcpy(pixels, wl_shm_buffer_get_data(shm_buffer), size);
+    } else if (gs != NULL)  {
+        glGenFramebuffers(1, &fbo);
+        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+        glFramebufferTexture2D(GL_FRAMEBUFFER,
+                               GL_COLOR_ATTACHMENT0,
+                               GL_TEXTURE_2D,
+                               gs->textures[0], 0);
+
+        glReadPixels(x, y, width, height,
+                     gl_format, GL_UNSIGNED_BYTE, pixels);
+
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+        glDeleteFramebuffers(1, &fbo);
+    }
+    else    {
+        return -1;
+    }
+    return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+/**
  * @brief   win_mgr_register_surface: create UIFW surface
  *
  * @param[in]   layertype       surface layer type
- * @param[in]   client          Wayland client
- * @param[in]   resource        client resource
  * @param[in]   surface         Weston surface
+ * @param[in]   client          Wayland client
  * @param[in]   shsurf          shell surface
  * @return      none
  */
 /*--------------------------------------------------------------------------*/
 static void
-win_mgr_register_surface(int layertype, struct wl_client *client,
-                         struct wl_resource *resource, struct weston_surface *surface,
-                         struct shell_surface *shsurf)
+win_mgr_register_surface(int layertype, struct weston_surface *surface,
+                         struct wl_client *client, struct shell_surface *shsurf)
 {
     struct uifw_win_surface *usurf;
     struct uifw_win_surface *phash;
@@ -1233,8 +1438,8 @@ win_mgr_register_surface(int layertype, struct wl_client *client,
     int         layer;
     uint32_t    hash;
 
-    uifw_trace("win_mgr_register_surface: Enter(surf=%08x,client=%08x,res=%08x,layertype=%x)",
-               (int)surface, (int)client, (int)resource, layertype);
+    uifw_trace("win_mgr_register_surface: Enter(surf=%08x,client=%08x,type=%x,shsurf=%08x)",
+               (int)surface, (int)client, layertype, (int)shsurf);
 
     /* check new surface                    */
     if (find_uifw_win_surface_by_ws(surface))   {
@@ -1244,7 +1449,7 @@ win_mgr_register_surface(int layertype, struct wl_client *client,
     }
 
     /* set default color and shader */
-    weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1);
+    weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
 
     /* create UIFW surface management table */
     usurf = malloc(sizeof(struct uifw_win_surface));
@@ -1384,7 +1589,7 @@ win_mgr_surface_map(struct weston_surface *surface, int32_t *width, int32_t *hei
 
     usurf = find_uifw_win_surface_by_ws(surface);
 
-    if (usurf) {
+    if ((usurf != NULL) && (usurf->mapped == 0))    {
         uifw_trace("win_mgr_surface_map: surf=%08x w/h=%d/%d vis=%d",
                    usurf->surfaceid, usurf->width, usurf->height, usurf->visible);
         if ((usurf->width > 0) && (usurf->height > 0)) {
@@ -1412,17 +1617,17 @@ win_mgr_surface_map(struct weston_surface *surface, int32_t *width, int32_t *hei
                 /* set position */
                 usurf->node_tbl = &_ico_node_table[_ico_ivi_inputpanel_display];
 
-                usurf->width = (float)usurf->surface->geometry.width
+                usurf->width = (float)usurf->surface->width
                                * (float)_ico_ivi_inputdeco_mag / 100.0f;
-                usurf->height = (float)usurf->surface->geometry.height
+                usurf->height = (float)usurf->surface->height
                                 * (float)_ico_ivi_inputdeco_mag / 100.0f;
 
                 if ((usurf->width > (usurf->node_tbl->disp_width - 16)) ||
                     (usurf->height > (usurf->node_tbl->disp_height - 16)))  {
                     usurf->x = (usurf->node_tbl->disp_width
-                               - usurf->surface->geometry.width) / 2;
+                               - usurf->surface->width) / 2;
                     usurf->y = usurf->node_tbl->disp_height
-                               - usurf->surface->geometry.height - 16
+                               - usurf->surface->height - 16
                                - _ico_ivi_inputdeco_diff;
                     if (usurf->x < 0)   usurf->x = 0;
                     if (usurf->y < 0)   usurf->y = 0;
@@ -1454,8 +1659,7 @@ win_mgr_surface_map(struct weston_surface *surface, int32_t *width, int32_t *hei
                                               usurf->width, usurf->height);
                 }
                 uifw_trace("win_mgr_surface_map: 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);
+                           usurf->x, usurf->y, surface->width, surface->height);
             }
             else if (usurf->layertype != LAYER_TYPE_INPUTPANEL) {
                 uifw_trace("win_mgr_surface_map: No HomeScreen, chaneg to Visible");
@@ -1481,7 +1685,7 @@ win_mgr_surface_map(struct weston_surface *surface, int32_t *width, int32_t *hei
         uifw_trace("win_mgr_surface_map: Leave");
     }
     else    {
-        uifw_trace("win_mgr_surface_map: Leave(No UIFW Surface)");
+        uifw_trace("win_mgr_surface_map: Leave(No UIFW Surface or mapped)");
     }
 }
 
@@ -1501,7 +1705,7 @@ ico_window_mgr_restack_layer(struct uifw_win_surface *usurf)
     int32_t buf_width, buf_height;
     float   new_x, new_y;
     struct weston_layer *wlayer;
-    struct weston_surface  *surface, *surfacetmp;
+    struct weston_view  *view, *viewtmp;
     int     num_visible = 0;
     int     layertype;
 
@@ -1512,11 +1716,13 @@ ico_window_mgr_restack_layer(struct uifw_win_surface *usurf)
                (int)usurf, (int)wlayer);
 
     /* remove all surfaces in panel_layer   */
-    wl_list_for_each_safe (surface, surfacetmp, &wlayer->surface_list, layer_link)   {
-        wl_list_remove(&surface->layer_link);
-        wl_list_init(&surface->layer_link);
+    wl_list_for_each_safe (view, viewtmp, &wlayer->view_list, layer_link)   {
+uifw_debug("ico_window_mgr_restack_layer: remove view %08x surf=%08x",
+        (int)view, (int)view->surface);
+        wl_list_remove(&view->layer_link);
+        wl_list_init(&view->layer_link);
     }
-    wl_list_init(&wlayer->surface_list);
+    wl_list_init(&wlayer->view_list);
 
     wl_list_for_each (el, &_ico_win_mgr->ivi_layer_list, link)  {
         wl_list_for_each (eu, &el->surface_list, ivi_layer) {
@@ -1529,8 +1735,6 @@ ico_window_mgr_restack_layer(struct uifw_win_surface *usurf)
                 (layertype != LAYER_TYPE_UNKNOWN))  {
                 continue;
             }
-            wl_list_remove(&eu->surface->layer_link);
-            wl_list_init(&eu->surface->layer_link);
 
             if (eu->mapped != 0)    {
                 if ((el->visible == FALSE) || (eu->visible == FALSE))   {
@@ -1538,18 +1742,17 @@ ico_window_mgr_restack_layer(struct uifw_win_surface *usurf)
                     new_y = (float)(ICO_IVI_MAX_COORDINATE+1);
                 }
                 else if (eu->surface->buffer_ref.buffer)    {
-                    buf_width = weston_surface_buffer_width(eu->surface);
-                    buf_height = weston_surface_buffer_height(eu->surface);
+                    ico_ivi_surface_buffer_size(eu->surface, &buf_width, &buf_height);
                     if ((eu->width > buf_width) && (eu->scalex <= 1.0f))    {
                         new_x = (float)(eu->x +
-                                (eu->width - eu->surface->geometry.width)/2);
+                                (eu->width - eu->surface->width)/2);
                     }
                     else    {
                         new_x = (float)eu->x;
                     }
                     if ((eu->height > buf_height) && (eu->scaley <= 1.0f))  {
                         new_y = (float) (eu->y +
-                                (eu->height - eu->surface->geometry.height)/2);
+                                (eu->height - eu->surface->height)/2);
                     }
                     else    {
                         new_y = (float)eu->y;
@@ -1562,23 +1765,33 @@ ico_window_mgr_restack_layer(struct uifw_win_surface *usurf)
                     new_x = (float)(eu->x + eu->node_tbl->disp_x + eu->xadd);
                     new_y = (float)(eu->y + eu->node_tbl->disp_y + eu->yadd);
                 }
-                wl_list_insert(wlayer->surface_list.prev, &eu->surface->layer_link);
-                if ((eu->restrain_configure == 0) &&
-                    ((new_x != eu->surface->geometry.x) ||
-                     (new_y != eu->surface->geometry.y)))   {
-                    weston_surface_damage_below(eu->surface);
-                    weston_surface_set_position(eu->surface, (float)new_x, (float)new_y);
-                    weston_surface_damage(eu->surface);
+                wl_list_for_each (view, &eu->surface->views, surface_link)  {
+uifw_debug("ico_window_mgr_restack_layer: add %08x view %08x surf=%08x",
+        eu->surfaceid, (int)view, (int)view->surface);
+                    wl_list_remove(&view->layer_link);
+                    wl_list_init(&view->layer_link);
+                    wl_list_insert(wlayer->view_list.prev, &view->layer_link);
+                    if ((eu->restrain_configure == 0) &&
+                        ((new_x != view->geometry.x) ||
+                         (new_y != view->geometry.y)))   {
+                        weston_view_damage_below(view);
+                        weston_view_set_position(view, (float)new_x, (float)new_y);
+                        weston_surface_damage(eu->surface);
+                    }
+                    uifw_debug("ico_window_mgr_restack_layer:%3d(%d).%08x(%08x:%d) "
+                               "x/y=%d/%d w/h=%d/%d[%x]",
+                               el->layer, el->visible, eu->surfaceid, (int)eu->surface,
+                               eu->visible, (int)view->geometry.x,
+                               (int)view->geometry.y, eu->surface->width,
+                               eu->surface->height, eu->layertype);
                 }
-                uifw_debug("ico_window_mgr_restack_layer:%3d(%d).%08x(%08x:%d) "
-                           "x/y=%d/%d w/h=%d/%d %x",
-                           el->layer, el->visible, eu->surfaceid, (int)eu->surface,
-                           eu->visible, (int)eu->surface->geometry.x,
-                           (int)eu->surface->geometry.y, eu->surface->geometry.width,
-                           eu->surface->geometry.height, eu->layertype);
             }
         }
     }
+    wl_list_for_each (view, &wlayer->view_list, layer_link)   {
+uifw_debug("ico_window_mgr_restack_layer: panel_layer view %08x surf=%08x",
+        (int)view, (int)view->surface);
+    }
 
     /* damage(redraw) target surfacem if target exist   */
     if (usurf) {
@@ -1608,7 +1821,8 @@ ico_window_mgr_restack_layer(struct uifw_win_surface *usurf)
 WL_EXPORT   void
 ico_window_mgr_touch_layer(int omit)
 {
-    struct uifw_win_surface  *eu;
+    struct uifw_win_surface *eu;
+    struct weston_view      *ev;
 
     /* check current touch layer mode   */
     if ((_ico_win_mgr->touch_layer == NULL) ||
@@ -1619,15 +1833,16 @@ ico_window_mgr_touch_layer(int omit)
 
     wl_list_for_each (eu, &_ico_win_mgr->touch_layer->surface_list, ivi_layer) {
         if ((eu->surface == NULL) || (eu->mapped == 0)) continue;
+        ev = ico_ivi_get_primary_view(eu);
         if (omit != FALSE)  {
-            eu->animation.pos_x = (int)eu->surface->geometry.x;
-            eu->animation.pos_y = (int)eu->surface->geometry.y;
-            eu->surface->geometry.x = (float)(ICO_IVI_MAX_COORDINATE+1);
-            eu->surface->geometry.y = (float)(ICO_IVI_MAX_COORDINATE+1);
+            eu->animation.pos_x = (int)ev->geometry.x;
+            eu->animation.pos_y = (int)ev->geometry.y;
+            ev->geometry.x = (float)(ICO_IVI_MAX_COORDINATE+1);
+            ev->geometry.y = (float)(ICO_IVI_MAX_COORDINATE+1);
         }
         else    {
-            eu->surface->geometry.x = (float)eu->animation.pos_x;
-            eu->surface->geometry.y = (float)eu->animation.pos_y;
+            ev->geometry.x = (float)eu->animation.pos_x;
+            ev->geometry.y = (float)eu->animation.pos_y;
         }
     }
 }
@@ -2113,9 +2328,10 @@ 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 flags)
 {
-    struct uifw_client *uclient;
+    struct uifw_client      *uclient;
     struct uifw_win_surface *usurf;
-    struct weston_surface *es;
+    struct weston_surface   *es;
+    struct weston_view      *ev;
     int     op;
     int     retanima;
     int     oldx, oldy;
@@ -2190,6 +2406,7 @@ uifw_set_positionsize(struct wl_client *client, struct wl_resource *resource,
             if ((surfaceid != ICO_WINDOW_MGR_V_MAINSURFACE) &&
                 (uclient->manager == 0) && (uclient->privilege == 0))   uclient = NULL;
         }
+        ev = ico_ivi_get_primary_view(usurf);
         if (! uclient)  {
             if ((usurf->width > 0) && (usurf->height > 0))  {
                 win_mgr_surface_change_mgr(es, x, y, width, height);
@@ -2200,13 +2417,13 @@ uifw_set_positionsize(struct wl_client *client, struct wl_resource *resource,
             uifw_trace("uifw_set_positionsize: Initial Position/Size visible=%d",
                        usurf->visible);
             /* Initiale position is (0,0)   */
-            weston_surface_set_position(es, (float)(usurf->node_tbl->disp_x),
-                                        (float)(usurf->node_tbl->disp_y));
+            weston_view_set_position(ev, (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",
-                   (int)es->geometry.x, (int)es->geometry.y,
-                   (int)es->geometry.width, (int)es->geometry.height);
+                   (int)ev->geometry.x, (int)ev->geometry.y,
+                   (int)es->width, (int)es->height);
 
         usurf->animation.pos_x = usurf->x;
         usurf->animation.pos_y = usurf->y;
@@ -2220,23 +2437,23 @@ uifw_set_positionsize(struct wl_client *client, struct wl_resource *resource,
         usurf->height = height;
         if (_ico_win_mgr->num_manager <= 0) {
             /* no manager(HomeScreen), set geometory    */
-            weston_surface_set_position(es, (float)(usurf->node_tbl->disp_x + x),
-                                        (float)(usurf->node_tbl->disp_y + y));
+            weston_view_set_position(ev, (float)(usurf->node_tbl->disp_x + x),
+                                     (float)(usurf->node_tbl->disp_y + y));
         }
         if ((es->output) && (es->buffer_ref.buffer) &&
-            (es->geometry.width > 0) && (es->geometry.height > 0)) {
+            (es->width > 0) && (es->height > 0)) {
             uifw_trace("uifw_set_positionsize: Fixed Geometry, Change(Vis=%d)",
                        usurf->visible);
             if (usurf->visible) {
                 if ((flags & ICO_WINDOW_MGR_FLAGS_ANIMATION) &&
                     (win_mgr_hook_animation != NULL))   {
                     /* with animation   */
-                    if ((x != (usurf->surface->geometry.x - usurf->node_tbl->disp_x)) ||
-                        (y != (usurf->surface->geometry.y - usurf->node_tbl->disp_y)))  {
+                    if ((x != (ev->geometry.x - usurf->node_tbl->disp_x)) ||
+                        (y != (ev->geometry.y - usurf->node_tbl->disp_y)))  {
                         op = ICO_WINDOW_MGR_ANIMATION_OPMOVE;
                     }
-                    else if ((width != usurf->surface->geometry.width) ||
-                             (height != usurf->surface->geometry.height))   {
+                    else if ((width != usurf->surface->width) ||
+                             (height != usurf->surface->height))   {
                         op = ICO_WINDOW_MGR_ANIMATION_OPRESIZE;
                     }
                     else    {
@@ -2298,7 +2515,8 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource,
                  uint32_t surfaceid, int32_t visible, int32_t raise, int32_t flags)
 {
     struct uifw_win_surface *usurf;
-    struct uifw_client *uclient;
+    struct uifw_client      *uclient;
+    struct weston_view      *ev;
     int     restack;
     int     retanima;
     int     oldvisible;
@@ -2355,7 +2573,9 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource,
             usurf->visible = 1;
             uifw_trace("uifw_set_visible: Change to Visible");
 
-            ico_ivi_shell_set_toplevel(usurf->shsurf);
+            if (usurf->layertype != LAYER_TYPE_INPUTPANEL)  {
+                ico_ivi_shell_set_toplevel(usurf->shsurf);
+            }
 
             /* Weston surface configure                     */
             uifw_trace("uifw_set_visible: Visible to Weston WSurf=%08x,%d.%d/%d/%d/%d",
@@ -2404,7 +2624,8 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource,
             win_mgr_reset_focus(usurf);
 
             /* Weston surface configure                     */
-            weston_surface_damage_below(usurf->surface);
+            ev = ico_ivi_get_primary_view(usurf);
+            weston_view_damage_below(ev);
             ico_window_mgr_set_weston_surface(usurf, usurf->x, usurf->y,
                                               usurf->width, usurf->height);
 
@@ -2859,6 +3080,7 @@ uifw_set_layer_visible(struct wl_client *client, struct wl_resource *resource,
     struct uifw_win_layer   *el;
     struct uifw_win_layer   *new_el;
     struct uifw_win_surface *usurf;
+    struct weston_view      *ev;
     int     layertype = 0;
 
     if ((layer == ICO_WINDOW_MGR_LAYERTYPE_BACKGROUND) ||
@@ -2945,7 +3167,8 @@ uifw_set_layer_visible(struct wl_client *client, struct wl_resource *resource,
                 win_mgr_reset_focus(usurf);
             }
             /* Damage(redraw) target surface    */
-            weston_surface_damage_below(usurf->surface);
+            ev = ico_ivi_get_primary_view(usurf);
+            weston_view_damage_below(ev);
         }
     }
 
@@ -3045,22 +3268,23 @@ static void
 win_mgr_check_mapsurface(struct weston_animation *animation,
                          struct weston_output *output, uint32_t msecs)
 {
-    struct uifw_surface_map *sm;
+    struct uifw_surface_map *sm, *sm_tmp;
     uint32_t    curtime;
     int         wait = 99999999;
 
     /* check touch down counter     */
-    if (touch_check_seat)   {
-        if (touch_check_seat->num_tp > 10)  {
+    if ((touch_check_seat) &&
+        (touch_check_seat->touch))  {
+        if (touch_check_seat->touch->num_tp > 10)  {
             uifw_trace("win_mgr_check_mapsurface: illegal touch counter(num=%d), reset",
-                       (int)touch_check_seat->num_tp);
-            touch_check_seat->num_tp = 0;
+                       (int)touch_check_seat->touch->num_tp);
+            touch_check_seat->touch->num_tp = 0;
         }
     }
 
     /* check all mapped surfaces    */
     curtime = weston_compositor_get_time();
-    wl_list_for_each (sm, &_ico_win_mgr->map_list, map_link) {
+    wl_list_for_each_safe (sm, sm_tmp, &_ico_win_mgr->map_list, map_link)   {
         uifw_detail("win_mgr_check_mapsurface: sm=%08x surf=%08x",
                     (int)sm, sm->usurf->surfaceid);
         win_mgr_change_mapsurface(sm, 0, curtime);
@@ -3114,6 +3338,7 @@ win_mgr_change_mapsurface(struct uifw_surface_map *sm, int event, uint32_t curti
     struct uifw_intel_region  *dri_region;
     struct uifw_gl_surface_state *gl_state;
     struct weston_surface   *es;
+    struct weston_view      *ev;
     struct wl_shm_buffer    *shm_buffer;
     uint32_t    eglname;
     int         width;
@@ -3370,25 +3595,32 @@ win_mgr_change_mapsurface(struct uifw_surface_map *sm, int event, uint32_t curti
                         sm->eventque = 0;
                     }
                     else    {
-                        if (height > sm->height)    {
-                            height = sm->height;
-                        }
-                        if ((*(_ico_win_mgr->compositor->renderer->read_surface_pixels))
-                                    (es, PIXMAN_a8r8g8b8, p->image,
-                                     0, 0, sm->width, height) != 0) {
-                            uifw_debug("win_mgr_change_mapsurface: Error read pixel %s.%08x",
-                                       sm->usurf->uclient->appid, sm->usurf->surfaceid);
+                        ev = ico_ivi_get_primary_view(sm->usurf);
+                        if ((ev == NULL) || (ev->output == NULL))   {
+                            uifw_debug("win_mgr_change_mapsurface: surface %08x has no view",
+                                       sm->usurf->surfaceid);
                             event = ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR;
-                            sm->eventque = 0;
                         }
                         else    {
-                            uifw_detail("win_mgr_change_mapsurface: PIX read pixels(%d)",
-                                        idx+1);
-                            p->surfaceid = sm->usurf->surfaceid;
-                            p->settime = curtime;
-                            p->width = sm->width;
-                            p->height = height;
-                            sm->eglname = idx + 1;
+                            if (height > sm->height)    {
+                                height = sm->height;
+                            }
+                            if (ico_read_surface_pixels(es, PIXMAN_a8r8g8b8, p->image,
+                                                        0, 0, sm->width, height) != 0)  {
+                                uifw_debug("win_mgr_change_mapsurface: Error read pixel %s.%08x",
+                                           sm->usurf->uclient->appid, sm->usurf->surfaceid);
+                                event = ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR;
+                                sm->eventque = 0;
+                            }
+                            else    {
+                                uifw_detail("win_mgr_change_mapsurface: PIX read pixels(%d)",
+                                            idx+1);
+                                p->surfaceid = sm->usurf->surfaceid;
+                                p->settime = curtime;
+                                p->width = sm->width;
+                                p->height = height;
+                                sm->eglname = idx + 1;
+                            }
                         }
                     }
                 }
@@ -3559,6 +3791,13 @@ uifw_map_surface(struct wl_client *client, struct wl_resource *resource,
         uifw_trace("uifw_map_surface: Leave(surface=%08x dose not exist)", surfaceid);
         return;
     }
+    if (usurf->layertype == LAYER_TYPE_INPUTPANEL)  {
+        /* input panel surface dose not suport, error   */
+        ico_window_mgr_send_map_surface(resource, ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR,
+                                        surfaceid, 1, 0, 0, 0, 0, 0);
+        uifw_trace("uifw_map_surface: Leave(surface=%08x is input panel)", surfaceid);
+        return;
+    }
 
     /* check if buffered        */
     es = usurf->surface;
@@ -3576,15 +3815,6 @@ uifw_map_surface(struct wl_client *client, struct wl_resource *resource,
     if ((_ico_ivi_gpu_type == ICO_GPUTYPE_NOACCELERATION) ||
         (gl_state == NULL) || (gl_state->buffer_type == BUFFER_TYPE_SHM))   {
         /* No Acceleration or wl_shm_buffer support ReadPixels  */
-        if ((_ico_win_mgr->compositor->renderer == NULL) ||
-            (_ico_win_mgr->compositor->renderer->read_surface_pixels == NULL) ||
-            (uclient->shmbuf == NULL))  {
-            ico_window_mgr_send_map_surface(resource, ICO_WINDOW_MGR_MAP_SURFACE_EVENT_ERROR,
-                                            surfaceid, 4, 0, 0, 0, 0, 0);
-            uifw_trace("uifw_map_surface: Leave(surface(%08x) not support ReadPixels)",
-                       surfaceid);
-            return;
-        }
         if ((gl_state != NULL) && (gl_state->buffer_type == BUFFER_TYPE_SHM))   {
             maptype = -1;
             format = 0xff;
@@ -3818,17 +4048,7 @@ uifw_unmap_surface(struct wl_client *client, struct wl_resource *resource,
 
     wl_list_for_each_safe (sm, sm_tmp, &usurf->surf_map, surf_link) {
         if (((uclient != NULL) && (sm->uclient != uclient)))   continue;
-        /* send unmap event                     */
-        if ((uclient != NULL) && (uclient->mgr != NULL))    {
-            uifw_trace("uifw_unmap_surface: send UNMAP event(ev=%d surf=%08x name=%08x "
-                       "w/h/s=%d/%d/%d format=%x",
-                       ICO_WINDOW_MGR_MAP_SURFACE_EVENT_UNMAP, surfaceid,
-                       sm->eglname, sm->width, sm->height, sm->stride, sm->format);
-            ico_window_mgr_send_map_surface(uclient->mgr->resource,
-                                            ICO_WINDOW_MGR_MAP_SURFACE_EVENT_UNMAP,
-                                            surfaceid, sm->type, sm->eglname, sm->width,
-                                            sm->height, sm->stride, sm->format);
-        }
+
         if ((sm->type != ICO_WINDOW_MGR_MAP_TYPE_EGL) &&
             (sm->uclient->shmbuf != NULL))  {
             /* reset shared memory buffer   */
@@ -3902,6 +4122,7 @@ win_mgr_change_surface(struct weston_surface *surface, const int to, const int m
 {
     struct uifw_win_surface *usurf;
     struct weston_surface   *es;
+    struct weston_view      *ev;
     int     x;
     int     y;
     int     repaint = 0;
@@ -3921,25 +4142,25 @@ win_mgr_change_surface(struct weston_surface *surface, const int to, const int m
     }
 
     /* set surface size     */
+    ev = ico_ivi_get_primary_view(usurf);
     uifw_debug("win_mgr_change_surface: set surface x/y=%d/%d=>%d/%d w/h=%d/%d=>%d/%d",
-               (int)es->geometry.x, (int)es->geometry.y, usurf->x, usurf->y,
-               usurf->width, usurf->height, es->geometry.width, es->geometry.height);
+               (int)ev->geometry.x, (int)ev->geometry.y, usurf->x, usurf->y,
+               es->width, es->height, usurf->width, usurf->height);
     if ((usurf->width <= 0) || (usurf->height <= 0))    {
-        usurf->width = es->geometry.width;
-        usurf->height = es->geometry.height;
+        usurf->width = es->width;
+        usurf->height = es->height;
     }
     win_mgr_set_scale(usurf);
     if (usurf->visible) {
-        weston_surface_set_position(usurf->surface,
-                                    (float)(usurf->node_tbl->disp_x +
-                                            usurf->x + usurf->xadd),
-                                    (float)(usurf->node_tbl->disp_y +
-                                            usurf->y + usurf->yadd));
+        weston_view_set_position(ev, (float)(usurf->node_tbl->disp_x +
+                                             usurf->x + usurf->xadd),
+                                     (float)(usurf->node_tbl->disp_y +
+                                             usurf->y + usurf->yadd));
         ico_window_mgr_restack_layer(usurf);
     }
     else    {
-        weston_surface_set_position(usurf->surface, (float)(ICO_IVI_MAX_COORDINATE+1),
-                                    (float)(ICO_IVI_MAX_COORDINATE+1));
+        weston_view_set_position(ev, (float)(ICO_IVI_MAX_COORDINATE+1),
+                                     (float)(ICO_IVI_MAX_COORDINATE+1));
     }
 
     /* send wayland event to client     */
@@ -3967,9 +4188,9 @@ win_mgr_change_surface(struct weston_surface *surface, const int to, const int m
     }
     /* change geometry if request from manager  */
     if (manager)    {
-        if ((usurf->width != es->geometry.width) ||
-            (usurf->height != es->geometry.height) ||
-            (es->geometry.x != (float)x) || (es->geometry.y != (float)y))   {
+        if ((usurf->width != es->width) ||
+            (usurf->height != es->height) ||
+            ((int)ev->geometry.x != x) || ((int)ev->geometry.y != y))   {
             win_mgr_surface_configure(usurf, (float)x, (float)y, usurf->width, usurf->height);
             repaint ++;
         }
@@ -3984,15 +4205,15 @@ win_mgr_change_surface(struct weston_surface *surface, const int to, const int m
         }
         else    {
             ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CONFIGURE,
-                                    usurf, (int)es->geometry.x, (int)es->geometry.y,
-                                    es->geometry.width, es->geometry.height, 1);
+                                    usurf, (int)ev->geometry.x, (int)ev->geometry.y,
+                                    es->width, es->height, 1);
         }
     }
 
     /* change geometry if request from client   */
     if (! manager)  {
-        if ((usurf->width != es->geometry.width) || (usurf->height != es->geometry.height) ||
-            (es->geometry.x != (float)x) || (es->geometry.y != (float)y))   {
+        if ((usurf->width != es->width) || (usurf->height != es->height) ||
+            ((int)ev->geometry.x != x) || ((int)ev->geometry.y != y))   {
             win_mgr_surface_configure(usurf, x, y, usurf->width, usurf->height);
             repaint ++;
         }
@@ -4022,23 +4243,25 @@ win_mgr_surface_configure(struct uifw_win_surface *usurf,
                           int x, int y, int width, int height)
 {
     struct weston_surface   *es;
+    struct weston_view      *ev;
 
     es = usurf->surface;
     if ((es != NULL) && (es->buffer_ref.buffer))  {
         if (usurf->client_width == 0)   {
-            usurf->client_width = es->geometry.width;
+            usurf->client_width = es->width;
             if (usurf->client_width == 0)
-                usurf->client_width = weston_surface_buffer_width(es);
+                usurf->client_width = ico_ivi_surface_buffer_width(es);
         }
         if (usurf->client_height == 0)  {
-            usurf->client_height = es->geometry.height;
+            usurf->client_height = es->height;
             if (usurf->client_height == 0)
-                usurf->client_height = weston_surface_buffer_height(es);
+                usurf->client_height = ico_ivi_surface_buffer_height(es);
         }
 
         /* not set geometry width/height    */
         win_mgr_set_scale(usurf);
-        weston_surface_set_position(es, x + usurf->xadd, y + usurf->yadd);
+        ev = ico_ivi_get_primary_view(usurf);
+        weston_view_set_position(ev, x + usurf->xadd, y + usurf->yadd);
     }
 }
 
@@ -4066,10 +4289,9 @@ win_mgr_shell_configure(struct weston_surface *surface)
         return;
     }
 
-    usurf->client_width = surface->geometry.width;
-    usurf->client_height = surface->geometry.height;
-    buf_width = weston_surface_buffer_width(surface);
-    buf_height = weston_surface_buffer_height(surface);
+    usurf->client_width = surface->width;
+    usurf->client_height = surface->height;
+    ico_ivi_surface_buffer_size(surface, &buf_width, &buf_height);
     uifw_trace("win_mgr_shell_configure: %08x client w/h=%d/%d buf=%d/%d",
                usurf->surfaceid,
                usurf->client_width, usurf->client_height, buf_width, buf_height);
@@ -4528,20 +4750,17 @@ win_mgr_fullscreen(int event, struct weston_surface *surface)
                                     usurf->width, usurf->height, 1);
         }
         break;
-    case SHELL_FULLSCREEN_STACK:        /* change surface to top of layer   */
-        uifw_trace("win_mgr_fullscreen: %08x SHELL_FULLSCREEN_STACK", usurf->surfaceid);
-        if (usurf->mapped == 0) {
-            uifw_trace("win_mgr_fullscreen: not map, change to map");
-            width = usurf->node_tbl->disp_width;
-            height = usurf->node_tbl->disp_height;
-            sx = 0;
-            sy = 0;
-            win_mgr_surface_map(usurf->surface, &width, &height, &sx, &sy);
-        }
-        if ((usurf->surface != NULL) && (usurf->mapped != 0) &&
-            (usurf->surface->buffer_ref.buffer != NULL))    {
-            /* fullscreen surface raise         */
-            win_mgr_set_raise(usurf, 1);
+    case SHELL_FULLSCREEN_UNSET:        /* change surface to normal screen  */
+        uifw_trace("win_mgr_fullscreen: %08x SHELL_FULLSCREEN_UNSET", usurf->surfaceid);
+        if (usurf->layertype == LAYER_TYPE_FULLSCREEN)  {
+            ico_window_mgr_set_visible(usurf, 2);
+            usurf->layertype = usurf->old_layertype;
+            win_mgr_set_layer(usurf, usurf->old_layer->layer);
+            win_mgr_change_surface(usurf->surface, -1, 1);
+            /* send event to HomeScreen         */
+            ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CONFIGURE,
+                                    usurf, usurf->x, usurf->y,
+                                    usurf->width, usurf->height, 0);
         }
         break;
     case SHELL_FULLSCREEN_CONF:         /* configure full screen surface    */
@@ -4606,7 +4825,7 @@ win_mgr_reset_focus(struct uifw_win_surface *usurf)
  *
  * @param[in]   usurf       UIFW surface
  * @param[in]   visible     bit 0: visible(=1)/unvisible(=0)
- *                          bit 1: widht anima(=1)/without anima(=0)
+ *                          bit 1: width anima(=1)/without anima(=0)
  * @return      none
  */
 /*--------------------------------------------------------------------------*/
@@ -5053,14 +5272,15 @@ static int
 win_mgr_set_scale(struct uifw_win_surface *usurf)
 {
     struct weston_surface   *es;
+    struct weston_view      *ev;
     float   scalex;
     float   scaley;
     int     ret = 0;
 
     es = usurf->surface;
     if ((es != NULL) && (es->buffer_ref.buffer))  {
-        if (usurf->client_width == 0)   usurf->client_width = es->geometry.width;
-        if (usurf->client_height == 0)  usurf->client_height = es->geometry.height;
+        if (usurf->client_width == 0)   usurf->client_width = es->width;
+        if (usurf->client_height == 0)  usurf->client_height = es->height;
         if ((usurf->client_width > 0) && (usurf->client_height > 0))    {
             scalex = (float)usurf->width / (float)usurf->client_width;
             scaley = (float)usurf->height / (float)usurf->client_height;
@@ -5094,20 +5314,24 @@ win_mgr_set_scale(struct uifw_win_surface *usurf)
                     }
                 }
             }
-            uifw_trace("win_mgr_set_scale: %08x fixed aspect x/yadd=%d/%d",
+            uifw_debug("win_mgr_set_scale: %08x fixed aspect x/yadd=%d/%d",
                        usurf->surfaceid, usurf->xadd, usurf->yadd);
         }
         if ((scalex != usurf->scalex) || (scaley != usurf->scaley)) {
             usurf->scalex = scalex;
             usurf->scaley = scaley;
+            ev = ico_ivi_get_primary_view(usurf);
             if ((scalex != 1.0f) || (scaley != 1.0f))   {
                 weston_matrix_init(&usurf->transform.matrix);
                 weston_matrix_scale(&usurf->transform.matrix, scalex, scaley, 1.0f);
                 uifw_trace("win_mgr_set_scale: change scale(%d)", usurf->set_transform);
+uifw_trace("ev=%08x transformation_list=%08x next=%08x prev=%08x",
+    (int)ev, (int)&ev->geometry.transformation_list,
+    (int)ev->geometry.transformation_list.next, (int)ev->geometry.transformation_list.prev);
                 if (usurf->set_transform == 0)  {
                     usurf->set_transform = 1;
                     wl_list_init(&usurf->transform.link);
-                    wl_list_insert(&es->geometry.transformation_list, &usurf->transform.link);
+                    wl_list_insert(&ev->geometry.transformation_list, &usurf->transform.link);
                 }
             }
             else if (usurf->set_transform != 0) {
@@ -5115,9 +5339,9 @@ win_mgr_set_scale(struct uifw_win_surface *usurf)
                 usurf->set_transform = 0;
                 wl_list_remove(&usurf->transform.link);
             }
-            weston_surface_geometry_dirty(es);
-            weston_surface_update_transform(es);
-            weston_surface_damage_below(es);
+            weston_view_geometry_dirty(ev);
+            weston_view_update_transform(ev);
+            weston_view_damage_below(ev);
             weston_surface_damage(es);
             ret = 1;
         }
index 9a081ca..96b7e57 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2013 TOYOTA MOTOR CORPORATION.
+ * Copyright © 2013-2014 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
index 08bed30..f390bcb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2013 TOYOTA MOTOR CORPORATION.
+ * Copyright © 2013-2014 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
@@ -72,7 +72,7 @@ struct  uifw_win_layer  {
     char        visible;                    /* visibility                           */
     char        layertype;                  /* layer type                           */
     char        res[2];                     /* (unused)                             */
-    struct wl_list surface_list;            /* Surfacae list                        */
+    struct wl_list surface_list;            /* Surface list                         */
     struct wl_list link;                    /* Link pointer for layer list          */
 };
 
@@ -238,6 +238,14 @@ void ico_window_mgr_touch_layer(int omit);
 int ico_window_mgr_is_visible(struct uifw_win_surface *usurf);
                                             /* set active surface                   */
 void ico_window_mgr_active_surface(struct weston_surface *surface);
+                                            /* get buffer width                     */
+int ico_ivi_surface_buffer_width(struct weston_surface *es);
+                                            /* get buffer height                    */
+int ico_ivi_surface_buffer_height(struct weston_surface *es);
+                                            /* get buffer size                      */
+void ico_ivi_surface_buffer_size(struct weston_surface *es, int *width, int *height);
+                                            /* get surface primary view             */
+struct weston_view *ico_ivi_get_primary_view(struct uifw_win_surface *usurf);
                                             /* set window animation hook            */
 void ico_window_mgr_set_hook_animation(int (*hook_animation)(const int op, void *data));
                                             /* set surface attribute change hook    */
index d94fa58..4eb81ba 100644 (file)
@@ -5,7 +5,7 @@ modules=error_but_no_problem_for_test.so
 
 [shell]
 num-workspaces=1
-shell-exe=
+client=
 locking=false
 animation=zoom
 startup-animation=fade