diff options
-rw-r--r-- | Makefile.am | 17 | ||||
-rw-r--r-- | ivi-shell/ivi-layout-export.h | 964 | ||||
-rw-r--r-- | ivi-shell/ivi-layout.c | 2798 |
3 files changed, 3778 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index 279fffc2..e8bcb1bd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -703,7 +703,8 @@ endif if ENABLE_IVI_SHELL module_LTLIBRARIES += \ - $(ivi_shell) + $(ivi_shell) \ + $(ivi_layout) ivi_shell = ivi-shell.la ivi_shell_la_LDFLAGS = -module -avoid-version @@ -719,6 +720,20 @@ nodist_ivi_shell_la_SOURCES = \ BUILT_SOURCES += $(nodist_ivi_shell_la_SOURCES) +ivi_layout = ivi-layout.la +ivi_layout_la_LDFLAGS = -module -avoid-version +ivi_layout_la_LIBADD = $(COMPOSITOR_LIBS) $(IVI_SHELL_LIBS) libshared.la +ivi_layout_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) $(IVI_SHELL_CFLAGS) +ivi_layout_la_SOURCES = \ + ivi-shell/ivi-layout.h \ + ivi-shell/ivi-layout-export.h \ + ivi-shell/ivi-layout.c +nodist_ivi_layout_la_SOURCES = \ + protocol/ivi-application-protocol.c \ + protocol/ivi-application-server-protocol.h + +BUILT_SOURCES += $(nodist_ivi_layout_la_SOURCES) + endif diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h new file mode 100644 index 00000000..0f95f53f --- /dev/null +++ b/ivi-shell/ivi-layout-export.h @@ -0,0 +1,964 @@ +/* + * Copyright (C) 2013 DENSO 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. + */ + +/** + * The ivi-layout library supports API set of controlling properties of + * surface and layer which groups surfaces. An unique ID whose type is integer + * is required to create surface and layer. With the unique ID, surface and + * layer are identified to control them. The API set consists of APIs to control + * properties of surface and layers about followings, + * - visibility. + * - opacity. + * - clipping (x,y,width,height). + * - position and size of it to be displayed. + * - orientation per 90 degree. + * - add or remove surfaces to a layer. + * - order of surfaces/layers in layer/screen to be displayed. + * - commit to apply property changes. + * - notifications of property change. + * + * Management of surfaces and layers grouping these surfaces are common way in + * In-Vehicle Infotainment system, which integrate several domains in one system. + * A layer is allocated to a domain in order to control application surfaces + * grouped to the layer all together. + */ + +#ifndef _IVI_LAYOUT_EXPORT_H_ +#define _IVI_LAYOUT_EXPORT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "compositor.h" +#include "ivi-layout.h" + +struct ivi_layout_SurfaceProperties +{ + float opacity; + uint32_t sourceX; + uint32_t sourceY; + uint32_t sourceWidth; + uint32_t sourceHeight; + uint32_t origSourceWidth; + uint32_t origSourceHeight; + int32_t destX; + int32_t destY; + uint32_t destWidth; + uint32_t destHeight; + uint32_t orientation; + uint32_t visibility; + uint32_t frameCounter; + uint32_t drawCounter; + uint32_t updateCounter; + uint32_t pixelformat; + uint32_t nativeSurface; + uint32_t inputDevicesAcceptance; + uint32_t chromaKeyEnabled; + uint32_t chromaKeyRed; + uint32_t chromaKeyGreen; + uint32_t chromaKeyBlue; + int32_t creatorPid; +}; + +struct ivi_layout_LayerProperties +{ + float opacity; + uint32_t sourceX; + uint32_t sourceY; + uint32_t sourceWidth; + uint32_t sourceHeight; + uint32_t origSourceWidth; + uint32_t origSourceHeight; + int32_t destX; + int32_t destY; + uint32_t destWidth; + uint32_t destHeight; + uint32_t orientation; + uint32_t visibility; + uint32_t type; + uint32_t chromaKeyEnabled; + uint32_t chromaKeyRed; + uint32_t chromaKeyGreen; + uint32_t chromaKeyBlue; + int32_t creatorPid; +}; + +struct ivi_layout_layer; +struct ivi_layout_screen; + +typedef struct ivi_layout_surface* ivi_layout_surface_ptr; +typedef struct ivi_layout_layer* ivi_layout_layer_ptr; +typedef struct ivi_layout_screen* ivi_layout_screen_ptr; + +enum ivi_layout_notification_mask { + IVI_NOTIFICATION_NONE = 0, + IVI_NOTIFICATION_OPACITY = (1 << 1), + IVI_NOTIFICATION_SOURCE_RECT = (1 << 2), + IVI_NOTIFICATION_DEST_RECT = (1 << 3), + IVI_NOTIFICATION_DIMENSION = (1 << 4), + IVI_NOTIFICATION_POSITION = (1 << 5), + IVI_NOTIFICATION_ORIENTATION = (1 << 6), + IVI_NOTIFICATION_VISIBILITY = (1 << 7), + IVI_NOTIFICATION_PIXELFORMAT = (1 << 8), + IVI_NOTIFICATION_ADD = (1 << 9), + IVI_NOTIFICATION_REMOVE = (1 << 10), + IVI_NOTIFICATION_ALL = 0xFFFF +}; + +typedef void(*layerPropertyNotificationFunc)(struct ivi_layout_layer *ivilayer, + struct ivi_layout_LayerProperties*, + enum ivi_layout_notification_mask mask, + void *userdata); + +typedef void(*surfacePropertyNotificationFunc)(struct ivi_layout_surface *ivisurf, + struct ivi_layout_SurfaceProperties*, + enum ivi_layout_notification_mask mask, + void *userdata); + +typedef void(*layerCreateNotificationFunc)(struct ivi_layout_layer *ivilayer, + void *userdata); + +typedef void(*layerRemoveNotificationFunc)(struct ivi_layout_layer *ivilayer, + void *userdata); + +typedef void(*surfaceCreateNotificationFunc)(struct ivi_layout_surface *ivisurf, + void *userdata); + +typedef void(*surfaceRemoveNotificationFunc)(struct ivi_layout_surface *ivisurf, + void *userdata); + +typedef void(*surfaceConfigureNotificationFunc)(struct ivi_layout_surface *ivisurf, + void *userdata); + +/** + * \brief to be called by ivi-shell in order to set initail view of + * weston_surface. + */ +/* +struct weston_view * +ivi_layout_get_weston_view(struct ivi_layout_surface *surface); +*/ + +/** + * \brief initialize ivi-layout + */ +/* +void +ivi_layout_initWithCompositor(struct weston_compositor *ec); +*/ + +/** + * \brief register for notification when layer is created + */ +int32_t +ivi_layout_addNotificationCreateLayer(layerCreateNotificationFunc callback, + void *userdata); + +void +ivi_layout_removeNotificationCreateLayer(layerCreateNotificationFunc callback, + void *userdata); + +/** + * \brief register for notification when layer is removed + */ +int32_t +ivi_layout_addNotificationRemoveLayer(layerRemoveNotificationFunc callback, + void *userdata); + +void +ivi_layout_removeNotificationRemoveLayer(layerRemoveNotificationFunc callback, + void *userdata); + +/** + * \brief register for notification when surface is created + */ +int32_t +ivi_layout_addNotificationCreateSurface(surfaceCreateNotificationFunc callback, + void *userdata); + +void +ivi_layout_removeNotificationCreateSurface(surfaceCreateNotificationFunc callback, + void *userdata); + +/** + * \brief register for notification when surface is removed + */ +int32_t +ivi_layout_addNotificationRemoveSurface(surfaceRemoveNotificationFunc callback, + void *userdata); + +void +ivi_layout_removeNotificationRemoveSurface(surfaceRemoveNotificationFunc callback, + void *userdata); + +/** + * \brief register for notification when surface is configured + */ +int32_t +ivi_layout_addNotificationConfigureSurface(surfaceConfigureNotificationFunc callback, + void *userdata); + +void +ivi_layout_removeNotificationConfigureSurface(surfaceConfigureNotificationFunc callback, + void *userdata); + +/** + * \brief get id of surface from ivi_layout_surface + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +uint32_t +ivi_layout_getIdOfSurface(struct ivi_layout_surface *ivisurf); + +/** + * \brief get id of layer from ivi_layout_layer + * + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +uint32_t +ivi_layout_getIdOfLayer(struct ivi_layout_layer *ivilayer); + +/** + * \brief get ivi_layout_layer from id of layer + * + * \return (struct ivi_layout_layer *) + * if the method call was successful + * \return NULL if the method call was failed + */ +struct ivi_layout_layer * +ivi_layout_getLayerFromId(uint32_t id_layer); + +/** + * \brief get ivi_layout_surface from id of surface + * + * \return (struct ivi_layout_surface *) + * if the method call was successful + * \return NULL if the method call was failed + */ +struct ivi_layout_surface * +ivi_layout_getSurfaceFromId(uint32_t id_surface); + +/** + * \brief get ivi_layout_screen from id of screen + * + * \return (struct ivi_layout_screen *) + * if the method call was successful + * \return NULL if the method call was failed + */ +struct ivi_layout_screen * +ivi_layout_getScreenFromId(uint32_t id_screen); + +/** + * \brief Get the screen resolution of a specific screen + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_getScreenResolution(struct ivi_layout_screen *iviscrn, + uint32_t *pWidth, + uint32_t *pHeight); + +/** + * \brief register for notification on property changes of surface + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceAddNotification(struct ivi_layout_surface *ivisurf, + surfacePropertyNotificationFunc callback, + void *userdata); + +/** + * \brief remove notification on property changes of surface + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceRemoveNotification(struct ivi_layout_surface *ivisurf); + +/** + * \brief Create a surface + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +/* +struct ivi_layout_surface * +ivi_layout_surfaceCreate(struct weston_surface *wl_surface, + uint32_t id_surface); +*/ + +/** + * \brief Set the native content of an application to be used as surface content. + * If wl_surface is NULL, remove the native content of a surface + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +/* +int32_t +ivi_layout_surfaceSetNativeContent(struct weston_surface *wl_surface, + uint32_t width, + uint32_t height, + uint32_t id_surface); +*/ + +/** + * \brief initialize ivi_layout_surface dest/source width and height + */ +/* +void +ivi_layout_surfaceConfigure(struct ivi_layout_surface *ivisurf, + uint32_t width, uint32_t height); +*/ + +/** + * \brief Remove a surface + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceRemove(struct ivi_layout_surface *ivisurf); + +/** + * \brief Set from which kind of devices the surface can accept input events. + * By default, a surface accept input events from all kind of devices (keyboards, pointer, ...) + * By calling this function, you can adjust surface preferences. Note that this function only + * adjust the acceptance for the specified devices. Non specified are keept untouched. + * + * Typicall use case for this function is when dealing with pointer or touch events. + * Those are normally dispatched to the first visible surface below the coordinate. + * If you want a different behavior (i.e. forward events to an other surface below the coordinate, + * you can set all above surfaces to refuse input events) + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_UpdateInputEventAcceptanceOn(struct ivi_layout_surface *ivisurf, + uint32_t devices, + uint32_t acceptance); + +/** + * \brief Get the layer properties + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_getPropertiesOfLayer(struct ivi_layout_layer *ivilayer, + struct ivi_layout_LayerProperties *pLayerProperties); + +/** + * \brief Get the number of hardware layers of a screen + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_getNumberOfHardwareLayers(uint32_t id_screen, + uint32_t *pNumberOfHardwareLayers); + +/** + * \brief Get the screens + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_getScreens(uint32_t *pLength, ivi_layout_screen_ptr **ppArray); + +/** + * \brief Get the screens under the given layer + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_getScreensUnderLayer(struct ivi_layout_layer *ivilayer, + uint32_t *pLength, + ivi_layout_screen_ptr **ppArray); + +/** + * \brief Get all Layers which are currently registered and managed by the services + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_getLayers(uint32_t *pLength, ivi_layout_layer_ptr **ppArray); + +/** + * \brief Get all Layers of the given screen + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_getLayersOnScreen(struct ivi_layout_screen *iviscrn, + uint32_t *pLength, + ivi_layout_layer_ptr **ppArray); + +/** + * \brief Get all Layers under the given surface + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_getLayersUnderSurface(struct ivi_layout_surface *ivisurf, + uint32_t *pLength, + ivi_layout_layer_ptr **ppArray); + +/** + * \brief Get all Surfaces which are currently registered and managed by the services + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_getSurfaces(uint32_t *pLength, ivi_layout_surface_ptr **ppArray); + +/** + * \brief Get all Surfaces which are currently registered to a given layer and are managed by the services + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_getSurfacesOnLayer(struct ivi_layout_layer *ivilayer, + uint32_t *pLength, + ivi_layout_surface_ptr **ppArray); + +/** + * \brief Create a layer which should be managed by the service + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +struct ivi_layout_layer * +ivi_layout_layerCreateWithDimension(uint32_t id_layer, + uint32_t width, uint32_t height); + +/** + * \brief Removes a layer which is currently managed by the service + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerRemove(struct ivi_layout_layer *ivilayer); + +/** + * \brief Get the current type of the layer. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerGetType(struct ivi_layout_layer *ivilayer, + uint32_t *pLayerType); + +/** + * \brief Set the visibility of a layer. If a layer is not visible, the layer and its + * surfaces will not be rendered. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerSetVisibility(struct ivi_layout_layer *ivilayer, + uint32_t newVisibility); + +/** + * \brief Get the visibility of a layer. If a layer is not visible, the layer and its + * surfaces will not be rendered. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerGetVisibility(struct ivi_layout_layer *ivilayer, + uint32_t *pVisibility); + +/** + * \brief Set the opacity of a layer. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerSetOpacity(struct ivi_layout_layer *ivilayer, float opacity); + +/** + * \brief Get the opacity of a layer. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerGetOpacity(struct ivi_layout_layer *ivilayer, float *pOpacity); + +/** + * \brief Set the area of a layer which should be used for the rendering. + * Only this part will be visible. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerSetSourceRectangle(struct ivi_layout_layer *ivilayer, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height); + +/** + * \brief Set the destination area on the display for a layer. + * The layer will be scaled and positioned to this rectangle for rendering + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerSetDestinationRectangle(struct ivi_layout_layer *ivilayer, + int32_t x, int32_t y, + uint32_t width, uint32_t height); + +/** + * \brief Get the horizontal and vertical dimension of the layer. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerGetDimension(struct ivi_layout_layer *ivilayer, + uint32_t *pDimension); + +/** + * \brief Set the horizontal and vertical dimension of the layer. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerSetDimension(struct ivi_layout_layer *ivilayer, + uint32_t *pDimension); + +/** + * \brief Get the horizontal and vertical position of the layer. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerGetPosition(struct ivi_layout_layer *ivilayer, + int32_t *pPosition); + +/** + * \brief Sets the horizontal and vertical position of the layer. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerSetPosition(struct ivi_layout_layer *ivilayer, + int32_t *pPosition); + +/** + * \brief Sets the orientation of a layer. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerSetOrientation(struct ivi_layout_layer *ivilayer, + uint32_t orientation); + +/** + * \brief Gets the orientation of a layer. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerGetOrientation(struct ivi_layout_layer *ivilayer, + uint32_t *pOrientation); + +/** + * \brief Sets the color value which defines the transparency value. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerSetChromaKey(struct ivi_layout_layer *ivilayer, + uint32_t* pColor); + +/** + * \brief Sets render order of surfaces within one layer + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerSetRenderOrder(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface **pSurface, + uint32_t number); + +/** + * \brief Get the capabilities of a layer + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerGetCapabilities(struct ivi_layout_layer *ivilayer, + uint32_t *pCapabilities); + +/** + * \brief Get the possible capabilities of a layertype + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerTypeGetCapabilities(uint32_t layerType, + uint32_t *pCapabilities); + +/** + * \brief Create the logical surface, which has no native buffer associated + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceInitialize(struct ivi_layout_surface **pSurface); + +/** + * \brief Set the visibility of a surface. + * If a surface is not visible it will not be rendered. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceSetVisibility(struct ivi_layout_surface *ivisurf, + uint32_t newVisibility); + +/** + * \brief Get the visibility of a surface. + * If a surface is not visible it will not be rendered. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceGetVisibility(struct ivi_layout_surface *ivisurf, + uint32_t *pVisibility); + +/** + * \brief Set the opacity of a surface. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceSetOpacity(struct ivi_layout_surface *ivisurf, + float opacity); + +/** + * \brief Get the opacity of a surface. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceGetOpacity(struct ivi_layout_surface *ivisurf, + float *pOpacity); + +/** + * \brief Set the keyboard focus on a certain surface + * To receive keyboard events, 2 conditions must be fulfilled: + * 1- The surface must accept events from keyboard. See ilm_UpdateInputEventAcceptanceOn + * 2- The keyboard focus must be set on that surface + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_SetKeyboardFocusOn(struct ivi_layout_surface *ivisurf); + +/** + * \brief Get the indentifier of the surface which hold the keyboard focus + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_GetKeyboardFocusSurfaceId(struct ivi_layout_surface **pSurfaceId); + +/** + * \brief Set the destination area of a surface within a layer for rendering. + * The surface will be scaled to this rectangle for rendering. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceSetDestinationRectangle(struct ivi_layout_surface *ivisurf, + int32_t x, int32_t y, + uint32_t width, uint32_t height); + +/** + * \brief Set the horizontal and vertical dimension of the surface. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceSetDimension(struct ivi_layout_surface *ivisurf, + uint32_t *pDimension); + +/** + * \brief Get the horizontal and vertical dimension of the surface. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceGetDimension(struct ivi_layout_surface *ivisurf, + uint32_t *pDimension); + +/** + * \brief Sets the horizontal and vertical position of the surface. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceSetPosition(struct ivi_layout_surface *ivisurf, + int32_t *pPosition); + +/** + * \brief Get the horizontal and vertical position of the surface. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceGetPosition(struct ivi_layout_surface *ivisurf, + int32_t *pPosition); + +/** + * \brief Sets the orientation of a surface. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceSetOrientation(struct ivi_layout_surface *ivisurf, + uint32_t orientation); + +/** + * \brief Gets the orientation of a surface. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceGetOrientation(struct ivi_layout_surface *ivisurf, + uint32_t *pOrientation); + +/** + * \brief Gets the pixelformat of a surface. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceGetPixelformat(struct ivi_layout_layer *ivisurf, + uint32_t *pPixelformat); + +/** + * \brief Sets the color value which defines the transparency value of a surface. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceSetChromaKey(struct ivi_layout_surface *ivisurf, + uint32_t* pColor); + +/** + * \brief Add a layer to a screen which is currently managed by the service + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_screenAddLayer(struct ivi_layout_screen *iviscrn, + struct ivi_layout_layer *addlayer); + +/** + * \brief Sets render order of layers on a display + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_screenSetRenderOrder(struct ivi_layout_screen *iviscrn, + struct ivi_layout_layer **pLayer, + const uint32_t number); + +/** + * \brief Take a screenshot from the current displayed layer scene. + * The screenshot is saved as bmp file with the corresponding filename. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_takeScreenshot(struct ivi_layout_screen *iviscrn, + const char *filename); + +/** + * \brief Take a screenshot of a certain layer + * The screenshot is saved as bmp file with the corresponding filename. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_takeLayerScreenshot(const char *filename, + struct ivi_layout_layer *ivilayer); + +/** + * \brief Take a screenshot of a certain surface + * The screenshot is saved as bmp file with the corresponding filename. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_takeSurfaceScreenshot(const char *filename, + struct ivi_layout_surface *ivisurf); + +/** + * \brief Enable or disable a rendering optimization + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_SetOptimizationMode(uint32_t id, uint32_t mode); + +/** + * \brief Get the current enablement for an optimization + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_GetOptimizationMode(uint32_t id, uint32_t *pMode); + +/** + * \brief register for notification on property changes of layer + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerAddNotification(struct ivi_layout_layer *ivilayer, + layerPropertyNotificationFunc callback, + void *userdata); + +/** + * \brief remove notification on property changes of layer + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerRemoveNotification(struct ivi_layout_layer *ivilayer); + +/** + * \brief Get the surface properties + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_getPropertiesOfSurface(struct ivi_layout_surface *ivisurf, + struct ivi_layout_SurfaceProperties *pSurfaceProperties); + +/** + * \brief Add a surface to a layer which is currently managed by the service + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerAddSurface(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface *addsurf); + +/** + * \brief Removes a surface from a layer which is currently managed by the service + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_layerRemoveSurface(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface *remsurf); + +/** + * \brief Set the area of a surface which should be used for the rendering. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_surfaceSetSourceRectangle(struct ivi_layout_surface *ivisurf, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height); + +/** + * \brief Commit all changes and execute all enqueued commands since last commit. + * + * \return 0 if the method call was successful + * \return -1 if the method call was failed + */ +int32_t +ivi_layout_commitChanges(void); + +#ifdef __cplusplus +} /**/ +#endif /* __cplusplus */ + +#endif /* _IVI_LAYOUT_EXPORT_H_ */ diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c new file mode 100644 index 00000000..68f9b526 --- /dev/null +++ b/ivi-shell/ivi-layout.c @@ -0,0 +1,2798 @@ +/* + * Copyright (C) 2013 DENSO 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. + */ + +/** + * Implementation of ivi-layout library. The actual view on screen is + * not updated till calling ivi_layout_commitChanges. A overview from + * calling API for updating properties of surfaces/layer to asking compositor + * to compose them by using weston_compositor_schedule_repaint, + * 0/ initialize this library by ivi_layout_initWithCompositor + * with (struct weston_compositor *ec) from ivi-shell. + * 1/ When a API for updating properties of surface/layer, it updates + * pending prop of ivi_layout_surface/layer/screen which are structure to + * store properties. + * 2/ Before calling commitChanges, in case of calling a API to get a property, + * return current property, not pending property. + * 3/ At the timing of calling ivi_layout_commitChanges, pending properties + * are applied + * to properties. + * 4/ According properties, set transformation by using weston_matrix and + * weston_view per surfaces and layers in while loop. + * 5/ Set damage and trigger transform by using weston_view_geometry_dirty and + * weston_view_geometry_dirty. + * 6/ Notify update of properties. + * 7/ Trigger composition by weston_compositor_schedule_repaint. + * + */ + +#include <sys/wait.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <linux/input.h> +#include <cairo.h> + +#include "compositor.h" +#include "ivi-layout.h" +#include "ivi-layout-export.h" + +enum ivi_layout_surface_orientation { + IVI_LAYOUT_SURFACE_ORIENTATION_0_DEGREES = 0, + IVI_LAYOUT_SURFACE_ORIENTATION_90_DEGREES = 1, + IVI_LAYOUT_SURFACE_ORIENTATION_180_DEGREES = 2, + IVI_LAYOUT_SURFACE_ORIENTATION_270_DEGREES = 3, +}; + +enum ivi_layout_surface_pixelformat { + IVI_LAYOUT_SURFACE_PIXELFORMAT_R_8 = 0, + IVI_LAYOUT_SURFACE_PIXELFORMAT_RGB_888 = 1, + IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_8888 = 2, + IVI_LAYOUT_SURFACE_PIXELFORMAT_RGB_565 = 3, + IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_5551 = 4, + IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_6661 = 5, + IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_4444 = 6, + IVI_LAYOUT_SURFACE_PIXELFORMAT_UNKNOWN = 7, +}; + +struct link_layer { + struct ivi_layout_layer *ivilayer; + struct wl_list link; + struct wl_list link_to_layer; +}; + +struct link_screen { + struct ivi_layout_screen *iviscrn; + struct wl_list link; + struct wl_list link_to_screen; +}; + +struct link_layerPropertyNotification { + layerPropertyNotificationFunc callback; + void *userdata; + struct wl_list link; +}; + +struct link_surfacePropertyNotification { + surfacePropertyNotificationFunc callback; + void *userdata; + struct wl_list link; +}; + +struct link_layerCreateNotification { + layerCreateNotificationFunc callback; + void *userdata; + struct wl_list link; +}; + +struct link_layerRemoveNotification { + layerRemoveNotificationFunc callback; + void *userdata; + struct wl_list link; +}; + +struct link_surfaceCreateNotification { + surfaceCreateNotificationFunc callback; + void *userdata; + struct wl_list link; +}; + +struct link_surfaceRemoveNotification { + surfaceRemoveNotificationFunc callback; + void *userdata; + struct wl_list link; +}; + +struct link_surfaceConfigureNotification { + surfaceConfigureNotificationFunc callback; + void *userdata; + struct wl_list link; +}; + +struct ivi_layout; + +struct ivi_layout_surface { + struct wl_list link; + struct wl_list list_notification; + struct wl_list list_layer; + uint32_t update_count; + uint32_t id_surface; + + struct ivi_layout *layout; + struct weston_surface *surface; + struct weston_view *view; + + uint32_t buffer_width; + uint32_t buffer_height; + + struct wl_listener surface_destroy_listener; + struct weston_transform surface_rotation; + struct weston_transform layer_rotation; + struct weston_transform surface_pos; + struct weston_transform layer_pos; + struct weston_transform scaling; + struct ivi_layout_SurfaceProperties prop; + int32_t pixelformat; + uint32_t event_mask; + + struct { + struct ivi_layout_SurfaceProperties prop; + struct wl_list link; + } pending; + + struct { + struct wl_list link; + struct wl_list list_layer; + } order; +}; + +struct ivi_layout_layer { + struct wl_list link; + struct wl_list list_notification; + struct wl_list list_screen; + struct wl_list link_to_surface; + uint32_t id_layer; + + struct ivi_layout *layout; + + struct ivi_layout_LayerProperties prop; + uint32_t event_mask; + + struct { + struct ivi_layout_LayerProperties prop; + struct wl_list list_surface; + struct wl_list link; + } pending; + + struct { + struct wl_list list_surface; + struct wl_list link; + } order; +}; + +struct ivi_layout_screen { + struct wl_list link; + struct wl_list link_to_layer; + uint32_t id_screen; + + struct ivi_layout *layout; + struct weston_output *output; + + uint32_t event_mask; + + struct { + struct wl_list list_layer; + struct wl_list link; + } pending; + + struct { + struct wl_list list_layer; + struct wl_list link; + } order; +}; + +struct ivi_layout { + struct weston_compositor *compositor; + + struct wl_list list_surface; + struct wl_list list_layer; + struct wl_list list_screen; + + struct { + struct wl_list list_create; + struct wl_list list_remove; + } layer_notification; + + struct { + struct wl_list list_create; + struct wl_list list_remove; + struct wl_list list_configure; + } surface_notification; + + struct weston_layer layout_layer; +}; + +static struct ivi_layout ivilayout = {0}; + +static struct ivi_layout * +get_instance(void) +{ + return &ivilayout; +} + +/** + * Internal API to add/remove a link to surface from layer. + */ +static void +add_link_to_surface(struct ivi_layout_layer *ivilayer, + struct link_layer *link_layer) +{ + wl_list_init(&link_layer->link_to_layer); + wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer); +} + +static void +remove_link_to_surface(struct ivi_layout_layer *ivilayer) +{ + struct link_layer *link = NULL; + struct link_layer *next = NULL; + + wl_list_for_each_safe(link, next, &ivilayer->link_to_surface, link_to_layer) { + if (!wl_list_empty(&link->link_to_layer)) { + wl_list_remove(&link->link_to_layer); + } + free(link); + } + + wl_list_init(&ivilayer->link_to_surface); +} + +/** + * Internal API to add a link to layer from screen. + */ +static void +add_link_to_layer(struct ivi_layout_screen *iviscrn, + struct link_screen *link_screen) +{ + wl_list_init(&link_screen->link_to_screen); + wl_list_insert(&iviscrn->link_to_layer, &link_screen->link_to_screen); +} + +/** + * Internal API to add/remove a surface from layer. + */ +static void +add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf, + struct ivi_layout_layer *ivilayer) +{ + struct link_layer *link_layer = NULL; + + link_layer = malloc(sizeof *link_layer); + if (link_layer == NULL) { + weston_log("fails to allocate memory\n"); + return; + } + + link_layer->ivilayer = ivilayer; + wl_list_init(&link_layer->link); + wl_list_insert(&ivisurf->list_layer, &link_layer->link); + add_link_to_surface(ivilayer, link_layer); +} + +static void +remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf) +{ + struct link_layer *link_layer = NULL; + struct link_layer *next = NULL; + + wl_list_for_each_safe(link_layer, next, &ivisurf->list_layer, link) { + if (!wl_list_empty(&link_layer->link)) { + wl_list_remove(&link_layer->link); + } + free(link_layer); + } + wl_list_init(&ivisurf->list_layer); +} + +/** + * Internal API to add/remove a layer from screen. + */ +static void +add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer, + struct ivi_layout_screen *iviscrn) +{ + struct link_screen *link_scrn = NULL; + + link_scrn = malloc(sizeof *link_scrn); + if (link_scrn == NULL) { + weston_log("fails to allocate memory\n"); + return; + } + + link_scrn->iviscrn = iviscrn; + wl_list_init(&link_scrn->link); + wl_list_insert(&ivilayer->list_screen, &link_scrn->link); + add_link_to_layer(iviscrn, link_scrn); +} + +static void +remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer) +{ + struct link_screen *link_scrn = NULL; + struct link_screen *next = NULL; + + wl_list_for_each_safe(link_scrn, next, &ivilayer->list_screen, link) { + if (!wl_list_empty(&link_scrn->link)) { + wl_list_remove(&link_scrn->link); + } + free(link_scrn); + } + wl_list_init(&ivilayer->list_screen); +} + +/** + * Internal API to add/remove a layer from screen. + */ +static struct ivi_layout_surface * +get_surface(struct wl_list *list_surf, uint32_t id_surface) +{ + struct ivi_layout_surface *ivisurf; + + wl_list_for_each(ivisurf, list_surf, link) { + if (ivisurf->id_surface == id_surface) { + return ivisurf; + } + } + + return NULL; +} + +static struct ivi_layout_layer * +get_layer(struct wl_list *list_layer, uint32_t id_layer) +{ + struct ivi_layout_layer *ivilayer; + + wl_list_for_each(ivilayer, list_layer, link) { + if (ivilayer->id_layer == id_layer) { + return ivilayer; + } + } + + return NULL; +} + +/** + * Called at destruction of ivi_surface + */ +static void +westonsurface_destroy_from_ivisurface(struct wl_listener *listener, void *data) +{ + struct ivi_layout_surface *ivisurf = NULL; + + ivisurf = container_of(listener, struct ivi_layout_surface, + surface_destroy_listener); + ivisurf->surface = NULL; + ivisurf->view = NULL; + ivi_layout_surfaceRemove(ivisurf); +} + +/** + * Internal API to check layer/surface already added in layer/screen. + * Called by ivi_layout_layerAddSurface/ivi_layout_screenAddLayer + */ +static int +is_surface_in_layer(struct ivi_layout_surface *ivisurf, + struct ivi_layout_layer *ivilayer) +{ + struct ivi_layout_surface *surf = NULL; + + wl_list_for_each(surf, &ivilayer->pending.list_surface, pending.link) { + if (surf->id_surface == ivisurf->id_surface) { + return 1; + } + } + + return 0; +} + +static int +is_layer_in_screen(struct ivi_layout_layer *ivilayer, + struct ivi_layout_screen *iviscrn) +{ + struct ivi_layout_layer *layer = NULL; + + wl_list_for_each(layer, &iviscrn->pending.list_layer, pending.link) { + if (layer->id_layer == ivilayer->id_layer) { + return 1; + } + } + + return 0; +} + +/** + * Internal API to initialize screens found from output_list of weston_compositor. + * Called by ivi_layout_initWithCompositor. + */ +static void +create_screen(struct weston_compositor *ec) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_screen *iviscrn = NULL; + struct weston_output *output = NULL; + int32_t count = 0; + + wl_list_for_each(output, &ec->output_list, link) { + iviscrn = calloc(1, sizeof *iviscrn); + if (iviscrn == NULL) { + weston_log("fails to allocate memory\n"); + continue; + } + + wl_list_init(&iviscrn->link); + iviscrn->layout = layout; + + iviscrn->id_screen = count; + count++; + + iviscrn->output = output; + iviscrn->event_mask = 0; + + wl_list_init(&iviscrn->pending.list_layer); + wl_list_init(&iviscrn->pending.link); + + wl_list_init(&iviscrn->order.list_layer); + wl_list_init(&iviscrn->order.link); + + wl_list_init(&iviscrn->link_to_layer); + + wl_list_insert(&layout->list_screen, &iviscrn->link); + } +} + +/** + * Internal APIs to initialize properties of surface/layer when they are created. + */ +static void +init_layerProperties(struct ivi_layout_LayerProperties *prop, + int32_t width, int32_t height) +{ + memset(prop, 0, sizeof *prop); + prop->opacity = wl_fixed_from_double(1.0); + prop->sourceWidth = width; + prop->sourceHeight = height; + prop->destWidth = width; + prop->destHeight = height; +} + +static void +init_surfaceProperties(struct ivi_layout_SurfaceProperties *prop) +{ + memset(prop, 0, sizeof *prop); + prop->opacity = wl_fixed_from_double(1.0); +} + +/** + * Internal APIs to be called from ivi_layout_commitChanges. + */ +static void +update_opacity(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface *ivisurf) +{ + double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity); + double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity); + + if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) || + (ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) { + if (ivisurf->view == NULL) { + return; + } + ivisurf->view->alpha = layer_alpha * surf_alpha; + } +} + +static void +update_surface_orientation(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface *ivisurf) +{ + struct weston_view *view = ivisurf->view; + struct weston_matrix *matrix = &ivisurf->surface_rotation.matrix; + float width = 0.0f; + float height = 0.0f; + float v_sin = 0.0f; + float v_cos = 0.0f; + float cx = 0.0f; + float cy = 0.0f; + float sx = 1.0f; + float sy = 1.0f; + + if (view == NULL) { + return; + } + + if ((ivilayer->prop.destWidth == 0) || + (ivilayer->prop.destHeight == 0)) { + return; + } + width = (float)ivilayer->prop.destWidth; + height = (float)ivilayer->prop.destHeight; + + switch (ivisurf->prop.orientation) { + case IVI_LAYOUT_SURFACE_ORIENTATION_0_DEGREES: + v_sin = 0.0f; + v_cos = 1.0f; + break; + case IVI_LAYOUT_SURFACE_ORIENTATION_90_DEGREES: + v_sin = 1.0f; + v_cos = 0.0f; + sx = width / height; + sy = height / width; + break; + case IVI_LAYOUT_SURFACE_ORIENTATION_180_DEGREES: + v_sin = 0.0f; + v_cos = -1.0f; + break; + case IVI_LAYOUT_SURFACE_ORIENTATION_270_DEGREES: + default: + v_sin = -1.0f; + v_cos = 0.0f; + sx = width / height; + sy = height / width; + break; + } + wl_list_remove(&ivisurf->surface_rotation.link); + weston_view_geometry_dirty(view); + + weston_matrix_init(matrix); + cx = 0.5f * width; + cy = 0.5f * height; + weston_matrix_translate(matrix, -cx, -cy, 0.0f); + weston_matrix_rotate_xy(matrix, v_cos, v_sin); + weston_matrix_scale(matrix, sx, sy, 1.0); + weston_matrix_translate(matrix, cx, cy, 0.0f); + wl_list_insert(&view->geometry.transformation_list, + &ivisurf->surface_rotation.link); + + weston_view_set_transform_parent(view, NULL); + weston_view_update_transform(view); +} + +static void +update_layer_orientation(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface *ivisurf) +{ + struct weston_surface *es = ivisurf->surface; + struct weston_view *view = ivisurf->view; + struct weston_matrix *matrix = &ivisurf->layer_rotation.matrix; + struct weston_output *output = NULL; + float width = 0.0f; + float height = 0.0f; + float v_sin = 0.0f; + float v_cos = 0.0f; + float cx = 0.0f; + float cy = 0.0f; + float sx = 1.0f; + float sy = 1.0f; + + if (es == NULL || view == NULL) { + return; + } + + output = es->output; + if (output == NULL) { + return; + } + if ((output->width == 0) || (output->height == 0)) { + return; + } + width = (float)output->width; + height = (float)output->height; + + switch (ivilayer->prop.orientation) { + case IVI_LAYOUT_SURFACE_ORIENTATION_0_DEGREES: + v_sin = 0.0f; + v_cos = 1.0f; + break; + case IVI_LAYOUT_SURFACE_ORIENTATION_90_DEGREES: + v_sin = 1.0f; + v_cos = 0.0f; + sx = width / height; + sy = height / width; + break; + case IVI_LAYOUT_SURFACE_ORIENTATION_180_DEGREES: + v_sin = 0.0f; + v_cos = -1.0f; + break; + case IVI_LAYOUT_SURFACE_ORIENTATION_270_DEGREES: + default: + v_sin = -1.0f; + v_cos = 0.0f; + sx = width / height; + sy = height / width; + break; + } + wl_list_remove(&ivisurf->layer_rotation.link); + weston_view_geometry_dirty(view); + + weston_matrix_init(matrix); + cx = 0.5f * width; + cy = 0.5f * height; + weston_matrix_translate(matrix, -cx, -cy, 0.0f); + weston_matrix_rotate_xy(matrix, v_cos, v_sin); + weston_matrix_scale(matrix, sx, sy, 1.0); + weston_matrix_translate(matrix, cx, cy, 0.0f); + wl_list_insert(&view->geometry.transformation_list, + &ivisurf->layer_rotation.link); + + weston_view_set_transform_parent(view, NULL); + weston_view_update_transform(view); +} + +static void +update_surface_position(struct ivi_layout_surface *ivisurf) +{ + struct weston_view *view = ivisurf->view; + float tx = (float)ivisurf->prop.destX; + float ty = (float)ivisurf->prop.destY; + struct weston_matrix *matrix = &ivisurf->surface_pos.matrix; + + if (view == NULL) { + return; + } + + wl_list_remove(&ivisurf->surface_pos.link); + + weston_matrix_init(matrix); + weston_matrix_translate(matrix, tx, ty, 0.0f); + wl_list_insert(&view->geometry.transformation_list, + &ivisurf->surface_pos.link); + + weston_view_set_transform_parent(view, NULL); + weston_view_update_transform(view); + +#if 0 + /* disable zoom animation */ + weston_zoom_run(es, 0.0, 1.0, NULL, NULL); +#endif + +} + +static void +update_layer_position(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface *ivisurf) +{ + struct weston_view *view = ivisurf->view; + struct weston_matrix *matrix = &ivisurf->layer_pos.matrix; + float tx = (float)ivilayer->prop.destX; + float ty = (float)ivilayer->prop.destY; + + if (view == NULL) { + return; + } + + wl_list_remove(&ivisurf->layer_pos.link); + + weston_matrix_init(matrix); + weston_matrix_translate(matrix, tx, ty, 0.0f); + wl_list_insert( + &view->geometry.transformation_list, + &ivisurf->layer_pos.link); + + weston_view_set_transform_parent(view, NULL); + weston_view_update_transform(view); +} + +static void +update_scale(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface *ivisurf) +{ + struct weston_view *view = ivisurf->view; + struct weston_matrix *matrix = &ivisurf->scaling.matrix; + float sx = 0.0f; + float sy = 0.0f; + float lw = 0.0f; + float sw = 0.0f; + float lh = 0.0f; + float sh = 0.0f; + + if (view == NULL) { + return; + } + + if (ivisurf->prop.sourceWidth == 0 && ivisurf->prop.sourceHeight == 0) { + ivisurf->prop.sourceWidth = ivisurf->buffer_width; + ivisurf->prop.sourceHeight = ivisurf->buffer_height; + + if (ivisurf->prop.destWidth == 0 && ivisurf->prop.destHeight == 0) { + ivisurf->prop.destWidth = ivisurf->buffer_width; + ivisurf->prop.destHeight = ivisurf->buffer_height; + } + } + + lw = ((float)ivilayer->prop.destWidth / ivilayer->prop.sourceWidth ); + sw = ((float)ivisurf->prop.destWidth / ivisurf->prop.sourceWidth ); + lh = ((float)ivilayer->prop.destHeight / ivilayer->prop.sourceHeight); + sh = ((float)ivisurf->prop.destHeight / ivisurf->prop.sourceHeight ); + sx = sw * lw; + sy = sh * lh; + + wl_list_remove(&ivisurf->scaling.link); + weston_matrix_init(matrix); + weston_matrix_scale(matrix, sx, sy, 1.0f); + + wl_list_insert(&view->geometry.transformation_list, + &ivisurf->scaling.link); + + weston_view_set_transform_parent(view, NULL); + weston_view_update_transform(view); +} + +static void +update_prop(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface *ivisurf) +{ + if (ivilayer->event_mask | ivisurf->event_mask) { + update_opacity(ivilayer, ivisurf); + update_layer_orientation(ivilayer, ivisurf); + update_layer_position(ivilayer, ivisurf); + update_surface_position(ivisurf); + update_surface_orientation(ivilayer, ivisurf); + update_scale(ivilayer, ivisurf); + + ivisurf->update_count++; + + if (ivisurf->view != NULL) { + weston_view_geometry_dirty(ivisurf->view); + } + + if (ivisurf->surface != NULL) { + weston_surface_damage(ivisurf->surface); + } + } +} + +static void +commit_changes(struct ivi_layout *layout) +{ + struct ivi_layout_screen *iviscrn = NULL; + struct ivi_layout_layer *ivilayer = NULL; + struct ivi_layout_surface *ivisurf = NULL; + + wl_list_for_each(iviscrn, &layout->list_screen, link) { + wl_list_for_each(ivilayer, &iviscrn->order.list_layer, order.link) { + wl_list_for_each(ivisurf, &ivilayer->order.list_surface, order.link) { + update_prop(ivilayer, ivisurf); + } + } + } +} + +static void +commit_list_surface(struct ivi_layout *layout) +{ + struct ivi_layout_surface *ivisurf = NULL; + + wl_list_for_each(ivisurf, &layout->list_surface, link) { + ivisurf->prop = ivisurf->pending.prop; + } +} + +static void +commit_list_layer(struct ivi_layout *layout) +{ + struct ivi_layout_layer *ivilayer = NULL; + struct ivi_layout_surface *ivisurf = NULL; + struct ivi_layout_surface *next = NULL; + + wl_list_for_each(ivilayer, &layout->list_layer, link) { + ivilayer->prop = ivilayer->pending.prop; + + if (!(ivilayer->event_mask & + (IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) { + continue; + } + + wl_list_for_each_safe(ivisurf, next, + &ivilayer->order.list_surface, order.link) { + remove_ordersurface_from_layer(ivisurf); + + if (!wl_list_empty(&ivisurf->order.link)) { + wl_list_remove(&ivisurf->order.link); + } + + wl_list_init(&ivisurf->order.link); + } + + wl_list_init(&ivilayer->order.list_surface); + wl_list_for_each(ivisurf, &ivilayer->pending.list_surface, + pending.link) { + if(!wl_list_empty(&ivisurf->order.link)){ + wl_list_remove(&ivisurf->order.link); + wl_list_init(&ivisurf->order.link); + } + + wl_list_insert(&ivilayer->order.list_surface, + &ivisurf->order.link); + add_ordersurface_to_layer(ivisurf, ivilayer); + } + } +} + +static void +commit_list_screen(struct ivi_layout *layout) +{ + struct ivi_layout_screen *iviscrn = NULL; + struct ivi_layout_layer *ivilayer = NULL; + struct ivi_layout_layer *next = NULL; + struct ivi_layout_surface *ivisurf = NULL; + + wl_list_for_each(iviscrn, &layout->list_screen, link) { + if (iviscrn->event_mask & IVI_NOTIFICATION_ADD) { + wl_list_for_each_safe(ivilayer, next, + &iviscrn->order.list_layer, order.link) { + remove_orderlayer_from_screen(ivilayer); + + if (!wl_list_empty(&ivilayer->order.link)) { + wl_list_remove(&ivilayer->order.link); + } + + wl_list_init(&ivilayer->order.link); + } + + wl_list_init(&iviscrn->order.list_layer); + wl_list_for_each(ivilayer, &iviscrn->pending.list_layer, + pending.link) { + wl_list_insert(&iviscrn->order.list_layer, + &ivilayer->order.link); + add_orderlayer_to_screen(ivilayer, iviscrn); + } + iviscrn->event_mask = 0; + } + + /* Clear view list of layout layer */ + wl_list_init(&layout->layout_layer.view_list); + + wl_list_for_each(ivilayer, &iviscrn->order.list_layer, order.link) { + + if (ivilayer->prop.visibility == 0) + continue; + + wl_list_for_each(ivisurf, &ivilayer->order.list_surface, order.link) { + + if (ivisurf->prop.visibility == 0) + continue; + if (ivisurf->surface == NULL || ivisurf->view == NULL) + continue; + + wl_list_insert(&layout->layout_layer.view_list, + &ivisurf->view->layer_link); + + ivisurf->surface->output = iviscrn->output; + } + } + + break; + } +} + +static void +send_surface_prop(struct ivi_layout_surface *ivisurf) +{ + struct link_surfacePropertyNotification *notification = NULL; + + wl_list_for_each(notification, &ivisurf->list_notification, link) { + notification->callback(ivisurf, &ivisurf->prop, + ivisurf->event_mask, + notification->userdata); + } + + ivisurf->event_mask = 0; +} + +static void +send_layer_prop(struct ivi_layout_layer *ivilayer) +{ + struct link_layerPropertyNotification *notification = NULL; + + wl_list_for_each(notification, &ivilayer->list_notification, link) { + notification->callback(ivilayer, &ivilayer->prop, + ivilayer->event_mask, + notification->userdata); + } + + ivilayer->event_mask = 0; +} + +static void +send_prop(struct ivi_layout *layout) +{ + struct ivi_layout_layer *ivilayer = NULL; + struct ivi_layout_surface *ivisurf = NULL; + + wl_list_for_each(ivilayer, &layout->list_layer, link) { + send_layer_prop(ivilayer); + } + + wl_list_for_each(ivisurf, &layout->list_surface, link) { + send_surface_prop(ivisurf); + } +} + +/** + * Exported APIs of ivi-layout library are implemented from here. + * Brief of APIs is described in ivi-layout-export.h. + */ +WL_EXPORT int32_t +ivi_layout_addNotificationCreateLayer(layerCreateNotificationFunc callback, + void *userdata) +{ + struct ivi_layout *layout = get_instance(); + struct link_layerCreateNotification *notification = NULL; + + if (callback == NULL) { + weston_log("ivi_layout_addNotificationCreateLayer: invalid argument\n"); + return -1; + } + + notification = malloc(sizeof *notification); + if (notification == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + notification->callback = callback; + notification->userdata = userdata; + wl_list_init(¬ification->link); + wl_list_insert(&layout->layer_notification.list_create, ¬ification->link); + + return 0; +} + +WL_EXPORT void +ivi_layout_removeNotificationCreateLayer(layerCreateNotificationFunc callback, + void *userdata) +{ + struct ivi_layout *layout = get_instance(); + struct link_layerCreateNotification *link = NULL; + struct link_layerCreateNotification *next = NULL; + + wl_list_for_each_safe(link, next, &layout->layer_notification.list_create, link) { + if ((link->callback == callback) && + (link->userdata == userdata)) { + if (!wl_list_empty(&link->link)) { + wl_list_remove(&link->link); + } + + free(link); + } + } +} + +WL_EXPORT int32_t +ivi_layout_addNotificationRemoveLayer(layerRemoveNotificationFunc callback, + void *userdata) +{ + struct ivi_layout *layout = get_instance(); + struct link_layerRemoveNotification *notification = NULL; + + if (callback == NULL) { + weston_log("ivi_layout_addNotificationRemoveLayer: invalid argument\n"); + return -1; + } + + notification = malloc(sizeof *notification); + if (notification == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + notification->callback = callback; + notification->userdata = userdata; + wl_list_init(¬ification->link); + wl_list_insert(&layout->layer_notification.list_remove, ¬ification->link); + + return 0; +} + +WL_EXPORT void +ivi_layout_removeNotificationRemoveLayer(layerRemoveNotificationFunc callback, + void *userdata) +{ + struct ivi_layout *layout = get_instance(); + struct link_layerRemoveNotification *link = NULL; + struct link_layerRemoveNotification *next = NULL; + + wl_list_for_each_safe(link, next, &layout->layer_notification.list_remove, link) { + if ((link->callback == callback) && + (link->userdata == userdata)) { + if (!wl_list_empty(&link->link)) { + wl_list_remove(&link->link); + } + + free(link); + } + } +} + +WL_EXPORT int32_t +ivi_layout_addNotificationCreateSurface(surfaceCreateNotificationFunc callback, + void *userdata) +{ + struct ivi_layout *layout = get_instance(); + struct link_surfaceCreateNotification *notification = NULL; + + if (callback == NULL) { + weston_log("ivi_layout_addNotificationCreateSurface: invalid argument\n"); + return -1; + } + + notification = malloc(sizeof *notification); + if (notification == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + notification->callback = callback; + notification->userdata = userdata; + wl_list_init(¬ification->link); + wl_list_insert(&layout->surface_notification.list_create, ¬ification->link); + + return 0; +} + +WL_EXPORT void +ivi_layout_removeNotificationCreateSurface(surfaceCreateNotificationFunc callback, + void *userdata) +{ + struct ivi_layout *layout = get_instance(); + struct link_surfaceCreateNotification *link = NULL; + struct link_surfaceCreateNotification *next = NULL; + + wl_list_for_each_safe(link, next, &layout->surface_notification.list_create, link) { + if ((link->callback == callback) && + (link->userdata == userdata)) { + if (!wl_list_empty(&link->link)) { + wl_list_remove(&link->link); + } + + free(link); + } + } +} + +WL_EXPORT int32_t +ivi_layout_addNotificationRemoveSurface(surfaceRemoveNotificationFunc callback, + void *userdata) +{ + struct ivi_layout *layout = get_instance(); + struct link_surfaceRemoveNotification *notification = NULL; + + if (callback == NULL) { + weston_log("ivi_layout_addNotificationRemoveSurface: invalid argument\n"); + return -1; + } + + notification = malloc(sizeof *notification); + if (notification == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + notification->callback = callback; + notification->userdata = userdata; + wl_list_init(¬ification->link); + wl_list_insert(&layout->surface_notification.list_remove, ¬ification->link); + + return 0; +} + +WL_EXPORT void +ivi_layout_removeNotificationRemoveSurface(surfaceRemoveNotificationFunc callback, + void *userdata) +{ + struct ivi_layout *layout = get_instance(); + struct link_surfaceRemoveNotification *link = NULL; + struct link_surfaceRemoveNotification *next = NULL; + + wl_list_for_each_safe(link, next, &layout->surface_notification.list_remove, link) { + if ((link->callback == callback) && + (link->userdata == userdata)) { + if (!wl_list_empty(&link->link)) { + wl_list_remove(&link->link); + } + + free(link); + } + } +} + +WL_EXPORT int32_t +ivi_layout_addNotificationConfigureSurface(surfaceConfigureNotificationFunc callback, + void *userdata) +{ + struct ivi_layout *layout = get_instance(); + struct link_surfaceConfigureNotification *notification = NULL; + + if (callback == NULL) { + weston_log("ivi_layout_addNotificationConfigureSurface: invalid argument\n"); + return -1; + } + + notification = malloc(sizeof *notification); + if (notification == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + notification->callback = callback; + notification->userdata = userdata; + wl_list_init(¬ification->link); + wl_list_insert(&layout->surface_notification.list_configure, ¬ification->link); + + return 0; +} + +WL_EXPORT void +ivi_layout_removeNotificationConfigureSurface(surfaceConfigureNotificationFunc callback, + void *userdata) +{ + struct ivi_layout *layout = get_instance(); + struct link_surfaceConfigureNotification *link = NULL; + struct link_surfaceConfigureNotification *next = NULL; + + wl_list_for_each_safe(link, next, &layout->surface_notification.list_configure, link) { + if ((link->callback == callback) && + (link->userdata == userdata)) { + if (!wl_list_empty(&link->link)) { + wl_list_remove(&link->link); + } + + free(link); + } + } +} + +WL_EXPORT uint32_t +ivi_layout_getIdOfSurface(struct ivi_layout_surface *ivisurf) +{ + return ivisurf->id_surface; +} + +WL_EXPORT uint32_t +ivi_layout_getIdOfLayer(struct ivi_layout_layer *ivilayer) +{ + return ivilayer->id_layer; +} + +WL_EXPORT struct ivi_layout_layer * +ivi_layout_getLayerFromId(uint32_t id_layer) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_layer *ivilayer = NULL; + + wl_list_for_each(ivilayer, &layout->list_layer, link) { + if (ivilayer->id_layer == id_layer) { + return ivilayer; + } + } + + return NULL; +} + +WL_EXPORT struct ivi_layout_surface * +ivi_layout_getSurfaceFromId(uint32_t id_surface) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_surface *ivisurf = NULL; + + wl_list_for_each(ivisurf, &layout->list_surface, link) { + if (ivisurf->id_surface == id_surface) { + return ivisurf; + } + } + + return NULL; +} + +WL_EXPORT struct ivi_layout_screen * +ivi_layout_getScreenFromId(uint32_t id_screen) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_screen *iviscrn = NULL; + (void)id_screen; + + wl_list_for_each(iviscrn, &layout->list_screen, link) { +//FIXME : select iviscrn from list_screen by id_screen + return iviscrn; + break; + } + + return NULL; +} + +WL_EXPORT int32_t +ivi_layout_getScreenResolution(struct ivi_layout_screen *iviscrn, + uint32_t *pWidth, uint32_t *pHeight) +{ + struct weston_output *output = NULL; + + if (pWidth == NULL || pHeight == NULL) { + weston_log("ivi_layout_getScreenResolution: invalid argument\n"); + return -1; + } + + output = iviscrn->output; + *pWidth = output->current_mode->width; + *pHeight = output->current_mode->height; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceAddNotification(struct ivi_layout_surface *ivisurf, + surfacePropertyNotificationFunc callback, + void *userdata) +{ + struct link_surfacePropertyNotification *notification = NULL; + + if (ivisurf == NULL || callback == NULL) { + weston_log("ivi_layout_surfaceAddNotification: invalid argument\n"); + return -1; + } + + notification = malloc(sizeof *notification); + if (notification == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + notification->callback = callback; + notification->userdata = userdata; + wl_list_init(¬ification->link); + wl_list_insert(&ivisurf->list_notification, ¬ification->link); + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceRemoveNotification(struct ivi_layout_surface *ivisurf) +{ + struct link_surfacePropertyNotification *notification = NULL; + struct link_surfacePropertyNotification *next = NULL; + + if (ivisurf == NULL) { + weston_log("ivi_layout_surfaceRemoveNotification: invalid argument\n"); + return -1; + } + + wl_list_for_each_safe(notification, next, + &ivisurf->list_notification, link) { + if (!wl_list_empty(¬ification->link)) { + wl_list_remove(¬ification->link); + } + free(notification); + } + wl_list_init(&ivisurf->list_notification); + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceRemove(struct ivi_layout_surface *ivisurf) +{ + struct ivi_layout *layout = get_instance(); + struct link_surfaceRemoveNotification *notification = NULL; + + if (ivisurf == NULL) { + weston_log("ivi_layout_surfaceRemove: invalid argument\n"); + return -1; + } + + if (!wl_list_empty(&ivisurf->pending.link)) { + wl_list_remove(&ivisurf->pending.link); + } + if (!wl_list_empty(&ivisurf->order.link)) { + wl_list_remove(&ivisurf->order.link); + } + if (!wl_list_empty(&ivisurf->link)) { + wl_list_remove(&ivisurf->link); + } + remove_ordersurface_from_layer(ivisurf); + + wl_list_for_each(notification, + &layout->surface_notification.list_remove, link) { + if (notification->callback != NULL) { + notification->callback(ivisurf, notification->userdata); + } + } + + free(ivisurf); + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_UpdateInputEventAcceptanceOn(struct ivi_layout_surface *ivisurf, + uint32_t devices, uint32_t acceptance) +{ + /* TODO */ + (void)ivisurf; + (void)devices; + (void)acceptance; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceInitialize(struct ivi_layout_surface **pSurfaceId) +{ + /* TODO */ + (void)pSurfaceId; + return 0; +} + +WL_EXPORT int32_t +ivi_layout_getPropertiesOfLayer(struct ivi_layout_layer *ivilayer, + struct ivi_layout_LayerProperties *pLayerProperties) +{ + if (ivilayer == NULL || pLayerProperties == NULL) { + weston_log("ivi_layout_getPropertiesOfLayer: invalid argument\n"); + return -1; + } + + *pLayerProperties = ivilayer->prop; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_getNumberOfHardwareLayers(uint32_t id_screen, + uint32_t *pNumberOfHardwareLayers) +{ + /* TODO */ + (void)id_screen; + (void)pNumberOfHardwareLayers; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_getScreens(uint32_t *pLength, ivi_layout_screen_ptr **ppArray) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_screen *iviscrn = NULL; + uint32_t length = 0; + uint32_t n = 0; + + if (pLength == NULL || ppArray == NULL) { + weston_log("ivi_layout_getScreens: invalid argument\n"); + return -1; + } + + length = wl_list_length(&layout->list_screen); + + if (length != 0){ + /* the Array must be free by module which called this function */ + *ppArray = calloc(length, sizeof(ivi_layout_screen_ptr)); + if (*ppArray == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + wl_list_for_each(iviscrn, &layout->list_screen, link) { + (*ppArray)[n++] = iviscrn; + } + } + + *pLength = length; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_getScreensUnderLayer(struct ivi_layout_layer *ivilayer, + uint32_t *pLength, + ivi_layout_screen_ptr **ppArray) +{ + struct link_screen *link_scrn = NULL; + uint32_t length = 0; + uint32_t n = 0; + + if (ivilayer == NULL || pLength == NULL || ppArray == NULL) { + weston_log("ivi_layout_getScreensUnderLayer: invalid argument\n"); + return -1; + } + + length = wl_list_length(&ivilayer->list_screen); + + if (length != 0){ + /* the Array must be free by module which called this function */ + *ppArray = calloc(length, sizeof(ivi_layout_screen_ptr)); + if (*ppArray == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + wl_list_for_each(link_scrn, &ivilayer->list_screen, link) { + (*ppArray)[n++] = link_scrn->iviscrn; + } + } + + *pLength = length; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_getLayers(uint32_t *pLength, ivi_layout_layer_ptr **ppArray) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_layer *ivilayer = NULL; + uint32_t length = 0; + uint32_t n = 0; + + if (pLength == NULL || ppArray == NULL) { + weston_log("ivi_layout_getLayers: invalid argument\n"); + return -1; + } + + length = wl_list_length(&layout->list_layer); + + if (length != 0){ + /* the Array must be free by module which called this function */ + *ppArray = calloc(length, sizeof(ivi_layout_layer_ptr)); + if (*ppArray == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + wl_list_for_each(ivilayer, &layout->list_layer, link) { + (*ppArray)[n++] = ivilayer; + } + } + + *pLength = length; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_getLayersOnScreen(struct ivi_layout_screen *iviscrn, + uint32_t *pLength, + ivi_layout_layer_ptr **ppArray) +{ + struct ivi_layout_layer *ivilayer = NULL; + uint32_t length = 0; + uint32_t n = 0; + + if (iviscrn == NULL || pLength == NULL || ppArray == NULL) { + weston_log("ivi_layout_getLayersOnScreen: invalid argument\n"); + return -1; + } + + length = wl_list_length(&iviscrn->order.list_layer); + + if (length != 0){ + /* the Array must be free by module which called this function */ + *ppArray = calloc(length, sizeof(ivi_layout_layer_ptr)); + if (*ppArray == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + wl_list_for_each(ivilayer, &iviscrn->order.list_layer, link) { + (*ppArray)[n++] = ivilayer; + } + } + + *pLength = length; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_getLayersUnderSurface(struct ivi_layout_surface *ivisurf, + uint32_t *pLength, + ivi_layout_layer_ptr **ppArray) +{ + struct link_layer *link_layer = NULL; + uint32_t length = 0; + uint32_t n = 0; + + if (ivisurf == NULL || pLength == NULL || ppArray == NULL) { + weston_log("ivi_layout_getLayers: invalid argument\n"); + return -1; + } + + length = wl_list_length(&ivisurf->list_layer); + + if (length != 0){ + /* the Array must be free by module which called this function */ + *ppArray = calloc(length, sizeof(ivi_layout_layer_ptr)); + if (*ppArray == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + wl_list_for_each(link_layer, &ivisurf->list_layer, link) { + (*ppArray)[n++] = link_layer->ivilayer; + } + } + + *pLength = length; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_getSurfaces(uint32_t *pLength, ivi_layout_surface_ptr **ppArray) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_surface *ivisurf = NULL; + uint32_t length = 0; + uint32_t n = 0; + + if (pLength == NULL || ppArray == NULL) { + weston_log("ivi_layout_getSurfaces: invalid argument\n"); + return -1; + } + + length = wl_list_length(&layout->list_surface); + + if (length != 0){ + /* the Array must be free by module which called this function */ + *ppArray = calloc(length, sizeof(ivi_layout_surface_ptr)); + if (*ppArray == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + wl_list_for_each(ivisurf, &layout->list_surface, link) { + (*ppArray)[n++] = ivisurf; + } + } + + *pLength = length; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_getSurfacesOnLayer(struct ivi_layout_layer *ivilayer, + uint32_t *pLength, + ivi_layout_surface_ptr **ppArray) +{ + struct ivi_layout_surface *ivisurf = NULL; + uint32_t length = 0; + uint32_t n = 0; + + if (ivilayer == NULL || pLength == NULL || ppArray == NULL) { + weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n"); + return -1; + } + + length = wl_list_length(&ivilayer->order.list_surface); + + if (length != 0) { + /* the Array must be free by module which called this function */ + *ppArray = calloc(length, sizeof(ivi_layout_surface_ptr)); + if (*ppArray == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + wl_list_for_each(ivisurf, &ivilayer->order.list_surface, order.link) { + (*ppArray)[n++] = ivisurf; + } + } + + *pLength = length; + + return 0; +} + +WL_EXPORT struct ivi_layout_layer * +ivi_layout_layerCreateWithDimension(uint32_t id_layer, + uint32_t width, uint32_t height) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_layer *ivilayer = NULL; + struct link_layerCreateNotification *notification = NULL; + + ivilayer = get_layer(&layout->list_layer, id_layer); + if (ivilayer != NULL) { + weston_log("id_layer is already created\n"); + return ivilayer; + } + + ivilayer = calloc(1, sizeof *ivilayer); + if (ivilayer == NULL) { + weston_log("fails to allocate memory\n"); + return NULL; + } + + wl_list_init(&ivilayer->link); + wl_list_init(&ivilayer->list_notification); + wl_list_init(&ivilayer->list_screen); + wl_list_init(&ivilayer->link_to_surface); + ivilayer->layout = layout; + ivilayer->id_layer = id_layer; + + init_layerProperties(&ivilayer->prop, width, height); + ivilayer->event_mask = 0; + + wl_list_init(&ivilayer->pending.list_surface); + wl_list_init(&ivilayer->pending.link); + ivilayer->pending.prop = ivilayer->prop; + + wl_list_init(&ivilayer->order.list_surface); + wl_list_init(&ivilayer->order.link); + + wl_list_insert(&layout->list_layer, &ivilayer->link); + + wl_list_for_each(notification, + &layout->layer_notification.list_create, link) { + if (notification->callback != NULL) { + notification->callback(ivilayer, notification->userdata); + } + } + + return ivilayer; +} + +WL_EXPORT int32_t +ivi_layout_layerRemove(struct ivi_layout_layer *ivilayer) +{ + struct ivi_layout *layout = get_instance(); + struct link_layerRemoveNotification *notification = NULL; + + if (ivilayer == NULL) { + weston_log("ivi_layout_layerRemove: invalid argument\n"); + return -1; + } + + wl_list_for_each(notification, + &layout->layer_notification.list_remove, link) { + if (notification->callback != NULL) { + notification->callback(ivilayer, notification->userdata); + } + } + + if (!wl_list_empty(&ivilayer->pending.link)) { + wl_list_remove(&ivilayer->pending.link); + } + if (!wl_list_empty(&ivilayer->order.link)) { + wl_list_remove(&ivilayer->order.link); + } + if (!wl_list_empty(&ivilayer->link)) { + wl_list_remove(&ivilayer->link); + } + remove_orderlayer_from_screen(ivilayer); + remove_link_to_surface(ivilayer); + + free(ivilayer); + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerGetType(struct ivi_layout_layer *ivilayer, + uint32_t *pLayerType) +{ + /* TODO */ + (void)ivilayer; + (void)pLayerType; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerSetVisibility(struct ivi_layout_layer *ivilayer, + uint32_t newVisibility) +{ + struct ivi_layout_LayerProperties *prop = NULL; + + if (ivilayer == NULL) { + weston_log("ivi_layout_layerSetVisibility: invalid argument\n"); + return -1; + } + + prop = &ivilayer->pending.prop; + prop->visibility = newVisibility; + + ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerGetVisibility(struct ivi_layout_layer *ivilayer, uint32_t *pVisibility) +{ + if (ivilayer == NULL || pVisibility == NULL) { + weston_log("ivi_layout_layerGetVisibility: invalid argument\n"); + return -1; + } + + *pVisibility = ivilayer->prop.visibility; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerSetOpacity(struct ivi_layout_layer *ivilayer, + float opacity) +{ + struct ivi_layout_LayerProperties *prop = NULL; + + if (ivilayer == NULL) { + weston_log("ivi_layout_layerSetOpacity: invalid argument\n"); + return -1; + } + + prop = &ivilayer->pending.prop; + prop->opacity = opacity; + + ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerGetOpacity(struct ivi_layout_layer *ivilayer, + float *pOpacity) +{ + if (ivilayer == NULL || pOpacity == NULL) { + weston_log("ivi_layout_layerGetOpacity: invalid argument\n"); + return -1; + } + + *pOpacity = ivilayer->prop.opacity; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerSetSourceRectangle(struct ivi_layout_layer *ivilayer, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height) +{ + struct ivi_layout_LayerProperties *prop = NULL; + + if (ivilayer == NULL) { + weston_log("ivi_layout_layerSetSourceRectangle: invalid argument\n"); + return -1; + } + + prop = &ivilayer->pending.prop; + prop->sourceX = x; + prop->sourceY = y; + prop->sourceWidth = width; + prop->sourceHeight = height; + + ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerSetDestinationRectangle(struct ivi_layout_layer *ivilayer, + int32_t x, int32_t y, + uint32_t width, uint32_t height) +{ + struct ivi_layout_LayerProperties *prop = NULL; + + if (ivilayer == NULL) { + weston_log("ivi_layout_layerSetDestinationRectangle: invalid argument\n"); + return -1; + } + + prop = &ivilayer->pending.prop; + prop->destX = x; + prop->destY = y; + prop->destWidth = width; + prop->destHeight = height; + + ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerGetDimension(struct ivi_layout_layer *ivilayer, + uint32_t *pDimension) +{ + if (ivilayer == NULL || &pDimension[0] == NULL || &pDimension[1] == NULL) { + weston_log("ivi_layout_layerGetDimension: invalid argument\n"); + return -1; + } + + pDimension[0] = ivilayer->prop.destX; + pDimension[1] = ivilayer->prop.destY; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerSetDimension(struct ivi_layout_layer *ivilayer, + uint32_t *pDimension) +{ + struct ivi_layout_LayerProperties *prop = NULL; + + if (ivilayer == NULL || &pDimension[0] == NULL || &pDimension[1] == NULL) { + weston_log("ivi_layout_layerSetDimension: invalid argument\n"); + return -1; + } + + prop = &ivilayer->pending.prop; + + prop->destWidth = pDimension[0]; + prop->destHeight = pDimension[1]; + + ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerGetPosition(struct ivi_layout_layer *ivilayer, int32_t *pPosition) +{ + if (ivilayer == NULL || pPosition == NULL) { + weston_log("ivi_layout_layerGetPosition: invalid argument\n"); + return -1; + } + + pPosition[0] = ivilayer->prop.destX; + pPosition[1] = ivilayer->prop.destY; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerSetPosition(struct ivi_layout_layer *ivilayer, int32_t *pPosition) +{ + struct ivi_layout_LayerProperties *prop = NULL; + + if (ivilayer == NULL || pPosition == NULL) { + weston_log("ivi_layout_layerSetPosition: invalid argument\n"); + return -1; + } + + prop = &ivilayer->pending.prop; + prop->destX = pPosition[0]; + prop->destY = pPosition[1]; + + ivilayer->event_mask |= IVI_NOTIFICATION_POSITION; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerSetOrientation(struct ivi_layout_layer *ivilayer, + uint32_t orientation) +{ + struct ivi_layout_LayerProperties *prop = NULL; + + if (ivilayer == NULL) { + weston_log("ivi_layout_layerSetOrientation: invalid argument\n"); + return -1; + } + + prop = &ivilayer->pending.prop; + prop->orientation = orientation; + + ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerGetOrientation(struct ivi_layout_layer *ivilayer, + uint32_t *pOrientation) +{ + if (ivilayer == NULL || pOrientation == NULL) { + weston_log("ivi_layout_layerGetOrientation: invalid argument\n"); + return -1; + } + + *pOrientation = ivilayer->prop.orientation; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerSetChromaKey(struct ivi_layout_layer *ivilayer, uint32_t* pColor) +{ + /* TODO */ + (void)ivilayer; + (void)pColor; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerSetRenderOrder(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface **pSurface, + uint32_t number) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_surface *ivisurf = NULL; + struct ivi_layout_surface *next = NULL; + uint32_t *id_surface = NULL; + uint32_t i = 0; + + if (ivilayer == NULL) { + weston_log("ivi_layout_layerSetRenderOrder: invalid argument\n"); + return -1; + } + + if (pSurface == NULL) { + return 0; + } + + for (i = 0; i < number; i++) { + id_surface = &pSurface[i]->id_surface; + + wl_list_for_each(ivisurf, &layout->list_surface, link) { + if (*id_surface != ivisurf->id_surface) { + continue; + } + + if (!wl_list_empty(&ivisurf->pending.link)) { + wl_list_remove(&ivisurf->pending.link); + } + wl_list_init(&ivisurf->pending.link); + wl_list_insert(&ivilayer->pending.list_surface, + &ivisurf->pending.link); + break; + } + } + + ivilayer->event_mask |= IVI_NOTIFICATION_ADD; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerGetCapabilities(struct ivi_layout_layer *ivilayer, + uint32_t *pCapabilities) +{ + /* TODO */ + (void)ivilayer; + (void)pCapabilities; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerTypeGetCapabilities(uint32_t layerType, + uint32_t *pCapabilities) +{ + /* TODO */ + (void)layerType; + (void)pCapabilities; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceSetVisibility(struct ivi_layout_surface *ivisurf, + uint32_t newVisibility) +{ + struct ivi_layout_SurfaceProperties *prop = NULL; + + if (ivisurf == NULL) { + weston_log("ivi_layout_surfaceSetVisibility: invalid argument\n"); + return -1; + } + + prop = &ivisurf->pending.prop; + prop->visibility = newVisibility; + + ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceGetVisibility(struct ivi_layout_surface *ivisurf, + uint32_t *pVisibility) +{ + if (ivisurf == NULL || pVisibility == NULL) { + weston_log("ivi_layout_surfaceGetVisibility: invalid argument\n"); + return -1; + } + + *pVisibility = ivisurf->prop.visibility; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceSetOpacity(struct ivi_layout_surface *ivisurf, + float opacity) +{ + struct ivi_layout_SurfaceProperties *prop = NULL; + + if (ivisurf == NULL) { + weston_log("ivi_layout_surfaceSetOpacity: invalid argument\n"); + return -1; + } + + prop = &ivisurf->pending.prop; + prop->opacity = opacity; + + ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceGetOpacity(struct ivi_layout_surface *ivisurf, + float *pOpacity) +{ + if (ivisurf == NULL || pOpacity == NULL) { + weston_log("ivi_layout_surfaceGetOpacity: invalid argument\n"); + return -1; + } + + *pOpacity = ivisurf->prop.opacity; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_SetKeyboardFocusOn(struct ivi_layout_surface *ivisurf) +{ + /* TODO */ + (void)ivisurf; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_GetKeyboardFocusSurfaceId(struct ivi_layout_surface **pSurfaceId) +{ + /* TODO */ + (void)pSurfaceId; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceSetDestinationRectangle(struct ivi_layout_surface *ivisurf, + int32_t x, int32_t y, + uint32_t width, uint32_t height) +{ + struct ivi_layout_SurfaceProperties *prop = NULL; + + if (ivisurf == NULL) { + weston_log("ivi_layout_surfaceSetDestinationRectangle: invalid argument\n"); + return -1; + } + + prop = &ivisurf->pending.prop; + prop->destX = x; + prop->destY = y; + prop->destWidth = width; + prop->destHeight = height; + + ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceSetDimension(struct ivi_layout_surface *ivisurf, uint32_t *pDimension) +{ + struct ivi_layout_SurfaceProperties *prop = NULL; + + if (ivisurf == NULL || &pDimension[0] == NULL || &pDimension[1] == NULL) { + weston_log("ivi_layout_surfaceSetDimension: invalid argument\n"); + return -1; + } + + prop = &ivisurf->pending.prop; + prop->destWidth = pDimension[0]; + prop->destHeight = pDimension[1]; + + ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceGetDimension(struct ivi_layout_surface *ivisurf, + uint32_t *pDimension) +{ + if (ivisurf == NULL || &pDimension[0] == NULL || &pDimension[1] == NULL) { + weston_log("ivi_layout_surfaceGetDimension: invalid argument\n"); + return -1; + } + + pDimension[0] = ivisurf->prop.destWidth; + pDimension[1] = ivisurf->prop.destHeight; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceSetPosition(struct ivi_layout_surface *ivisurf, + int32_t *pPosition) +{ + struct ivi_layout_SurfaceProperties *prop = NULL; + + if (ivisurf == NULL || pPosition == NULL) { + weston_log("ivi_layout_surfaceSetPosition: invalid argument\n"); + return -1; + } + + prop = &ivisurf->pending.prop; + prop->destX = pPosition[0]; + prop->destY = pPosition[1]; + + ivisurf->event_mask |= IVI_NOTIFICATION_POSITION; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceGetPosition(struct ivi_layout_surface *ivisurf, + int32_t *pPosition) +{ + if (ivisurf == NULL || pPosition == NULL) { + weston_log("ivi_layout_surfaceGetPosition: invalid argument\n"); + return -1; + } + + pPosition[0] = ivisurf->prop.destX; + pPosition[1] = ivisurf->prop.destY; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceSetOrientation(struct ivi_layout_surface *ivisurf, + uint32_t orientation) +{ + struct ivi_layout_SurfaceProperties *prop = NULL; + + if (ivisurf == NULL) { + weston_log("ivi_layout_surfaceSetOrientation: invalid argument\n"); + return -1; + } + + prop = &ivisurf->pending.prop; + prop->orientation = orientation; + + ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceGetOrientation(struct ivi_layout_surface *ivisurf, + uint32_t *pOrientation) +{ + if (ivisurf == NULL || pOrientation == NULL) { + weston_log("ivi_layout_surfaceGetOrientation: invalid argument\n"); + return -1; + } + + *pOrientation = ivisurf->prop.orientation; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceGetPixelformat(struct ivi_layout_layer *ivisurf, uint32_t *pPixelformat) +{ + /* TODO */ + (void)ivisurf; + (void)pPixelformat; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceSetChromaKey(struct ivi_layout_surface *ivisurf, uint32_t* pColor) +{ + /* TODO */ + (void)ivisurf; + (void)pColor; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_screenAddLayer(struct ivi_layout_screen *iviscrn, + struct ivi_layout_layer *addlayer) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_layer *ivilayer = NULL; + struct ivi_layout_layer *next = NULL; + int is_layer_in_scrn = 0; + + if (iviscrn == NULL || addlayer == NULL) { + weston_log("ivi_layout_screenAddLayer: invalid argument\n"); + return -1; + } + + is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn); + if (is_layer_in_scrn == 1) { + weston_log("ivi_layout_screenAddLayer: addlayer is already available\n"); + return 0; + } + + wl_list_for_each_safe(ivilayer, next, &layout->list_layer, link) { + if (ivilayer->id_layer == addlayer->id_layer) { + if (!wl_list_empty(&ivilayer->pending.link)) { + wl_list_remove(&ivilayer->pending.link); + } + wl_list_init(&ivilayer->pending.link); + wl_list_insert(&iviscrn->pending.list_layer, + &ivilayer->pending.link); + break; + } + } + + iviscrn->event_mask |= IVI_NOTIFICATION_ADD; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_screenSetRenderOrder(struct ivi_layout_screen *iviscrn, + struct ivi_layout_layer **pLayer, + const uint32_t number) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_layer *ivilayer = NULL; + struct ivi_layout_layer *next = NULL; + uint32_t *id_layer = NULL; + uint32_t i = 0; + + if (iviscrn == NULL) { + weston_log("ivi_layout_screenSetRenderOrder: invalid argument\n"); + return -1; + } + + wl_list_for_each_safe(ivilayer, next, + &iviscrn->pending.list_layer, pending.link) { + wl_list_init(&ivilayer->pending.link); + } + + wl_list_init(&iviscrn->pending.list_layer); + + if (pLayer == NULL) { + return 0; + } + + for (i = 0; i < number; i++) { + id_layer = &pLayer[i]->id_layer; + wl_list_for_each(ivilayer, &layout->list_layer, link) { + if (*id_layer != ivilayer->id_layer) { + continue; + } + + if (!wl_list_empty(&ivilayer->pending.link)) { + wl_list_remove(&ivilayer->pending.link); + } + wl_list_init(&ivilayer->pending.link); + wl_list_insert(&iviscrn->pending.list_layer, + &ivilayer->pending.link); + break; + } + } + + iviscrn->event_mask |= IVI_NOTIFICATION_ADD; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_takeScreenshot(struct ivi_layout_screen *iviscrn, + const char *filename) +{ + struct weston_output *output = NULL; + cairo_surface_t *cairo_surf = NULL; + int32_t i = 0; + int32_t width = 0; + int32_t height = 0; + int32_t stride = 0; + uint8_t *readpixs = NULL; + uint8_t *writepixs = NULL; + uint8_t *d = NULL; + uint8_t *s = NULL; + + if (iviscrn == NULL || filename == NULL) { + weston_log("ivi_layout_takeScreenshot: invalid argument\n"); + return -1; + } + + output = iviscrn->output; + output->disable_planes--; + + width = output->current_mode->width; + height = output->current_mode->height; + stride = width * (PIXMAN_FORMAT_BPP(output->compositor->read_format) / 8); + + readpixs = malloc(stride * height); + if (readpixs == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + writepixs = malloc(stride * height); + if (writepixs == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + output->compositor->renderer->read_pixels(output, + output->compositor->read_format, readpixs, + 0, 0, width, height); + + s = readpixs; + d = writepixs + stride * (height - 1); + + for (i = 0; i < height; i++) { + memcpy(d, s, stride); + d -= stride; + s += stride; + } + + cairo_surf = cairo_image_surface_create_for_data(writepixs, + CAIRO_FORMAT_ARGB32, + width, height, stride); + cairo_surface_write_to_png(cairo_surf, filename); + cairo_surface_destroy(cairo_surf); + free(writepixs); + free(readpixs); + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_takeLayerScreenshot(const char *filename, struct ivi_layout_layer *ivilayer) +{ + /* TODO */ + (void)filename; + (void)ivilayer; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_takeSurfaceScreenshot(const char *filename, + struct ivi_layout_surface *ivisurf) +{ + weston_log("ivi_layout_takeSurfaceScreenshot: " + "This function is not supported now\n"); + return 0; +} + +WL_EXPORT int32_t +ivi_layout_SetOptimizationMode(uint32_t id, uint32_t mode) +{ + /* TODO */ + (void)id; + (void)mode; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_GetOptimizationMode(uint32_t id, uint32_t *pMode) +{ + /* TODO */ + (void)id; + (void)pMode; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerAddNotification(struct ivi_layout_layer *ivilayer, + layerPropertyNotificationFunc callback, + void *userdata) +{ + struct link_layerPropertyNotification *notification = NULL; + + if (ivilayer == NULL || callback == NULL) { + weston_log("ivi_layout_layerAddNotification: invalid argument\n"); + return -1; + } + + notification = malloc(sizeof *notification); + if (notification == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + notification->callback = callback; + notification->userdata = userdata; + wl_list_init(¬ification->link); + wl_list_insert(&ivilayer->list_notification, ¬ification->link); + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerRemoveNotification(struct ivi_layout_layer *ivilayer) +{ + struct link_layerPropertyNotification *notification = NULL; + struct link_layerPropertyNotification *next = NULL; + + if (ivilayer == NULL) { + weston_log("ivi_layout_layerRemoveNotification: invalid argument\n"); + return -1; + } + + wl_list_for_each_safe(notification, next, + &ivilayer->list_notification, link) { + if (!wl_list_empty(¬ification->link)) { + wl_list_remove(¬ification->link); + } + free(notification); + } + wl_list_init(&ivilayer->list_notification); + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_getPropertiesOfSurface(struct ivi_layout_surface *ivisurf, + struct ivi_layout_SurfaceProperties *pSurfaceProperties) +{ + if (ivisurf == NULL || pSurfaceProperties == NULL) { + weston_log("ivi_layout_getPropertiesOfSurface: invalid argument\n"); + return -1; + } + + *pSurfaceProperties = ivisurf->prop; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerAddSurface(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface *addsurf) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_surface *ivisurf = NULL; + struct ivi_layout_surface *next = NULL; + int is_surf_in_layer = 0; + + if (ivilayer == NULL || addsurf == NULL) { + weston_log("ivi_layout_layerAddSurface: invalid argument\n"); + return -1; + } + + is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer); + if (is_surf_in_layer == 1) { + weston_log("ivi_layout_layerAddSurface: addsurf is already available\n"); + return 0; + } + + wl_list_for_each_safe(ivisurf, next, &layout->list_surface, link) { + if (ivisurf->id_surface == addsurf->id_surface) { + if (!wl_list_empty(&ivisurf->pending.link)) { + wl_list_remove(&ivisurf->pending.link); + } + wl_list_init(&ivisurf->pending.link); + wl_list_insert(&ivilayer->pending.list_surface, + &ivisurf->pending.link); + break; + } + } + + ivilayer->event_mask |= IVI_NOTIFICATION_ADD; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_layerRemoveSurface(struct ivi_layout_layer *ivilayer, + struct ivi_layout_surface *remsurf) +{ + struct ivi_layout_surface *ivisurf = NULL; + struct ivi_layout_surface *next = NULL; + + if (ivilayer == NULL || remsurf == NULL) { + weston_log("ivi_layout_layerRemoveSurface: invalid argument\n"); + return -1; + } + + wl_list_for_each_safe(ivisurf, next, + &ivilayer->pending.list_surface, pending.link) { + if (ivisurf->id_surface == remsurf->id_surface) { + if (!wl_list_empty(&ivisurf->pending.link)) { + wl_list_remove(&ivisurf->pending.link); + } + wl_list_init(&ivisurf->pending.link); + break; + } + } + + ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_surfaceSetSourceRectangle(struct ivi_layout_surface *ivisurf, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height) +{ + struct ivi_layout_SurfaceProperties *prop = NULL; + + if (ivisurf == NULL) { + weston_log("ivi_layout_surfaceSetSourceRectangle: invalid argument\n"); + return -1; + } + + prop = &ivisurf->pending.prop; + prop->sourceX = x; + prop->sourceY = y; + prop->sourceWidth = width; + prop->sourceHeight = height; + + ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT; + + return 0; +} + +WL_EXPORT int32_t +ivi_layout_commitChanges(void) +{ + struct ivi_layout *layout = get_instance(); + + commit_list_surface(layout); + commit_list_layer(layout); + commit_list_screen(layout); + + commit_changes(layout); + send_prop(layout); + weston_compositor_schedule_repaint(layout->compositor); + + return 0; +} + +/***called from ivi-shell**/ +static struct weston_view * +ivi_layout_get_weston_view(struct ivi_layout_surface *surface) +{ + return (surface != NULL) ? surface->view : NULL; +} + +static void +ivi_layout_surfaceConfigure(struct ivi_layout_surface *ivisurf, + uint32_t width, uint32_t height) +{ + struct ivi_layout *layout = get_instance(); + struct link_surfaceCreateNotification *notification = NULL; + + ivisurf->buffer_width = width; + ivisurf->buffer_height = height; + + wl_list_for_each(notification, + &layout->surface_notification.list_configure, link) { + if (notification->callback != NULL) { + notification->callback(ivisurf, notification->userdata); + } + } +} + +static int32_t +ivi_layout_surfaceSetNativeContent(struct weston_surface *surface, + uint32_t width, + uint32_t height, + uint32_t id_surface) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_surface *ivisurf; + struct link_surfaceCreateNotification *notification = NULL; + + ivisurf = get_surface(&layout->list_surface, id_surface); + if (ivisurf == NULL) { + weston_log("layout surface is not found\n"); + return -1; + } + + if (ivisurf->surface != NULL) { + if (surface != NULL) { + weston_log("id_surface(%d) is already set the native content\n", + id_surface); + return -1; + } + + wl_list_remove(&ivisurf->surface_destroy_listener.link); + weston_view_destroy(ivisurf->view); + + ivisurf->surface = NULL; + ivisurf->view = NULL; + } + + if (surface == NULL) + return 0; + + ivisurf->surface = surface; + ivisurf->surface_destroy_listener.notify = + westonsurface_destroy_from_ivisurface; + wl_resource_add_destroy_listener(surface->resource, + &ivisurf->surface_destroy_listener); + ivisurf->view = weston_view_create(surface); + if (ivisurf->view == NULL) { + weston_log("fails to allocate memory\n"); + return -1; + } + + ivisurf->buffer_width = width; + ivisurf->buffer_height = height; + ivisurf->pixelformat = IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_8888; + + wl_list_for_each(notification, + &layout->surface_notification.list_create, link) { + if (notification->callback != NULL) { + notification->callback(ivisurf, notification->userdata); + } + } + + return 0; +} + +static struct ivi_layout_surface* +ivi_layout_surfaceCreate(struct weston_surface *wl_surface, + uint32_t id_surface) +{ + struct ivi_layout *layout = get_instance(); + struct ivi_layout_surface *ivisurf = NULL; + struct link_surfaceCreateNotification *notification = NULL; + + if (wl_surface == NULL) { + weston_log("ivi_layout_surfaceCreate: invalid argument\n"); + return NULL; + } + + ivisurf = get_surface(&layout->list_surface, id_surface); + if (ivisurf != NULL) { + if (ivisurf->surface != NULL) { + weston_log("id_surface(%d) is already created\n", id_surface); + return NULL; + } else { + /* if ivisurf->surface exist, wl_surface is tied to id_surface again */ + /* This means client destroys ivi_surface once, and then tries to tie + the id_surface to new wl_surface again. The property of id_surface can + be inherited. + */ + ivi_layout_surfaceSetNativeContent( + wl_surface, wl_surface->width, wl_surface->height, id_surface); + return ivisurf; + } + } + + ivisurf = calloc(1, sizeof *ivisurf); + if (ivisurf == NULL) { + weston_log("fails to allocate memory\n"); + return NULL; + } + + wl_list_init(&ivisurf->link); + wl_list_init(&ivisurf->list_notification); + wl_list_init(&ivisurf->list_layer); + ivisurf->id_surface = id_surface; + ivisurf->layout = layout; + + ivisurf->surface = wl_surface; + ivisurf->surface_destroy_listener.notify = + westonsurface_destroy_from_ivisurface; + wl_resource_add_destroy_listener(wl_surface->resource, + &ivisurf->surface_destroy_listener); + + ivisurf->view = weston_view_create(wl_surface); + if (ivisurf->view == NULL) { + weston_log("fails to allocate memory\n"); + } + + ivisurf->buffer_width = 0; + ivisurf->buffer_height = 0; + + weston_matrix_init(&ivisurf->view->transform.matrix); + + weston_matrix_init(&ivisurf->surface_rotation.matrix); + weston_matrix_init(&ivisurf->layer_rotation.matrix); + weston_matrix_init(&ivisurf->surface_pos.matrix); + weston_matrix_init(&ivisurf->layer_pos.matrix); + weston_matrix_init(&ivisurf->scaling.matrix); + + wl_list_init(&ivisurf->surface_rotation.link); + wl_list_init(&ivisurf->layer_rotation.link); + wl_list_init(&ivisurf->surface_pos.link); + wl_list_init(&ivisurf->layer_pos.link); + wl_list_init(&ivisurf->scaling.link); + + init_surfaceProperties(&ivisurf->prop); + ivisurf->pixelformat = IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_8888; + ivisurf->event_mask = 0; + + ivisurf->pending.prop = ivisurf->prop; + wl_list_init(&ivisurf->pending.link); + + wl_list_init(&ivisurf->order.link); + wl_list_init(&ivisurf->order.list_layer); + + wl_list_insert(&layout->list_surface, &ivisurf->link); + + wl_list_for_each(notification, + &layout->surface_notification.list_create, link) { + if (notification->callback != NULL) { + notification->callback(ivisurf, notification->userdata); + } + } + + return ivisurf; +} + +static void +ivi_layout_initWithCompositor(struct weston_compositor *ec) +{ + struct ivi_layout *layout = get_instance(); + + layout->compositor = ec; + + wl_list_init(&layout->list_surface); + wl_list_init(&layout->list_layer); + wl_list_init(&layout->list_screen); + + wl_list_init(&layout->layer_notification.list_create); + wl_list_init(&layout->layer_notification.list_remove); + + wl_list_init(&layout->surface_notification.list_create); + wl_list_init(&layout->surface_notification.list_remove); + wl_list_init(&layout->surface_notification.list_configure); + + /* Add layout_layer at the last of weston_compositor.layer_list */ + weston_layer_init(&layout->layout_layer, ec->layer_list.prev); + + create_screen(ec); + + struct weston_config *config = weston_config_parse("weston.ini"); + struct weston_config_section *s = + weston_config_get_section(config, "ivi-shell", NULL, NULL); + + /*A cursor is configured if weston.ini has keys.*/ + char* cursor_theme = NULL; + weston_config_section_get_string(s, "cursor-theme", &cursor_theme, NULL); + if (cursor_theme) + free(cursor_theme); + else + wl_list_remove(&ec->cursor_layer.link); + weston_config_destroy(config); +} + + +WL_EXPORT struct ivi_layout_interface ivi_layout_interface = { + .get_weston_view = ivi_layout_get_weston_view, + .surfaceConfigure = ivi_layout_surfaceConfigure, + .surfaceSetNativeContent = ivi_layout_surfaceSetNativeContent, + .surfaceCreate = ivi_layout_surfaceCreate, + .initWithCompositor = ivi_layout_initWithCompositor +}; |