summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzheng_wenlong <wenlong_zheng@nexty-ele.com>2018-11-14 12:49:40 +0900
committerzheng_wenlong <wenlong_zheng@nexty-ele.com>2018-11-14 12:49:40 +0900
commit110215ad40cd0c24ed5ae70430e45304d5c60fe1 (patch)
tree3e5425dfbf5a4b7c18e3bc04edab2287a03e6415
parent6170bf6293128807341bbeda4eb9aa54a36276cc (diff)
Add waltham server for horizontal mode.
Add waltham server for horizontal mode. This application is used for receive video from waltham transmitter. Change-Id: I794abf014eb014a4f0b42175093bf5c898e261f5 Signed-off-by: zheng_wenlong <wenlong_zheng@nexty-ele.com>
-rw-r--r--demo3/README.md3
-rw-r--r--demo3/horizontal/waltham-server/CMakeLists.txt111
-rw-r--r--demo3/horizontal/waltham-server/README.md71
-rw-r--r--demo3/horizontal/waltham-server/config/pipeline.cfg1
-rw-r--r--demo3/horizontal/waltham-server/include/bitmap.h35
-rw-r--r--demo3/horizontal/waltham-server/include/hmi-debug.h70
-rw-r--r--demo3/horizontal/waltham-server/include/os-compatibility.h58
-rw-r--r--demo3/horizontal/waltham-server/include/wth-server-waltham-comm.h524
-rw-r--r--demo3/horizontal/waltham-server/include/wth-server-weston.h99
-rw-r--r--demo3/horizontal/waltham-server/orig/CMakeLists.txt93
-rw-r--r--demo3/horizontal/waltham-server/orig/README76
-rw-r--r--demo3/horizontal/waltham-server/orig/include/bitmap.h35
-rw-r--r--demo3/horizontal/waltham-server/orig/include/os-compatibility.h58
-rw-r--r--demo3/horizontal/waltham-server/orig/include/wth-server-waltham-comm.h524
-rw-r--r--demo3/horizontal/waltham-server/orig/include/wth-server-weston.h99
-rw-r--r--demo3/horizontal/waltham-server/orig/protocol/ivi-application.xml100
-rw-r--r--demo3/horizontal/waltham-server/orig/src/utils/bitmap.c107
-rw-r--r--demo3/horizontal/waltham-server/orig/src/utils/os-compatibility.c204
-rw-r--r--demo3/horizontal/waltham-server/orig/src/wth-server-gst.c1151
-rw-r--r--demo3/horizontal/waltham-server/orig/src/wth-server-main.c344
-rw-r--r--demo3/horizontal/waltham-server/orig/src/wth-server-waltham-comm.c1179
-rw-r--r--demo3/horizontal/waltham-server/orig/src/wth-server-weston.c811
-rw-r--r--demo3/horizontal/waltham-server/package/receiver/config.xml17
-rw-r--r--demo3/horizontal/waltham-server/package/receiver/icon.svg279
-rw-r--r--demo3/horizontal/waltham-server/package/root/config.xml17
-rw-r--r--demo3/horizontal/waltham-server/package/root/icon.svg279
-rw-r--r--demo3/horizontal/waltham-server/protocol/ivi-application.xml100
-rw-r--r--demo3/horizontal/waltham-server/screenshot/waltham-server.pngbin0 -> 293268 bytes
-rw-r--r--demo3/horizontal/waltham-server/src/utils/bitmap.c107
-rw-r--r--demo3/horizontal/waltham-server/src/utils/os-compatibility.c204
-rw-r--r--demo3/horizontal/waltham-server/src/wth-server-gst.cpp1326
-rw-r--r--demo3/horizontal/waltham-server/src/wth-server-main.cpp372
-rw-r--r--demo3/horizontal/waltham-server/src/wth-server-waltham-comm.cpp1202
-rw-r--r--demo3/horizontal/waltham-server/src/wth-server-weston.c811
34 files changed, 10466 insertions, 1 deletions
diff --git a/demo3/README.md b/demo3/README.md
index 096098a..3727f9a 100644
--- a/demo3/README.md
+++ b/demo3/README.md
@@ -16,7 +16,8 @@
<br> sandbox branch : [ces2019_horizontal](https://gerrit.automotivelinux.org/gerrit/gitweb?p=apps%2Fals-meter-demo.git;a=shortlog;h=refs%2Fheads%2Fsandbox%2Fzheng_wenlong%2Fces2019_horizontal)
- camapp
<br> sandbox branch : [camapp](https://gerrit.automotivelinux.org/gerrit/gitweb?p=apps%2Fals-meter-demo.git;a=shortlog;h=refs%2Fheads%2Fsandbox%2Fzheng_wenlong%2Fcamapp)
-- ...
+- waltham-server
+ <br> Used for receive video from waltham transmitter. Needs waltham weston.
## vertical (IVI mode)
- homescreen
<br> sandbox branch : [ces2019_vertical](https://gerrit.automotivelinux.org/gerrit/gitweb?p=apps%2Fhomescreen.git;a=shortlog;h=refs%2Fheads%2Fsandbox%2Fzheng_wenlong%2Fces2019_vertical)
diff --git a/demo3/horizontal/waltham-server/CMakeLists.txt b/demo3/horizontal/waltham-server/CMakeLists.txt
new file mode 100644
index 0000000..2f8d74e
--- /dev/null
+++ b/demo3/horizontal/waltham-server/CMakeLists.txt
@@ -0,0 +1,111 @@
+cmake_minimum_required( VERSION 2.8.5 )
+
+project (waltham-server)
+
+set(CMAKE_CXX_FLAGS "-Wall -fpermissive")
+
+find_package(PkgConfig)
+find_package (Threads)
+pkg_check_modules(WAYLAND_CLIENT wayland-client REQUIRED)
+pkg_check_modules(WAYLAND_CURSOR wayland-cursor REQUIRED)
+pkg_check_modules(WALTHAM waltham REQUIRED)
+pkg_check_modules(GLESv2 glesv2 REQUIRED)
+pkg_check_modules(WAYLAND_EGL wayland-egl REQUIRED)
+pkg_search_module(EGL egl required)
+pkg_search_module(GSTREAMER gstreamer-1.0 required)
+pkg_search_module(GSTREAMERAPP gstreamer-app-1.0 required)
+pkg_search_module(DRM libdrm required)
+
+find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
+find_library(GST_ALLOCATOR NAMES gstallocators-1.0 PATHs /usr/lib64)
+find_library(GST_VIDEO NAMES gstvideo-1.0 PATHs /usr/lib64)
+add_custom_command(
+ OUTPUT ivi-application-client-protocol.h
+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} client-header
+ < ${CMAKE_SOURCE_DIR}/protocol/ivi-application.xml
+ > ${CMAKE_CURRENT_BINARY_DIR}/ivi-application-client-protocol.h
+ DEPENDS ${CMAKE_SOURCE_DIR}/protocol/ivi-application.xml
+)
+
+add_custom_command(
+ OUTPUT ivi-application-protocol.c
+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} code
+ < ${CMAKE_SOURCE_DIR}/protocol/ivi-application.xml
+ > ${CMAKE_CURRENT_BINARY_DIR}/ivi-application-protocol.c
+ DEPENDS ${CMAKE_SOURCE_DIR}/protocol/ivi-application.xml
+)
+
+include_directories(
+ ${WAYLAND_CLIENT_INCLUDE_DIR}
+ ${WAYLAND_CURSOR_INCLUDE_DIR}
+ ${WALTHAM_INCLUDE_DIRS}
+ ${DRM_INCLUDE_DIRS}
+ ${GSTREAMER_LIBRARY_DIRS}
+ ${GSTREAMER_INCLUDE_DIRS}
+ ${GSTREAMERAPP_INCLUDE_DIRS}
+ ${EGL_INCLUDE_DIRS}
+ ${WAYLAND_EGL_INCLUDE_DIR}
+ ${GLESv2_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/include/
+ ${CMAKE_SOURCE_DIR}/waltham-renderer
+)
+
+link_directories(
+ ${WAYLAND_CLIENT_LIBRARY_DIRS}
+ ${WAYLAND_CURSOR_LIBRARY_DIRS}
+ ${WALTHAM_LIBRARY_DIRS}
+ ${EGL_LIBRARY_DIRS}
+ ${WAYLAND_EGL_LIBRAY_DIRS}
+ ${GLESv2_LIBRARY_DIRS}
+ ${GSTREAMER_LIBRARY_DIRS}
+ ${GSTREAMERAPP_LIBRARY_DIRS}
+)
+
+SET(LIBS
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${WAYLAND_CLIENT_LIBRARIES}
+ ${WAYLAND_CURSOR_LIBRARIES}
+ ${WALTHAM_LIBRARIES}
+ ${EGL_LIBRARIES}
+ ${WAYLAND_EGL_LIBRARIES}
+ ${GLESv2_LIBRARIES}
+ ${GSTREAMER_LIBRARIES}
+ ${GSTREAMERAPP_LIBRARIES}
+ ${GST_ALLOCATOR}
+ ${GST_VIDEO}
+ libwindowmanager.so
+ libjson-c.so
+ libhomescreen.so
+)
+
+SET(SRC_FILES
+ src/wth-server-main.cpp
+ src/wth-server-waltham-comm.cpp
+ src/wth-server-gst.cpp
+ src/utils/bitmap.c
+ src/utils/os-compatibility.c
+ ivi-application-protocol.c
+ ivi-application-client-protocol.h
+)
+
+add_executable(${PROJECT_NAME} ${SRC_FILES})
+
+add_definitions(${EGL_CFLAGS})
+
+target_link_libraries(${PROJECT_NAME} ${LIBS})
+
+add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
+ COMMAND cp -rf ${CMAKE_CURRENT_SOURCE_DIR}/package ${PROJECT_BINARY_DIR}
+ COMMAND mkdir -p ${PROJECT_BINARY_DIR}/package/root/bin
+ COMMAND cp -rf ${PROJECT_BINARY_DIR}/${PROJECT_NAME} ${PROJECT_BINARY_DIR}/package/root/bin)
+
+add_custom_target(widget DEPENDS ${PROJECT_BINARY_DIR}/package/root
+ COMMAND wgtpkg-pack -f -o ${PROJECT_BINARY_DIR}/package/${PROJECT_NAME}.wgt ${PROJECT_BINARY_DIR}/package/root)
+
+add_custom_target(receiver DEPENDS ${PROJECT_BINARY_DIR}/package/root
+ COMMAND mkdir -p ${PROJECT_BINARY_DIR}/package/receiver/bin
+ COMMAND cp -rf ${PROJECT_BINARY_DIR}/${PROJECT_NAME} ${PROJECT_BINARY_DIR}/package/receiver/bin/receiver
+ COMMAND wgtpkg-pack -f -o ${PROJECT_BINARY_DIR}/package/receiver.wgt ${PROJECT_BINARY_DIR}/package/receiver)
+
+install (TARGETS ${PROJECT_NAME} DESTINATION bin)
diff --git a/demo3/horizontal/waltham-server/README.md b/demo3/horizontal/waltham-server/README.md
new file mode 100644
index 0000000..0b48aa4
--- /dev/null
+++ b/demo3/horizontal/waltham-server/README.md
@@ -0,0 +1,71 @@
+**Overview**
+
+This application receives transmitted data by waltham-transmitter.
+This application is implemented based on waltham-server.
+The original source code of waltham-server is in `./orig`.
+
+**Download**
+
+Download souce code and SDK from gitlab.
+
+```
+$ git clone http://oss-project.tmc-tokai.jp/gitlab/WindowManager/waltham-server.git
+```
+
+*NOTE*
+
+This application uses waltham protocol, therefore waltham librarys is necessary.
+The downloaded SDK includes the libraries.
+If build this application, please use this SDK.
+
+**Install SDK**
+
+1. Install SDK which is in `./sdk`.
+```
+$ cd ./sdk
+$ ./poky-agl-glibc-x86_64-agl-demo-platform-crosssdk-aarch64-toolchain-6.0.0.sh
+```
+
+1. Copy gstglconfig.h
+This SDK has gstglconfig.h
+but it exists in `<sdk_installed_path>/sysroots/aarch64-agl-linux/usr/lib`
+and it occures build error.
+Therefore copy it to `<sdk_installed_path>/sysroots/aarch64-agl-linux/usr/include`.
+```
+$ cd <sdk_installed_path>/sysroots/aarch64-agl-linux/
+$ cp usr/lib/gstreamer-1.0/include/gst/gl/gstglconfig.h usr/include/gstreamer-1.0/gst/gl/
+```
+
+**Build application**
+
+Source SDK envirment and make.
+```
+$ source <sdk_installed_path>/environment-setup-aarch64-agl-linux
+$ cd waltham-server
+$ mkdir build
+$ cd build
+$ cmake ..
+$ make
+$ make receiver
+```
+
+**Install wgt and config file**
+
+```
+[On host]
+$ scp build/package/receiver.wgt root@<your_target_ip>
+$ scp config/pipeline.cfg root@<your_target_ip>:/etc/xdg/weston
+$ ssh root@<your_target_ip>
+
+[On target]
+# afm-util install receiver.wgt
+# sync
+```
+
+**NOTE**
+
+This application uses port 34400 by default.
+If change it, please modify the followings:
+
+- In `config/pipeline.cfg`, value of `port` at line 1.
+- In `src/wth-server-main.cpp`, value of `tcp_port` at line 49.
diff --git a/demo3/horizontal/waltham-server/config/pipeline.cfg b/demo3/horizontal/waltham-server/config/pipeline.cfg
new file mode 100644
index 0000000..536540b
--- /dev/null
+++ b/demo3/horizontal/waltham-server/config/pipeline.cfg
@@ -0,0 +1 @@
+udpsrc port=34400 caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)JPEG,payload=(int)26" ! rtpjpegdepay ! jpegdec ! videoconvert ! video/x-raw,format=RGBA ! appsink name=sink sync=true
diff --git a/demo3/horizontal/waltham-server/include/bitmap.h b/demo3/horizontal/waltham-server/include/bitmap.h
new file mode 100644
index 0000000..3cef52d
--- /dev/null
+++ b/demo3/horizontal/waltham-server/include/bitmap.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+#ifndef IVICONTROLLER_BITMAP_H_
+#define IVICONTROLLER_BITMAP_H_
+
+#include <stdint.h>
+
+int save_as_bitmap(const char *filename,
+ const char *buffer,
+ int32_t image_size,
+ int32_t width,
+ int32_t height,
+ int16_t bpp
+ );
+
+#endif /* IVICONTROLLER_BITMAP_H_*/
diff --git a/demo3/horizontal/waltham-server/include/hmi-debug.h b/demo3/horizontal/waltham-server/include/hmi-debug.h
new file mode 100644
index 0000000..2a744ba
--- /dev/null
+++ b/demo3/horizontal/waltham-server/include/hmi-debug.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __HMI_DEBUG_H__
+#define __HMI_DEBUG_H__
+
+#include <time.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+
+enum LOG_LEVEL{
+ LOG_LEVEL_NONE = 0,
+ LOG_LEVEL_ERROR,
+ LOG_LEVEL_WARNING,
+ LOG_LEVEL_NOTICE,
+ LOG_LEVEL_INFO,
+ LOG_LEVEL_DEBUG,
+ LOG_LEVEL_MAX = LOG_LEVEL_DEBUG
+};
+
+#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
+
+#define HMI_ERROR(prefix, args,...) _HMI_LOG(LOG_LEVEL_ERROR, __FILENAME__, __FUNCTION__, __LINE__, prefix, args, ##__VA_ARGS__)
+#define HMI_WARNING(prefix, args,...) _HMI_LOG(LOG_LEVEL_WARNING, __FILENAME__, __FUNCTION__,__LINE__, prefix, args,##__VA_ARGS__)
+#define HMI_NOTICE(prefix, args,...) _HMI_LOG(LOG_LEVEL_NOTICE, __FILENAME__, __FUNCTION__,__LINE__, prefix, args,##__VA_ARGS__)
+#define HMI_INFO(prefix, args,...) _HMI_LOG(LOG_LEVEL_INFO, __FILENAME__, __FUNCTION__,__LINE__, prefix, args,##__VA_ARGS__)
+#define HMI_DEBUG(prefix, args,...) _HMI_LOG(LOG_LEVEL_DEBUG, __FILENAME__, __FUNCTION__,__LINE__, prefix, args,##__VA_ARGS__)
+
+static char ERROR_FLAG[6][20] = {"NONE", "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG"};
+
+static void _HMI_LOG(enum LOG_LEVEL level, const char* file, const char* func, const int line, const char* prefix, const char* log, ...)
+{
+ const int log_level = (getenv("USE_HMI_DEBUG") == NULL)?LOG_LEVEL_ERROR:atoi(getenv("USE_HMI_DEBUG"));
+ if(log_level < level)
+ {
+ return;
+ }
+
+ char *message;
+ struct timespec tp;
+ unsigned int time;
+
+ clock_gettime(CLOCK_REALTIME, &tp);
+ time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
+
+ va_list args;
+ va_start(args, log);
+ if (log == NULL || vasprintf(&message, log, args) < 0)
+ message = NULL;
+ fprintf(stderr, "[%10.3f] [%s %s] [%s, %s(), Line:%d] >>> %s \n", time / 1000.0, prefix, ERROR_FLAG[level], file, func, line, message);
+ va_end(args);
+ free(message);
+}
+
+#endif //__HMI_DEBUG_H__ \ No newline at end of file
diff --git a/demo3/horizontal/waltham-server/include/os-compatibility.h b/demo3/horizontal/waltham-server/include/os-compatibility.h
new file mode 100644
index 0000000..690f229
--- /dev/null
+++ b/demo3/horizontal/waltham-server/include/os-compatibility.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2012 Collabora, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef OS_COMPATIBILITY_H
+#define OS_COMPATIBILITY_H
+
+#include <sys/types.h>
+
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#else
+static inline int
+backtrace(void **buffer, int size)
+{
+ return 0;
+}
+#endif
+
+int
+os_fd_set_cloexec(int fd);
+
+int
+os_socketpair_cloexec(int domain, int type, int protocol, int *sv);
+
+int
+os_epoll_create_cloexec(void);
+
+int
+os_create_anonymous_file(off_t size);
+
+#ifndef HAVE_STRCHRNUL
+char *
+strchrnul(const char *s, int c);
+#endif
+
+#endif /* OS_COMPATIBILITY_H */
diff --git a/demo3/horizontal/waltham-server/include/wth-server-waltham-comm.h b/demo3/horizontal/waltham-server/include/wth-server-waltham-comm.h
new file mode 100644
index 0000000..1d58dde
--- /dev/null
+++ b/demo3/horizontal/waltham-server/include/wth-server-waltham-comm.h
@@ -0,0 +1,524 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+** **
+** SRC-MODULE: **
+** **
+** TARGET : linux **
+** **
+** PROJECT : waltham-server **
+** **
+** AUTHOR : **
+** **
+** **
+** **
+** PURPOSE : Header file declare macros, extern functions, data types etc, **
+** required to interface with waltham IPC library **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+#ifndef WTH_SERVER_WALTHAM_COMM_H_
+#define WTH_SERVER_WALTHAM_COMM_H_
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <sys/epoll.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <assert.h>
+#include <getopt.h>
+#include <unistd.h>
+
+#include <gst/gl/gl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <wayland-egl.h>
+#include <wayland-client.h>
+#include <waltham-server.h>
+#include <waltham-connection.h>
+
+struct server;
+struct client;
+struct window;
+struct pointer;
+struct touch;
+/*
+pthread_mutex_t g_mutex;
+pthread_cond_t g_cond;
+int go_to_wait;
+*/
+extern const struct wth_display_interface display_implementation;
+
+/**
+* server_accept_client
+*
+* Accepts new waltham client connection and instantiates client structure
+*
+* @param names struct server *srv
+* @param value socket connection info and client data
+* @return none
+*/
+void server_accept_client(struct server *srv);
+
+/**
+* server_flush_clients
+*
+* write all the pending requests from the clients to socket
+*
+* @param names struct server *srv
+* @param value socket connection info and client data
+* @return none
+*/
+void server_flush_clients(struct server *srv);
+
+/**
+* client_destroy
+*
+* Destroy client connection
+*
+* @param names struct client *c
+* @param value client data
+* @return none
+*/
+void client_destroy(struct client *c);
+
+/**
+* waltham_pointer_enter
+*
+* Send pointer enter event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t serial
+* wl_fixed_t sx
+* wl_fixed_t sy
+* @param value window - window information
+* serial - serial number of the enter event
+* sx - surface-local x coordinate
+* sy - surface-local y coordinate
+* @return none
+*/
+void waltham_pointer_enter(struct window *window, uint32_t serial,
+ wl_fixed_t sx, wl_fixed_t sy);
+
+/**
+* waltham_pointer_leave
+*
+* Send pointer leave event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t serial
+* @param value window - window information
+* serial - serial number of the leave event
+* @return none
+*/
+void waltham_pointer_leave(struct window *window, uint32_t serial);
+
+/**
+* waltham_pointer_motion
+*
+* Send pointer motion event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t time
+* wl_fixed_t sx
+* wl_fixed_t sy
+* @param value window - window information
+* time - timestamp with millisecond granularity
+* sx - surface-local x coordinate
+* sy - surface-local y coordinate
+* @return none
+*/
+void waltham_pointer_motion(struct window *window, uint32_t time,
+ wl_fixed_t sx, wl_fixed_t sy);
+
+/**
+* waltham_pointer_button
+*
+* Send pointer button event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t serial
+* uint32_t time
+* uint32_t button
+* uint32_t state
+* @param value window - window information
+* serial - serial number of the button event
+* time - timestamp with millisecond granularity
+* button - button that produced the event
+* state - physical state of the button
+* @return none
+*/
+void waltham_pointer_button(struct window *window, uint32_t serial,
+ uint32_t time, uint32_t button,
+ uint32_t state);
+
+/**
+* waltham_pointer_axis
+*
+* Send pointer axis event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t time
+* uint32_t axis
+* wl_fixed_t value
+* @param value window - window information
+* time - timestamp with millisecond granularity
+* axis - axis type
+* value - length of vector in surface-local coordinate space
+* @return none
+*/
+void waltham_pointer_axis(struct window *window, uint32_t time,
+ uint32_t axis, wl_fixed_t value);
+
+/**
+* waltham_touch_down
+*
+* Send touch down event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t serial
+* uint32_t time
+* int32_t id
+* wl_fixed_t x_w
+* wl_fixed_t y_w
+* @param value window - window information
+* serial - serial number of the touch down event
+* time - timestamp with millisecond granularity
+* id - the unique ID of this touch point
+* x_w - surface-local x coordinate
+* y_w - surface-local y coordinate
+* @return none
+*/
+void waltham_touch_down(struct window *window, uint32_t serial,
+ uint32_t time, int32_t id,
+ wl_fixed_t x_w, wl_fixed_t y_w);
+
+/**
+* waltham_touch_up
+*
+* Send touch up event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t serial
+* uint32_t time
+* int32_t id
+* @param value window - window information
+* serial - serial number of the touch up event
+* time - timestamp with millisecond granularity
+* id - the unique ID of this touch point
+* @return none
+*/
+void waltham_touch_up(struct window *window, uint32_t serial,
+ uint32_t time, int32_t id);
+
+/**
+* waltham_touch_motion
+*
+* Send touch motion event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t time
+* int32_t id
+* wl_fixed_t x_w
+* wl_fixed_t y_w
+* @param value window - window information
+* time - timestamp with millisecond granularity
+* id - the unique ID of this touch point
+* x_w - surface-local x coordinate
+* y_w - surface-local y coordinate
+* @return none
+*/
+void waltham_touch_motion(struct window *window, uint32_t time,
+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w);
+
+/**
+* waltham_touch_frame
+*
+* Send touch frame event received from weston to waltham client
+*
+* @param names struct window *window
+* @param value window - window information
+* @return none
+*/
+void waltham_touch_frame(struct window *window);
+
+/**
+* waltham_touch_cancel
+*
+* Send touch cancel event received from weston to waltham client
+*
+* @param names struct window *window
+* @param value window - window information
+* @return none
+*/
+void waltham_touch_cancel(struct window *window);
+
+
+/***** macros *******/
+#define MAX_EPOLL_WATCHES 2
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({ \
+ const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#define wl_list_last_until_empty(pos, head, member) \
+ while (!wl_list_empty(head) && \
+ (pos = wl_container_of((head)->prev, pos, member), 1))
+
+#ifndef ARRAY_LENGTH
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+#endif
+
+#ifndef pr_fmt
+# define pr_fmt(fmt) fmt
+#endif
+
+#ifndef USE_STDOUT
+# define PRINT_OUT stderr
+#else
+# define PRINT_OUT stdout
+#endif
+
+#define wth_error(fmt, ...) \
+ ({ fprintf(PRINT_OUT, pr_fmt(fmt), ## __VA_ARGS__); fflush(PRINT_OUT); })
+#define wth_verbose(fmt, ...) \
+ ({ if (get_verbosity()) { fprintf(PRINT_OUT, pr_fmt(fmt), ## __VA_ARGS__); fflush(PRINT_OUT); } })
+
+/****** incline functions *****/
+static inline void *
+zalloc(size_t size)
+{
+ return calloc(1, size);
+}
+
+
+/***** Data types *****/
+/* wthp_region protocol object */
+struct region {
+ struct wthp_region *obj;
+ /* pixman_region32_t region; */
+ struct wl_list link; /* struct client::region_list */
+};
+
+/* wthp_compositor protocol object */
+struct compositor {
+ struct wthp_compositor *obj;
+ struct client *client;
+ struct wl_list link; /* struct client::compositor_list */
+};
+
+/* wthp_blob_factory protocol object */
+struct blob_factory {
+ struct wthp_blob_factory *obj;
+ struct client *client;
+ struct wl_list link; /* struct client::blob_factory_list */
+};
+
+/* wthp_buffer protocol object */
+struct buffer {
+ struct wthp_buffer *obj;
+ uint32_t data_sz;
+ void *data;
+ int32_t width;
+ int32_t height;
+ int32_t stride;
+ uint32_t format;
+ struct wl_list link; /* struct client::buffer_list */
+};
+
+/* wthp_seat protocol object */
+struct seat {
+ struct wthp_seat *obj;
+ struct client *client;
+ struct pointer *pointer;
+ struct keyboard *keyboard;
+ struct touch *touch;
+ struct wl_list link; /* struct client::seat_list */
+};
+
+/* wthp_pointer protocol object */
+struct pointer {
+ struct wthp_pointer *obj;
+ struct seat *seat;
+ struct wl_list link; /* struct client::pointer_list */
+};
+
+/* wthp_keyboard protocol object */
+struct keyboard {
+ struct wthp_keyboard *obj;
+ struct seat *seat;
+ struct wl_list link; /* struct client::keyboard_list */
+};
+
+/* wthp_touch protocol object */
+struct touch {
+ struct wthp_touch *obj;
+ struct seat *seat;
+ struct wl_list link; /* struct client::touch_list */
+};
+
+/* wthp_surface protocol object */
+struct surface {
+ struct wthp_surface *obj;
+ uint32_t ivi_id;
+ struct ivisurface3 *ivisurf;
+ struct wthp_callback *cb;
+ struct window *shm_window;
+ struct wl_list link; /* struct client::surface_list */
+};
+/* wthp_ivi_surface protocol object */
+struct ivisurface {
+ struct wthp_ivi_surface *obj;
+ struct wthp_callback *cb;
+ struct wl_list link; /* struct client::surface_list */
+ struct surface *surf;
+};
+
+/* wthp_ivi_application protocol object */
+struct application {
+ struct wthp_ivi_application *obj;
+ struct client *client;
+ struct wl_list link; /* struct client::surface_list */
+};
+
+/* wthp_registry protocol object */
+struct registry {
+ struct wthp_registry *obj;
+ struct client *client;
+ struct wl_list link; /* struct client::registry_list */
+};
+
+enum wthp_seat_capability {
+ /**
+ * the seat has pointer devices
+ */
+ WTHP_SEAT_CAPABILITY_POINTER = 1,
+ /**
+ * the seat has one or more keyboards
+ */
+ WTHP_SEAT_CAPABILITY_KEYBOARD = 2,
+ /**
+ * the seat has touch devices
+ */
+ WTHP_SEAT_CAPABILITY_TOUCH = 4,
+};
+
+/* epoll structure */
+struct watch {
+ struct server *server;
+ int fd;
+ void (*cb)(struct watch *w, uint32_t events);
+};
+
+struct client {
+ struct wl_list link; /* struct server::client_list */
+ struct server *server;
+
+ struct wth_connection *connection;
+ struct watch conn_watch;
+
+ /* client object lists for clean-up on disconnection */
+ struct wl_list registry_list; /* struct registry::link */
+ struct wl_list compositor_list; /* struct compositor::link */
+ struct wl_list region_list; /* struct region::link */
+ struct wl_list surface_list; /* struct surface::link */
+ struct wl_list buffer_list; /* struct buffer::link */
+ struct wl_list seat_list; /* struct seat::link */
+ struct wl_list pointer_list; /* struct pointer::link */
+ struct wl_list touch_list; /* struct touch::link */
+};
+
+/* server structure */
+struct server {
+ int listen_fd;
+ struct watch listen_watch;
+
+ bool running;
+ int epoll_fd;
+
+ struct wl_list client_list; /* struct client::link */
+};
+
+struct shm_buffer {
+ struct wl_buffer *buffer;
+ void *shm_data;
+ int busy;
+};
+
+struct display {
+ struct wl_display *display;
+ struct wl_registry *registry;
+ struct wl_compositor *compositor;
+ struct wl_shm *shm;
+ bool has_xrgb;
+ struct ivi_application *ivi_application;
+
+ struct wl_seat *seat;
+ struct wl_pointer *wl_pointer;
+ struct wl_keyboard *wl_keyboard;
+ struct wl_touch *wl_touch;
+ struct window *window;
+ struct {
+ EGLDisplay dpy;
+ EGLContext ctx;
+ EGLConfig conf;
+
+ PFNEGLCREATEIMAGEKHRPROC create_image;
+ PFNEGLDESTROYIMAGEKHRPROC destroy_image;
+ PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_texture_2d;
+ } egl;
+ struct {
+ GLuint vertex_shader;
+ GLuint fragment_shader;
+ GLuint program_object;
+ GLuint texture;
+ } gl;
+};
+
+struct window {
+ struct display *display;
+ struct {
+ GLuint rotation_uniform;
+ GLuint pos;
+ GLuint col;
+ } gl;
+ int width, height;
+ struct wl_surface *surface;
+ struct ivi_surface *ivi_surface;
+ struct shm_buffer buffers[2];
+ struct shm_buffer *prev_buffer;
+ struct wl_callback *callback;
+ uint32_t window_frames;
+ uint32_t window_benchmark_time;
+ int wait;
+ struct surface *server_surf;
+ struct wl_egl_window *native;
+ EGLSurface egl_surface;
+ EGLImageKHR egl_img;
+ struct seat *server_seat;
+ struct pointer *server_pointer;
+ bool ready;
+ uint32_t id_ivisurf;
+};
+
+
+#endif
diff --git a/demo3/horizontal/waltham-server/include/wth-server-weston.h b/demo3/horizontal/waltham-server/include/wth-server-weston.h
new file mode 100644
index 0000000..50e1b2c
--- /dev/null
+++ b/demo3/horizontal/waltham-server/include/wth-server-weston.h
@@ -0,0 +1,99 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+** **
+** SRC-MODULE: **
+** **
+** TARGET : linux **
+** **
+** PROJECT : waltham-server **
+** **
+** AUTHOR : **
+** **
+** **
+** **
+** PURPOSE : Header file declare macros, extern functions, data types etc **
+** required to interface with weston compositor at server side **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+#ifndef WALTHAM_SHM_H_
+#define WALTHAM_SHM_H_
+
+#include "wth-server-waltham-comm.h"
+/**
+* wth_server_weston_shm_attach
+*
+* attach waltham surface data to weston surface
+*
+* @param names struct window *window
+* uint32_t data_sz
+* void * data
+* int32_t width
+* int32_t height
+* int32_t stride
+* uint32_t format
+* @param value struct window *window - window info pointer
+* uint32_t data_sz - buffer data size
+* void * data - buffer pointer
+* int32_t width - width
+* int32_t height -height
+* int32_t stride -stride information
+* uint32_t format - buffer data format
+* @return none
+*/
+void wth_server_weston_shm_attach(struct window *window, uint32_t data_sz, void * data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format);
+
+/**
+* wth_server_weston_shm_damage
+*
+* Send weston surface damage
+*
+* @param names struct window *window
+*
+* @param value struct window *window - window info pointer
+*
+* @return none
+*/
+void wth_server_weston_shm_damage(struct window *window);
+
+/**
+* wth_server_weston_shm_commit
+*
+* Commit weston surface data
+*
+* @param names struct window *window
+*
+* @param value struct window *window - window info pointer
+*
+* @return none
+*/
+void wth_server_weston_shm_commit(struct window *window);
+
+/**
+* wth_server_weston_main
+*
+* This is the main function which will handle connection to the compositor at server side
+*
+* @param names void *data
+* @param value struct window data
+* @return 0 on success, -1 on error
+*/
+int wth_server_weston_main(void *data);
+
+
+#endif
diff --git a/demo3/horizontal/waltham-server/orig/CMakeLists.txt b/demo3/horizontal/waltham-server/orig/CMakeLists.txt
new file mode 100644
index 0000000..5ea80bc
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/CMakeLists.txt
@@ -0,0 +1,93 @@
+cmake_minimum_required( VERSION 2.8.5 )
+
+project (waltham-server)
+
+find_package(PkgConfig)
+find_package (Threads)
+pkg_check_modules(WAYLAND_CLIENT wayland-client REQUIRED)
+pkg_check_modules(WAYLAND_CURSOR wayland-cursor REQUIRED)
+pkg_check_modules(WALTHAM waltham REQUIRED)
+pkg_check_modules(GLESv2 glesv2 REQUIRED)
+pkg_check_modules(WAYLAND_EGL wayland-egl REQUIRED)
+pkg_search_module(EGL egl required)
+pkg_search_module(GSTREAMER gstreamer-1.0 required)
+pkg_search_module(GSTREAMERAPP gstreamer-app-1.0 required)
+pkg_search_module(DRM libdrm required)
+
+find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
+find_library(GST_ALLOCATOR NAMES gstallocators-1.0 PATHs /usr/lib64)
+find_library(GST_VIDEO NAMES gstvideo-1.0 PATHs /usr/lib64)
+add_custom_command(
+ OUTPUT ivi-application-client-protocol.h
+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} client-header
+ < ${CMAKE_SOURCE_DIR}/waltham-server/protocol/ivi-application.xml
+ > ${CMAKE_CURRENT_BINARY_DIR}/ivi-application-client-protocol.h
+ DEPENDS ${CMAKE_SOURCE_DIR}/waltham-server/protocol/ivi-application.xml
+)
+
+add_custom_command(
+ OUTPUT ivi-application-protocol.c
+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} code
+ < ${CMAKE_SOURCE_DIR}/waltham-server/protocol/ivi-application.xml
+ > ${CMAKE_CURRENT_BINARY_DIR}/ivi-application-protocol.c
+ DEPENDS ${CMAKE_SOURCE_DIR}/waltham-server/protocol/ivi-application.xml
+)
+
+include_directories(
+ ${WAYLAND_CLIENT_INCLUDE_DIR}
+ ${WAYLAND_CURSOR_INCLUDE_DIR}
+ ${WALTHAM_INCLUDE_DIRS}
+ ${DRM_INCLUDE_DIRS}
+ ${GSTREAMER_LIBRARY_DIRS}
+ ${GSTREAMER_INCLUDE_DIRS}
+ ${GSTREAMERAPP_INCLUDE_DIRS}
+ ${EGL_INCLUDE_DIRS}
+ ${WAYLAND_EGL_INCLUDE_DIR}
+ ${GLESv2_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/waltham-server/include/
+ ${CMAKE_SOURCE_DIR}/waltham-renderer
+)
+
+link_directories(
+ ${WAYLAND_CLIENT_LIBRARY_DIRS}
+ ${WAYLAND_CURSOR_LIBRARY_DIRS}
+ ${WALTHAM_LIBRARY_DIRS}
+ ${EGL_LIBRARY_DIRS}
+ ${WAYLAND_EGL_LIBRAY_DIRS}
+ ${GLESv2_LIBRARY_DIRS}
+ ${GSTREAMER_LIBRARY_DIRS}
+ ${GSTREAMERAPP_LIBRARY_DIRS}
+)
+
+SET(LIBS
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${WAYLAND_CLIENT_LIBRARIES}
+ ${WAYLAND_CURSOR_LIBRARIES}
+ ${WALTHAM_LIBRARIES}
+ ${EGL_LIBRARIES}
+ ${WAYLAND_EGL_LIBRARIES}
+ ${GLESv2_LIBRARIES}
+ ${GSTREAMER_LIBRARIES}
+ ${GSTREAMERAPP_LIBRARIES}
+ ${GST_ALLOCATOR}
+ ${GST_VIDEO}
+)
+
+SET(SRC_FILES
+ src/wth-server-main.c
+ src/wth-server-waltham-comm.c
+ src/wth-server-gst.c
+ src/utils/bitmap.c
+ src/utils/os-compatibility.c
+ ivi-application-protocol.c
+ ivi-application-client-protocol.h
+)
+
+add_executable(${PROJECT_NAME} ${SRC_FILES})
+
+add_definitions(${EGL_CFLAGS})
+
+target_link_libraries(${PROJECT_NAME} ${LIBS})
+
+install (TARGETS ${PROJECT_NAME} DESTINATION bin)
diff --git a/demo3/horizontal/waltham-server/orig/README b/demo3/horizontal/waltham-server/orig/README
new file mode 100644
index 0000000..f20c1e6
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/README
@@ -0,0 +1,76 @@
+Component Name:
+============
+waltham-server
+
+Description
+============
+waltham-server component is a server side implementation for using
+Waltham IPC library to obtain and process remote output received from
+waltham-transmitter
+
+This component is designed to be used for evaluating the functionalities of
+waltham-transmitter plugin.
+
+This component also acts as weston client application to display/handle various
+requests from actual weston client at transmitter side.
+
+Build Steps
+===========
+Currently built for HOST environment
+
+1. Prerequisite before building
+weston, wayland and waltham should be built and available in HOST machine
+Refer below link to build on Ubuntu HOST machie
+https://wayland.freedesktop.org/ubuntu16.04.html
+
+2. In waltham-server directory, create build directory
+# cd waltham-server
+# mkdir build
+
+3. Run cmake
+# cmake ..
+
+4. waltham-server binary should be availaible in build directory
+
+Features supported
+==================
+1. Connection establishment with waltham-transmitter
+2. Create surface sent by waltham-transmitter
+3. Handle pointer events from weston at server side
+4. Transmit pointer events from weston at server side to transmitter
+
+Basic test steps
+=================
+1. Start weston at server side
+# weston
+
+2. Run waltham-server
+#waltham-server -p <port_number> -v
+
+3. Start weston with transmitter plugin at transmitter side
+#weston
+
+###############Connection established -Server side logs ################
+set_sigint_handler >>>
+ <<< set_sigint_handler
+server_listen >>>
+ <<< server_listen
+watch_ctl >>>
+ <<< watch_ctl
+Waltham server listening on TCP port 34400...
+server_mainloop >>>
+server_flush_clients >>>
+ <<< server_flush_clients
+listen_socket_handle_data >>>
+EPOLLIN evnet received.
+server_accept_client >>>
+client_create >>>
+watch_ctl >>>
+Client 0xb6c20930 connected.
+
+
+Limitation/Workarounds if any
+==============================
+1. Currently server does not display framed data received from the transmitter,
+instead frame data created in local buffer is used.
+2. Pointer events are also tested with local buffer data.
diff --git a/demo3/horizontal/waltham-server/orig/include/bitmap.h b/demo3/horizontal/waltham-server/orig/include/bitmap.h
new file mode 100644
index 0000000..3cef52d
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/include/bitmap.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+#ifndef IVICONTROLLER_BITMAP_H_
+#define IVICONTROLLER_BITMAP_H_
+
+#include <stdint.h>
+
+int save_as_bitmap(const char *filename,
+ const char *buffer,
+ int32_t image_size,
+ int32_t width,
+ int32_t height,
+ int16_t bpp
+ );
+
+#endif /* IVICONTROLLER_BITMAP_H_*/
diff --git a/demo3/horizontal/waltham-server/orig/include/os-compatibility.h b/demo3/horizontal/waltham-server/orig/include/os-compatibility.h
new file mode 100644
index 0000000..690f229
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/include/os-compatibility.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2012 Collabora, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef OS_COMPATIBILITY_H
+#define OS_COMPATIBILITY_H
+
+#include <sys/types.h>
+
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#else
+static inline int
+backtrace(void **buffer, int size)
+{
+ return 0;
+}
+#endif
+
+int
+os_fd_set_cloexec(int fd);
+
+int
+os_socketpair_cloexec(int domain, int type, int protocol, int *sv);
+
+int
+os_epoll_create_cloexec(void);
+
+int
+os_create_anonymous_file(off_t size);
+
+#ifndef HAVE_STRCHRNUL
+char *
+strchrnul(const char *s, int c);
+#endif
+
+#endif /* OS_COMPATIBILITY_H */
diff --git a/demo3/horizontal/waltham-server/orig/include/wth-server-waltham-comm.h b/demo3/horizontal/waltham-server/orig/include/wth-server-waltham-comm.h
new file mode 100644
index 0000000..05f3810
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/include/wth-server-waltham-comm.h
@@ -0,0 +1,524 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+** **
+** SRC-MODULE: **
+** **
+** TARGET : linux **
+** **
+** PROJECT : waltham-server **
+** **
+** AUTHOR : **
+** **
+** **
+** **
+** PURPOSE : Header file declare macros, extern functions, data types etc, **
+** required to interface with waltham IPC library **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+#ifndef WTH_SERVER_WALTHAM_COMM_H_
+#define WTH_SERVER_WALTHAM_COMM_H_
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <sys/epoll.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <assert.h>
+#include <getopt.h>
+#include <unistd.h>
+
+#include <GLES/gl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <wayland-egl.h>
+#include <wayland-client.h>
+#include <waltham-server.h>
+#include <waltham-connection.h>
+
+struct server;
+struct client;
+struct window;
+struct pointer;
+struct touch;
+
+pthread_mutex_t g_mutex;
+pthread_cond_t g_cond;
+int go_to_wait;
+
+const struct wth_display_interface display_implementation;
+
+/**
+* server_accept_client
+*
+* Accepts new waltham client connection and instantiates client structure
+*
+* @param names struct server *srv
+* @param value socket connection info and client data
+* @return none
+*/
+void server_accept_client(struct server *srv);
+
+/**
+* server_flush_clients
+*
+* write all the pending requests from the clients to socket
+*
+* @param names struct server *srv
+* @param value socket connection info and client data
+* @return none
+*/
+void server_flush_clients(struct server *srv);
+
+/**
+* client_destroy
+*
+* Destroy client connection
+*
+* @param names struct client *c
+* @param value client data
+* @return none
+*/
+void client_destroy(struct client *c);
+
+/**
+* waltham_pointer_enter
+*
+* Send pointer enter event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t serial
+* wl_fixed_t sx
+* wl_fixed_t sy
+* @param value window - window information
+* serial - serial number of the enter event
+* sx - surface-local x coordinate
+* sy - surface-local y coordinate
+* @return none
+*/
+void waltham_pointer_enter(struct window *window, uint32_t serial,
+ wl_fixed_t sx, wl_fixed_t sy);
+
+/**
+* waltham_pointer_leave
+*
+* Send pointer leave event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t serial
+* @param value window - window information
+* serial - serial number of the leave event
+* @return none
+*/
+void waltham_pointer_leave(struct window *window, uint32_t serial);
+
+/**
+* waltham_pointer_motion
+*
+* Send pointer motion event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t time
+* wl_fixed_t sx
+* wl_fixed_t sy
+* @param value window - window information
+* time - timestamp with millisecond granularity
+* sx - surface-local x coordinate
+* sy - surface-local y coordinate
+* @return none
+*/
+void waltham_pointer_motion(struct window *window, uint32_t time,
+ wl_fixed_t sx, wl_fixed_t sy);
+
+/**
+* waltham_pointer_button
+*
+* Send pointer button event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t serial
+* uint32_t time
+* uint32_t button
+* uint32_t state
+* @param value window - window information
+* serial - serial number of the button event
+* time - timestamp with millisecond granularity
+* button - button that produced the event
+* state - physical state of the button
+* @return none
+*/
+void waltham_pointer_button(struct window *window, uint32_t serial,
+ uint32_t time, uint32_t button,
+ uint32_t state);
+
+/**
+* waltham_pointer_axis
+*
+* Send pointer axis event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t time
+* uint32_t axis
+* wl_fixed_t value
+* @param value window - window information
+* time - timestamp with millisecond granularity
+* axis - axis type
+* value - length of vector in surface-local coordinate space
+* @return none
+*/
+void waltham_pointer_axis(struct window *window, uint32_t time,
+ uint32_t axis, wl_fixed_t value);
+
+/**
+* waltham_touch_down
+*
+* Send touch down event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t serial
+* uint32_t time
+* int32_t id
+* wl_fixed_t x_w
+* wl_fixed_t y_w
+* @param value window - window information
+* serial - serial number of the touch down event
+* time - timestamp with millisecond granularity
+* id - the unique ID of this touch point
+* x_w - surface-local x coordinate
+* y_w - surface-local y coordinate
+* @return none
+*/
+void waltham_touch_down(struct window *window, uint32_t serial,
+ uint32_t time, int32_t id,
+ wl_fixed_t x_w, wl_fixed_t y_w);
+
+/**
+* waltham_touch_up
+*
+* Send touch up event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t serial
+* uint32_t time
+* int32_t id
+* @param value window - window information
+* serial - serial number of the touch up event
+* time - timestamp with millisecond granularity
+* id - the unique ID of this touch point
+* @return none
+*/
+void waltham_touch_up(struct window *window, uint32_t serial,
+ uint32_t time, int32_t id);
+
+/**
+* waltham_touch_motion
+*
+* Send touch motion event received from weston to waltham client
+*
+* @param names struct window *window
+* uint32_t time
+* int32_t id
+* wl_fixed_t x_w
+* wl_fixed_t y_w
+* @param value window - window information
+* time - timestamp with millisecond granularity
+* id - the unique ID of this touch point
+* x_w - surface-local x coordinate
+* y_w - surface-local y coordinate
+* @return none
+*/
+void waltham_touch_motion(struct window *window, uint32_t time,
+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w);
+
+/**
+* waltham_touch_frame
+*
+* Send touch frame event received from weston to waltham client
+*
+* @param names struct window *window
+* @param value window - window information
+* @return none
+*/
+void waltham_touch_frame(struct window *window);
+
+/**
+* waltham_touch_cancel
+*
+* Send touch cancel event received from weston to waltham client
+*
+* @param names struct window *window
+* @param value window - window information
+* @return none
+*/
+void waltham_touch_cancel(struct window *window);
+
+
+/***** macros *******/
+#define MAX_EPOLL_WATCHES 2
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({ \
+ const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#define wl_list_last_until_empty(pos, head, member) \
+ while (!wl_list_empty(head) && \
+ (pos = wl_container_of((head)->prev, pos, member), 1))
+
+#ifndef ARRAY_LENGTH
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+#endif
+
+#ifndef pr_fmt
+# define pr_fmt(fmt) fmt
+#endif
+
+#ifndef USE_STDOUT
+# define PRINT_OUT stderr
+#else
+# define PRINT_OUT stdout
+#endif
+
+#define wth_error(fmt, ...) \
+ ({ fprintf(PRINT_OUT, pr_fmt(fmt), ## __VA_ARGS__); fflush(PRINT_OUT); })
+#define wth_verbose(fmt, ...) \
+ ({ if (get_verbosity()) { fprintf(PRINT_OUT, pr_fmt(fmt), ## __VA_ARGS__); fflush(PRINT_OUT); } })
+
+/****** incline functions *****/
+static inline void *
+zalloc(size_t size)
+{
+ return calloc(1, size);
+}
+
+
+/***** Data types *****/
+/* wthp_region protocol object */
+struct region {
+ struct wthp_region *obj;
+ /* pixman_region32_t region; */
+ struct wl_list link; /* struct client::region_list */
+};
+
+/* wthp_compositor protocol object */
+struct compositor {
+ struct wthp_compositor *obj;
+ struct client *client;
+ struct wl_list link; /* struct client::compositor_list */
+};
+
+/* wthp_blob_factory protocol object */
+struct blob_factory {
+ struct wthp_blob_factory *obj;
+ struct client *client;
+ struct wl_list link; /* struct client::blob_factory_list */
+};
+
+/* wthp_buffer protocol object */
+struct buffer {
+ struct wthp_buffer *obj;
+ uint32_t data_sz;
+ void *data;
+ int32_t width;
+ int32_t height;
+ int32_t stride;
+ uint32_t format;
+ struct wl_list link; /* struct client::buffer_list */
+};
+
+/* wthp_seat protocol object */
+struct seat {
+ struct wthp_seat *obj;
+ struct client *client;
+ struct pointer *pointer;
+ struct keyboard *keyboard;
+ struct touch *touch;
+ struct wl_list link; /* struct client::seat_list */
+};
+
+/* wthp_pointer protocol object */
+struct pointer {
+ struct wthp_pointer *obj;
+ struct seat *seat;
+ struct wl_list link; /* struct client::pointer_list */
+};
+
+/* wthp_keyboard protocol object */
+struct keyboard {
+ struct wthp_keyboard *obj;
+ struct seat *seat;
+ struct wl_list link; /* struct client::keyboard_list */
+};
+
+/* wthp_touch protocol object */
+struct touch {
+ struct wthp_touch *obj;
+ struct seat *seat;
+ struct wl_list link; /* struct client::touch_list */
+};
+
+/* wthp_surface protocol object */
+struct surface {
+ struct wthp_surface *obj;
+ uint32_t ivi_id;
+ struct ivisurface3 *ivisurf;
+ struct wthp_callback *cb;
+ struct window *shm_window;
+ struct wl_list link; /* struct client::surface_list */
+};
+/* wthp_ivi_surface protocol object */
+struct ivisurface {
+ struct wthp_ivi_surface *obj;
+ struct wthp_callback *cb;
+ struct wl_list link; /* struct client::surface_list */
+ struct surface *surf;
+};
+
+/* wthp_ivi_application protocol object */
+struct application {
+ struct wthp_ivi_application *obj;
+ struct client *client;
+ struct wl_list link; /* struct client::surface_list */
+};
+
+/* wthp_registry protocol object */
+struct registry {
+ struct wthp_registry *obj;
+ struct client *client;
+ struct wl_list link; /* struct client::registry_list */
+};
+
+enum wthp_seat_capability {
+ /**
+ * the seat has pointer devices
+ */
+ WTHP_SEAT_CAPABILITY_POINTER = 1,
+ /**
+ * the seat has one or more keyboards
+ */
+ WTHP_SEAT_CAPABILITY_KEYBOARD = 2,
+ /**
+ * the seat has touch devices
+ */
+ WTHP_SEAT_CAPABILITY_TOUCH = 4,
+};
+
+/* epoll structure */
+struct watch {
+ struct server *server;
+ int fd;
+ void (*cb)(struct watch *w, uint32_t events);
+};
+
+struct client {
+ struct wl_list link; /* struct server::client_list */
+ struct server *server;
+
+ struct wth_connection *connection;
+ struct watch conn_watch;
+
+ /* client object lists for clean-up on disconnection */
+ struct wl_list registry_list; /* struct registry::link */
+ struct wl_list compositor_list; /* struct compositor::link */
+ struct wl_list region_list; /* struct region::link */
+ struct wl_list surface_list; /* struct surface::link */
+ struct wl_list buffer_list; /* struct buffer::link */
+ struct wl_list seat_list; /* struct seat::link */
+ struct wl_list pointer_list; /* struct pointer::link */
+ struct wl_list touch_list; /* struct touch::link */
+};
+
+/* server structure */
+struct server {
+ int listen_fd;
+ struct watch listen_watch;
+
+ bool running;
+ int epoll_fd;
+
+ struct wl_list client_list; /* struct client::link */
+};
+
+struct shm_buffer {
+ struct wl_buffer *buffer;
+ void *shm_data;
+ int busy;
+};
+
+struct display {
+ struct wl_display *display;
+ struct wl_registry *registry;
+ struct wl_compositor *compositor;
+ struct wl_shm *shm;
+ bool has_xrgb;
+ struct ivi_application *ivi_application;
+
+ struct wl_seat *seat;
+ struct wl_pointer *wl_pointer;
+ struct wl_keyboard *wl_keyboard;
+ struct wl_touch *wl_touch;
+ struct window *window;
+ struct {
+ EGLDisplay dpy;
+ EGLContext ctx;
+ EGLConfig conf;
+
+ PFNEGLCREATEIMAGEKHRPROC create_image;
+ PFNEGLDESTROYIMAGEKHRPROC destroy_image;
+ PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_texture_2d;
+ } egl;
+ struct {
+ GLuint vertex_shader;
+ GLuint fragment_shader;
+ GLuint program_object;
+ GLuint texture;
+ } gl;
+};
+
+struct window {
+ struct display *display;
+ struct {
+ GLuint rotation_uniform;
+ GLuint pos;
+ GLuint col;
+ } gl;
+ int width, height;
+ struct wl_surface *surface;
+ struct ivi_surface *ivi_surface;
+ struct shm_buffer buffers[2];
+ struct shm_buffer *prev_buffer;
+ struct wl_callback *callback;
+ uint32_t window_frames;
+ uint32_t window_benchmark_time;
+ int wait;
+ struct surface *server_surf;
+ struct wl_egl_window *native;
+ EGLSurface egl_surface;
+ EGLImageKHR egl_img;
+ struct seat *server_seat;
+ struct pointer *server_pointer;
+ bool ready;
+ uint32_t id_ivisurf;
+};
+
+
+#endif
diff --git a/demo3/horizontal/waltham-server/orig/include/wth-server-weston.h b/demo3/horizontal/waltham-server/orig/include/wth-server-weston.h
new file mode 100644
index 0000000..50e1b2c
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/include/wth-server-weston.h
@@ -0,0 +1,99 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+** **
+** SRC-MODULE: **
+** **
+** TARGET : linux **
+** **
+** PROJECT : waltham-server **
+** **
+** AUTHOR : **
+** **
+** **
+** **
+** PURPOSE : Header file declare macros, extern functions, data types etc **
+** required to interface with weston compositor at server side **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+#ifndef WALTHAM_SHM_H_
+#define WALTHAM_SHM_H_
+
+#include "wth-server-waltham-comm.h"
+/**
+* wth_server_weston_shm_attach
+*
+* attach waltham surface data to weston surface
+*
+* @param names struct window *window
+* uint32_t data_sz
+* void * data
+* int32_t width
+* int32_t height
+* int32_t stride
+* uint32_t format
+* @param value struct window *window - window info pointer
+* uint32_t data_sz - buffer data size
+* void * data - buffer pointer
+* int32_t width - width
+* int32_t height -height
+* int32_t stride -stride information
+* uint32_t format - buffer data format
+* @return none
+*/
+void wth_server_weston_shm_attach(struct window *window, uint32_t data_sz, void * data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format);
+
+/**
+* wth_server_weston_shm_damage
+*
+* Send weston surface damage
+*
+* @param names struct window *window
+*
+* @param value struct window *window - window info pointer
+*
+* @return none
+*/
+void wth_server_weston_shm_damage(struct window *window);
+
+/**
+* wth_server_weston_shm_commit
+*
+* Commit weston surface data
+*
+* @param names struct window *window
+*
+* @param value struct window *window - window info pointer
+*
+* @return none
+*/
+void wth_server_weston_shm_commit(struct window *window);
+
+/**
+* wth_server_weston_main
+*
+* This is the main function which will handle connection to the compositor at server side
+*
+* @param names void *data
+* @param value struct window data
+* @return 0 on success, -1 on error
+*/
+int wth_server_weston_main(void *data);
+
+
+#endif
diff --git a/demo3/horizontal/waltham-server/orig/protocol/ivi-application.xml b/demo3/horizontal/waltham-server/orig/protocol/ivi-application.xml
new file mode 100644
index 0000000..78e2569
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/protocol/ivi-application.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="ivi_application">
+
+ <copyright>
+ Copyright (C) 2013 DENSO CORPORATION
+ Copyright (c) 2013 BMW Car IT GmbH
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice (including the next
+ paragraph) shall be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ </copyright>
+
+ <interface name="ivi_surface" version="1">
+ <description summary="application interface to surface in ivi compositor"/>
+
+ <request name="destroy" type="destructor">
+ <description summary="destroy ivi_surface">
+ This removes link from ivi_id to wl_surface and destroys ivi_surface.
+ The ID, ivi_id, is free and can be used for surface_create again.
+ </description>
+ </request>
+
+ <event name="configure">
+ <description summary="suggest resize">
+ The configure event asks the client to resize its surface.
+
+ The size is a hint, in the sense that the client is free to
+ ignore it if it doesn't resize, pick a smaller size (to
+ satisfy aspect ratio or resize in steps of NxM pixels).
+
+ The client is free to dismiss all but the last configure
+ event it received.
+
+ The width and height arguments specify the size of the window
+ in surface-local coordinates.
+ </description>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ </event>
+ </interface>
+
+ <interface name="ivi_application" version="1">
+ <description summary="create ivi-style surfaces">
+ This interface is exposed as a global singleton.
+ This interface is implemented by servers that provide IVI-style user interfaces.
+ It allows clients to associate a ivi_surface with wl_surface.
+ </description>
+
+ <enum name="error">
+ <entry name="role" value="0" summary="given wl_surface has another role"/>
+ <entry name="ivi_id" value="1" summary="given ivi_id is assigned to another wl_surface"/>
+ </enum>
+
+ <request name="surface_create">
+ <description summary="create ivi_surface with numeric ID in ivi compositor">
+ This request gives the wl_surface the role of an IVI Surface. Creating more than
+ one ivi_surface for a wl_surface is not allowed. Note, that this still allows the
+ following example:
+
+ 1. create a wl_surface
+ 2. create ivi_surface for the wl_surface
+ 3. destroy the ivi_surface
+ 4. create ivi_surface for the wl_surface (with the same or another ivi_id as before)
+
+ surface_create will create a interface:ivi_surface with numeric ID; ivi_id in
+ ivi compositor. These ivi_ids are defined as unique in the system to identify
+ it inside of ivi compositor. The ivi compositor implements business logic how to
+ set properties of the surface with ivi_id according to status of the system.
+ E.g. a unique ID for Car Navigation application is used for implementing special
+ logic of the application about where it shall be located.
+ The server regards following cases as protocol errors and disconnects the client.
+ - wl_surface already has an nother role.
+ - ivi_id is already assigned to an another wl_surface.
+
+ If client destroys ivi_surface or wl_surface which is assigne to the ivi_surface,
+ ivi_id which is assigned to the ivi_surface is free for reuse.
+ </description>
+ <arg name="ivi_id" type="uint"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="id" type="new_id" interface="ivi_surface"/>
+ </request>
+
+ </interface>
+
+</protocol>
diff --git a/demo3/horizontal/waltham-server/orig/src/utils/bitmap.c b/demo3/horizontal/waltham-server/orig/src/utils/bitmap.c
new file mode 100644
index 0000000..2c7fdb5
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/src/utils/bitmap.c
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+#include "bitmap.h"
+#include <stdio.h>
+
+struct __attribute__ ((__packed__)) BITMAPFILEHEADER {
+ char bfType[2];
+ uint32_t bfSize;
+ uint16_t bfReserved1;
+ uint16_t bfReserved2;
+ uint32_t bfOffBits;
+};
+
+struct __attribute__ ((__packed__)) BITMAPINFOHEADER {
+ uint32_t biSize;
+ uint32_t biWidth;
+ uint32_t biHeight;
+ uint16_t biPlanes;
+ uint16_t biBitCount;
+ uint32_t biCompression;
+ uint32_t biSizeImage;
+ uint32_t biXPixPerMeter;
+ uint32_t biYPixPerMeter;
+ uint32_t biClrUsed;
+ uint32_t biClrImporant;
+};
+
+static void
+create_file_header(struct BITMAPFILEHEADER *file_header, int32_t image_size)
+{
+ file_header->bfType[0] = 'B';
+ file_header->bfType[1] = 'M';
+ file_header->bfSize = sizeof(struct BITMAPFILEHEADER)
+ + sizeof(struct BITMAPINFOHEADER)
+ + image_size;
+ file_header->bfOffBits = sizeof(struct BITMAPFILEHEADER)
+ + sizeof(struct BITMAPINFOHEADER);
+}
+
+static void
+create_info_header(struct BITMAPINFOHEADER *info_header, int32_t image_size, int32_t width, int32_t height, int16_t bpp)
+{
+ info_header->biSize = sizeof(struct BITMAPINFOHEADER);
+ info_header->biWidth = width;
+ info_header->biHeight = height;
+ info_header->biPlanes = 1;
+ info_header->biBitCount = bpp;
+ info_header->biSizeImage = image_size;
+}
+
+static int
+write_bitmap(const char *filename,
+ const struct BITMAPFILEHEADER *file_header,
+ const struct BITMAPINFOHEADER *info_header,
+ const char *buffer)
+{
+ FILE *fp = fopen(filename, "w");
+ if (fp == NULL) {
+ return -1;
+ }
+
+ fwrite(file_header, sizeof(struct BITMAPFILEHEADER), 1, fp);
+ fwrite(info_header, sizeof(struct BITMAPINFOHEADER), 1, fp);
+ fwrite(buffer, info_header->biSizeImage, 1, fp);
+
+ fclose(fp);
+ return 0;
+}
+
+int
+save_as_bitmap(const char *filename,
+ const char *buffer,
+ int32_t image_size,
+ int32_t width,
+ int32_t height,
+ int16_t bpp)
+{
+ if ((filename == NULL) || (buffer == NULL)) {
+ return -1;
+ }
+
+ struct BITMAPFILEHEADER file_header = {};
+ struct BITMAPINFOHEADER info_header = {};
+
+ create_file_header(&file_header, image_size);
+ create_info_header(&info_header, image_size, width, height, bpp);
+ return write_bitmap(filename, &file_header, &info_header, buffer);
+}
diff --git a/demo3/horizontal/waltham-server/orig/src/utils/os-compatibility.c b/demo3/horizontal/waltham-server/orig/src/utils/os-compatibility.c
new file mode 100644
index 0000000..d9502e5
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/src/utils/os-compatibility.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright © 2012 Collabora, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/epoll.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "os-compatibility.h"
+
+int
+os_fd_set_cloexec(int fd)
+{
+ long flags;
+
+ if (fd == -1)
+ return -1;
+
+ flags = fcntl(fd, F_GETFD);
+ if (flags == -1)
+ return -1;
+
+ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
+ return -1;
+
+ return 0;
+}
+
+static int
+set_cloexec_or_close(int fd)
+{
+ if (os_fd_set_cloexec(fd) != 0) {
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+int
+os_socketpair_cloexec(int domain, int type, int protocol, int *sv)
+{
+ int ret;
+
+#ifdef SOCK_CLOEXEC
+ ret = socketpair(domain, type | SOCK_CLOEXEC, protocol, sv);
+ if (ret == 0 || errno != EINVAL)
+ return ret;
+#endif
+
+ ret = socketpair(domain, type, protocol, sv);
+ if (ret < 0)
+ return ret;
+
+ sv[0] = set_cloexec_or_close(sv[0]);
+ sv[1] = set_cloexec_or_close(sv[1]);
+
+ if (sv[0] != -1 && sv[1] != -1)
+ return 0;
+
+ close(sv[0]);
+ close(sv[1]);
+ return -1;
+}
+
+int
+os_epoll_create_cloexec(void)
+{
+ int fd;
+
+#ifdef EPOLL_CLOEXEC
+ fd = epoll_create1(EPOLL_CLOEXEC);
+ if (fd >= 0)
+ return fd;
+ if (errno != EINVAL)
+ return -1;
+#endif
+
+ fd = epoll_create(1);
+ return set_cloexec_or_close(fd);
+}
+
+static int
+create_tmpfile_cloexec(char *tmpname)
+{
+ int fd;
+
+#ifdef HAVE_MKOSTEMP
+ fd = mkostemp(tmpname, O_CLOEXEC);
+ if (fd >= 0)
+ unlink(tmpname);
+#else
+ fd = mkstemp(tmpname);
+ if (fd >= 0) {
+ fd = set_cloexec_or_close(fd);
+ unlink(tmpname);
+ }
+#endif
+
+ return fd;
+}
+
+/*
+ * Create a new, unique, anonymous file of the given size, and
+ * return the file descriptor for it. The file descriptor is set
+ * CLOEXEC. The file is immediately suitable for mmap()'ing
+ * the given size at offset zero.
+ *
+ * The file should not have a permanent backing store like a disk,
+ * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
+ *
+ * The file name is deleted from the file system.
+ *
+ * The file is suitable for buffer sharing between processes by
+ * transmitting the file descriptor over Unix sockets using the
+ * SCM_RIGHTS methods.
+ *
+ * If the C library implements posix_fallocate(), it is used to
+ * guarantee that disk space is available for the file at the
+ * given size. If disk space is insufficent, errno is set to ENOSPC.
+ * If posix_fallocate() is not supported, program may receive
+ * SIGBUS on accessing mmap()'ed file contents instead.
+ */
+int
+os_create_anonymous_file(off_t size)
+{
+ static const char template[] = "/weston-shared-XXXXXX";
+ const char *path;
+ char *name;
+ int fd;
+ int ret;
+
+ path = getenv("XDG_RUNTIME_DIR");
+ if (!path) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ name = malloc(strlen(path) + sizeof(template));
+ if (!name)
+ return -1;
+
+ strcpy(name, path);
+ strcat(name, template);
+
+ fd = create_tmpfile_cloexec(name);
+
+ free(name);
+
+ if (fd < 0)
+ return -1;
+
+#ifdef HAVE_POSIX_FALLOCATE
+ ret = posix_fallocate(fd, 0, size);
+ if (ret != 0) {
+ close(fd);
+ errno = ret;
+ return -1;
+ }
+#else
+ ret = ftruncate(fd, size);
+ if (ret < 0) {
+ close(fd);
+ return -1;
+ }
+#endif
+
+ return fd;
+}
+
+#ifndef HAVE_STRCHRNUL
+char *
+strchrnul(const char *s, int c)
+{
+ while (*s && *s != c)
+ s++;
+ return (char *)s;
+}
+#endif
diff --git a/demo3/horizontal/waltham-server/orig/src/wth-server-gst.c b/demo3/horizontal/waltham-server/orig/src/wth-server-gst.c
new file mode 100644
index 0000000..572a04d
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/src/wth-server-gst.c
@@ -0,0 +1,1151 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+ ** **
+ ** SRC-MODULE: **
+ ** **
+ ** TARGET : linux **
+ ** **
+ ** PROJECT : waltham-server **
+ ** **
+ ** AUTHOR : **
+ ** **
+ ** **
+ ** **
+ ** PURPOSE : This file is acts as interface to weston compositor at server **
+ ** side **
+ ** **
+ ** REMARKS : **
+ ** **
+ ** PLATFORM DEPENDANT [yes/no]: yes **
+ ** **
+ ** TO BE CHANGED BY USER [yes/no]: no **
+ ** **
+ *******************************************************************************/
+
+#include <sys/mman.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <gst/gst.h>
+#include <gst/gl/gl.h>
+#include <GL/gl.h>
+#include <gst/video/gstvideometa.h>
+#include <gst/allocators/gstdmabuf.h>
+#include <gst/app/gstappsink.h>
+#include <pthread.h>
+
+#include <xf86drm.h>
+#include <drm.h>
+#include <drm_fourcc.h>
+
+#include "wth-server-waltham-comm.h"
+#include "os-compatibility.h"
+#include "ivi-application-client-protocol.h"
+#include "bitmap.h"
+
+static int running = 1;
+extern bool get_verbosity(void);
+extern int verbose;
+
+typedef struct _GstAppContext
+{
+ GMainLoop *loop;
+ GstBus *bus;
+ GstElement *pipeline;
+ GstElement *sink;
+ GstSample *sample;
+ GstBuffer *gstbuffer;
+ GstVideoMeta *vmeta;
+
+ int dma_fd[2];
+
+ struct display *display;
+ struct window *window;
+
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int wait;
+
+ GstVideoInfo info;
+ uint32_t format;
+ bool no_dma_buf;
+}GstAppContext;
+
+static const gchar *vertex_shader_str =
+"attribute vec4 a_position; \n"
+"attribute vec2 a_texCoord; \n"
+"varying vec2 v_texCoord; \n"
+"void main() \n"
+"{ \n"
+" gl_Position = a_position; \n"
+" v_texCoord = a_texCoord; \n"
+"} \n";
+
+static const gchar *fragment_shader_str =
+"#ifdef GL_ES \n"
+"precision mediump float; \n"
+"#endif \n"
+"varying vec2 v_texCoord; \n"
+"uniform sampler2D tex; \n"
+"void main() \n"
+"{ \n"
+"vec2 uv; \n"
+"uv = v_texCoord.xy; \n"
+"vec4 c = texture2D(tex, uv); \n"
+"gl_FragColor = c; \n"
+"} \n";
+
+/*
+ * pointer callbcak functions
+ */
+ static void
+pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
+ uint32_t serial, struct wl_surface *wl_surface,
+ wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("data [%p]\n", data);
+
+ struct display *display = data;
+ struct window *window = display->window;
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+
+ waltham_pointer_enter(window, serial, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_leave(void *data, struct wl_pointer *pointer,
+ uint32_t serial, struct wl_surface *surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("data [%p]\n", data);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_leave(window, serial);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_motion(void *data, struct wl_pointer *pointer,
+ uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_motion(window, time, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
+ uint32_t serial, uint32_t time, uint32_t button,
+ uint32_t state)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_button(window, serial, time, button, state);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
+ uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_axis(window, time, axis, value);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+ pointer_handle_enter,
+ pointer_handle_leave,
+ pointer_handle_motion,
+ pointer_handle_button,
+ pointer_handle_axis,
+};
+
+/*
+ * touch callbcak functions
+ */
+
+static void
+touch_handle_down(void *data, struct wl_touch *touch, uint32_t serial,
+ uint32_t time, struct wl_surface *surface, int32_t id,
+ wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ int x = (int)wl_fixed_to_double(x_w);
+ int y = (int)wl_fixed_to_double(y_w);
+ wth_verbose("%p x %d y %d\n",window, x, y);
+
+ waltham_touch_down(window, serial, time, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_up(void *data, struct wl_touch *touch, uint32_t serial,
+ uint32_t time, int32_t id)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_up(window, serial, time, id);
+}
+
+static void
+touch_handle_motion(void *data, struct wl_touch *touch, uint32_t time,
+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_motion(window, time, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_frame(void *data, struct wl_touch *touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_frame(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_cancel(void *data, struct wl_touch *touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_cancel(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_touch_listener touch_listener = {
+ touch_handle_down,
+ touch_handle_up,
+ touch_handle_motion,
+ touch_handle_frame,
+ touch_handle_cancel
+};
+
+/*
+ * seat callback
+ */
+static void
+seat_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+
+ wth_verbose("caps = %d\n", caps);
+
+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !display->wl_pointer)
+ {
+ wth_verbose("WL_SEAT_CAPABILITY_POINTER\n");
+ display->wl_pointer = wl_seat_get_pointer(wl_seat);
+ wl_pointer_set_user_data(display->wl_pointer, display);
+ wl_pointer_add_listener(display->wl_pointer, &pointer_listener, display);
+ wl_display_roundtrip(display->display);
+ } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && display->wl_pointer) {
+ wth_verbose("!WL_SEAT_CAPABILITY_POINTER\n");
+ wl_pointer_destroy(display->wl_pointer);
+ display->wl_pointer = NULL;
+ }
+
+ if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !display->wl_touch)
+ {
+ wth_verbose("WL_SEAT_CAPABILITY_TOUCH\n");
+ display->wl_touch = wl_seat_get_touch(wl_seat);
+ wl_touch_set_user_data(display->wl_touch, display);
+ wl_touch_add_listener(display->wl_touch, &touch_listener, display);
+ wl_display_roundtrip(display->display);
+ } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && display->wl_touch) {
+ wth_verbose("!WL_SEAT_CAPABILITY_TOUCH\n");
+ wl_touch_destroy(display->wl_touch);
+ display->wl_touch = NULL;
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_seat_listener seat_listener = {
+ seat_capabilities,
+ NULL
+};
+
+static void
+add_seat(struct display *display, uint32_t id, uint32_t version)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ display->wl_pointer = NULL;
+ display->seat = wl_registry_bind(display->registry, id,
+ &wl_seat_interface, 1);
+ wl_seat_add_listener(display->seat, &seat_listener, display);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static int
+drm_fourcc_from_gst_format(GstVideoFormat format)
+{
+ switch (format) {
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ return DRM_FORMAT_RGB565;
+
+ case GST_VIDEO_FORMAT_RGB:
+ case GST_VIDEO_FORMAT_BGR:
+ return DRM_FORMAT_BGR888;
+
+ case GST_VIDEO_FORMAT_RGBA:
+ case GST_VIDEO_FORMAT_RGBx:
+ case GST_VIDEO_FORMAT_BGRA:
+ case GST_VIDEO_FORMAT_BGRx:
+ case GST_VIDEO_FORMAT_ARGB:
+ case GST_VIDEO_FORMAT_xRGB:
+ case GST_VIDEO_FORMAT_ABGR:
+ case GST_VIDEO_FORMAT_xBGR:
+ case GST_VIDEO_FORMAT_AYUV:
+ return DRM_FORMAT_ARGB8888;
+
+ case GST_VIDEO_FORMAT_GRAY8:
+ return DRM_FORMAT_R8;
+
+ case GST_VIDEO_FORMAT_YUY2:
+ case GST_VIDEO_FORMAT_UYVY:
+ case GST_VIDEO_FORMAT_GRAY16_LE:
+ case GST_VIDEO_FORMAT_GRAY16_BE:
+ return DRM_FORMAT_GR88;
+
+ case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_YV12:
+ case GST_VIDEO_FORMAT_Y41B:
+ case GST_VIDEO_FORMAT_Y42B:
+ case GST_VIDEO_FORMAT_Y444:
+ return DRM_FORMAT_R8;
+
+ case GST_VIDEO_FORMAT_NV12:
+ return DRM_FORMAT_NV12;
+
+ default:
+ return -1;
+ }
+}
+
+gboolean bus_message(GstBus *bus, GstMessage *message, gpointer p)
+{
+ GstAppContext *gstctx = p;
+
+ fprintf(stderr, "mesage: %s\n", GST_MESSAGE_TYPE_NAME(message));
+
+ switch( GST_MESSAGE_TYPE(message)) {
+ case GST_MESSAGE_ERROR:
+ {
+ GError *err;
+ gchar *debug;
+
+ gst_message_parse_error(message, &err, &debug);
+ g_print("ERROR: %s\n", err->message);
+
+ g_error_free(err);
+ g_free(debug);
+ g_main_loop_quit(gstctx->loop);
+ break;
+ }
+
+ case GST_MESSAGE_STATE_CHANGED:
+ {
+ GstState oldstate, newstate;
+
+ gst_message_parse_state_changed(message, &oldstate, &newstate, NULL);
+ fprintf(stderr, "#%s state changed\n", GST_MESSAGE_SRC_NAME(message));
+ switch (newstate){
+ case GST_STATE_NULL:
+ fprintf(stderr, "%s: state is NULL\n", GST_MESSAGE_SRC_NAME(message));
+ break;
+ case GST_STATE_READY:
+ fprintf(stderr, "%s: state is READY\n", GST_MESSAGE_SRC_NAME(message));
+ break;
+ case GST_STATE_PAUSED:
+ fprintf(stderr, "%s: state is PAUSED\n", GST_MESSAGE_SRC_NAME(message));
+ break;
+ case GST_STATE_PLAYING:
+ fprintf(stderr, "%s: state is PLAYING\n", GST_MESSAGE_SRC_NAME(message));
+ break;
+ }
+ break;
+ }
+ default:
+ fprintf(stderr, "Unhandled message\n");
+ break;
+ }
+ fprintf(stderr, "-----------------\n");
+}
+
+EGLImageKHR create_eglImage(GstAppContext* gstctx)
+{
+ struct display *display = gstctx->display;
+ GstVideoMeta *vmeta = gstctx->vmeta;
+
+ uint32_t n_planes = vmeta->n_planes;
+ EGLint attribs[30];
+ int fourcc;
+ int atti = 0;
+
+ fourcc = drm_fourcc_from_gst_format(vmeta->format);
+
+ n_planes = GST_VIDEO_INFO_N_PLANES(&(gstctx->info));
+
+ int width = GST_VIDEO_INFO_WIDTH(&(gstctx->info));
+ int height = GST_VIDEO_INFO_HEIGHT(&(gstctx->info));
+
+ attribs[atti++] = EGL_WIDTH;
+ attribs[atti++] = vmeta->width;
+ attribs[atti++] = EGL_HEIGHT;
+ attribs[atti++] = vmeta->height;
+ attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
+ attribs[atti++] = fourcc;
+
+ /*
+ * Offset value for both the planes i.e Y and UV is "0"
+ * The omxdec gives the output is 2 different memory blocks,
+ * One for Y -> dmafd[0] and other for UV -> dmafd[1]
+ */
+
+ if (n_planes > 0) {
+ attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
+ attribs[atti++] = gstctx->dma_fd[0];
+ attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
+ attribs[atti++] = 0;
+ attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
+ attribs[atti++] = vmeta->stride[0];
+ }
+
+ if (n_planes > 1) {
+ attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT;
+ attribs[atti++] = gstctx->dma_fd[1];
+ attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
+ attribs[atti++] = 0;
+ attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
+ attribs[atti++] = vmeta->stride[1];
+ }
+
+ attribs[atti++] = EGL_NONE;
+
+ return display->egl.create_image(display->egl.dpy, EGL_NO_CONTEXT,
+ EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)NULL,
+ attribs);
+}
+
+static int
+redraw(GstAppContext* gstctx)
+{
+ struct display *display = gstctx->display;
+ GstVideoMeta *vmeta = gstctx->vmeta;
+ struct window *window = display->window;
+ GLfloat vVertices[] = { -1.0f, 1.0f, 1.0f, // Position 0
+ 0.0f, 0.0f, // TexCoord 0
+ -1.0f, -1.0f, 1.0f, // Position 1
+ 0.0f, 1.0f, // TexCoord 1
+ 1.0f, -1.0f, 1.0f, // Position 2
+ 1.0f, 1.0f, // TexCoord 2
+ 1.0f, 1.0f, 1.0f, // Position 3, skewed a bit
+ 1.0f, 0.0f // TexCoord 3
+ };
+
+ GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
+ glViewport(0,0,vmeta->width,vmeta->height);
+ wl_egl_window_resize(window->native,vmeta->width,vmeta->height,0,0);
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glUseProgram(display->gl.program_object);
+
+ /* Load the vertex position */
+ GLint positionLoc = glGetAttribLocation(display->gl.program_object, "a_position");
+ glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vVertices);
+ /* Load the texture coordinate */
+ GLint texCoordLoc = glGetAttribLocation(display->gl.program_object, "a_texCoord");
+ glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3]);
+ glEnableVertexAttribArray(positionLoc);
+ glEnableVertexAttribArray(texCoordLoc);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, display->gl.texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+
+ if(gstctx->no_dma_buf == false && window->egl_img != NULL )
+ {
+ display->egl.image_texture_2d(GL_TEXTURE_2D, window->egl_img);
+ }
+ else
+ {
+ GstMapInfo map;
+ gst_buffer_map(gstctx->gstbuffer, &map, GST_MAP_READ);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, vmeta->width, vmeta->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)map.data);
+ gst_buffer_unmap(gstctx->gstbuffer, &map);
+ }
+
+ /* Set the texture sampler to texture unit 0 */
+ GLint tex = glGetUniformLocation(display->gl.program_object, "tex");
+ glUniform1i(tex, 0);
+
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+
+ eglSwapBuffers(display->egl.dpy, window->egl_surface);
+}
+
+static GstFlowReturn
+appsink_callback(GstElement *object, gpointer *data)
+{
+ wth_verbose("%s >>> \n",__func__);
+ int ret;
+ GstAppContext *gstctx = (struct gstApplContext *)data;
+ GstSample *sample;
+ GstBuffer *gstbuffer;
+ GstMemory *mem;
+ int i;
+ int n_mem;
+
+ sample = gst_app_sink_pull_sample((GstAppSink*)((void*)object));
+ if(sample == NULL) {
+ wth_error("No frame received\n");
+ return -1;
+ }
+ else {
+ wth_verbose("Frame received\n");
+ }
+
+ /* get dmabuf fd from gstbuffer */
+ gstbuffer = gst_sample_get_buffer(sample);
+ if(!gstbuffer){
+ wth_error("Cannot get buffer from sample\n");
+ }
+ gstctx->vmeta = gst_buffer_get_video_meta(gstbuffer);
+ if(gstctx->vmeta==NULL){
+ wth_error("no metadata on buffer\n");
+ }
+
+ n_mem = gst_buffer_n_memory(gstbuffer);
+ if (n_mem < 1) {
+ wth_error("Buffer with no mem!\n");
+ }
+
+ for (i = 0; i < n_mem; i++) {
+ /* get dmabuf fd from gstbuffer */
+ mem = gst_buffer_peek_memory (gstbuffer, i);
+ if (!gst_is_dmabuf_memory(mem)) {
+ wth_verbose("Memory is not of dmabuf type \n");
+ gstctx->no_dma_buf = true;
+
+ gst_buffer_ref(gstbuffer);
+ gstctx->gstbuffer = gstbuffer;
+ gstctx->sample = sample;
+
+ /* wake render thread up */
+ gstctx->wait = 0;
+ pthread_cond_signal(&gstctx->cond);
+ wth_verbose(" <<< %s \n",__func__);
+ return GST_FLOW_OK;
+ }
+ gstctx->dma_fd[i] = gst_dmabuf_memory_get_fd(mem);
+ }
+
+ if (gstctx->dma_fd[0] < 0 || gstctx->dma_fd[1] < 0 ) {
+ wth_error("dma fd is null \n");
+ return GST_FLOW_ERROR;
+ }
+
+ gst_buffer_ref(gstbuffer);
+ gstctx->gstbuffer = gstbuffer;
+ gstctx->sample = sample;
+
+ /* wake render thread up */
+ gstctx->wait = 0;
+ pthread_cond_signal(&gstctx->cond);
+ wth_verbose(" <<< %s \n",__func__);
+ return GST_FLOW_OK;
+}
+
+/*
+ * registry callback
+ */
+static void
+registry_handle_global(void *data, struct wl_registry *registry,
+ uint32_t id, const char *interface, uint32_t version)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *d = data;
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ d->compositor =
+ wl_registry_bind(registry,
+ id, &wl_compositor_interface, 1);
+ } else if (strcmp(interface, "ivi_application") == 0) {
+ d->ivi_application =
+ wl_registry_bind(registry, id,
+ &ivi_application_interface, 1);
+ } else if (strcmp(interface, "wl_seat") == 0) {
+ add_seat(d, id, version);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+ uint32_t name)
+{
+ /* stub */
+}
+
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ registry_handle_global_remove
+};
+
+wth_server_weston_shm_attach(struct window *window, uint32_t data_sz, void * data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format)
+{
+ /* stub */
+}
+void
+wth_server_weston_shm_damage(struct window *window)
+{
+ /* stub */
+}
+
+void
+wth_server_weston_shm_commit(struct window *window)
+{
+ /* stub */
+}
+
+static struct display *
+create_display(void)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display;
+
+ display = malloc(sizeof *display);
+ if (display == NULL) {
+ wth_error("out of memory\n");
+ exit(1);
+ }
+ display->display = wl_display_connect(NULL);
+ assert(display->display);
+
+ display->has_xrgb = false;
+ display->registry = wl_display_get_registry(display->display);
+ wl_registry_add_listener(display->registry,
+ &registry_listener, display);
+ wl_display_roundtrip(display->display);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return display;
+}
+
+static void
+destroy_display(struct display *display)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ if (display->compositor)
+ wl_compositor_destroy(display->compositor);
+
+ wl_registry_destroy(display->registry);
+ wl_display_flush(display->display);
+ wl_display_disconnect(display->display);
+ free(display);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * ivi surface callback
+ */
+static void
+handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface,
+ int32_t width, int32_t height)
+{
+ /* Simple-shm is resizable */
+}
+
+static const struct ivi_surface_listener ivi_surface_listener = {
+ handle_ivi_surface_configure,
+};
+
+static void
+init_egl(struct display *display)
+{
+ wth_verbose("%s >>> \n",__func__);
+ EGLint config_attribs[] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_NONE
+ };
+
+ static const EGLint context_attribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ EGLint major, minor, count;
+ EGLBoolean ret;
+
+ display->egl.dpy = eglGetDisplay(display->display);
+ assert(display->egl.dpy);
+
+ ret = eglInitialize(display->egl.dpy, &major, &minor);
+ assert(ret == EGL_TRUE);
+ ret = eglBindAPI(EGL_OPENGL_ES_API);
+ assert(ret == EGL_TRUE);
+
+ ret = eglChooseConfig(display->egl.dpy, config_attribs,
+ &display->egl.conf, 1, &count);
+ assert(ret && count >= 1);
+
+ display->egl.ctx = eglCreateContext(display->egl.dpy,
+ display->egl.conf,
+ EGL_NO_CONTEXT, context_attribs);
+ assert(display->egl.ctx);
+
+ eglSwapInterval(display->egl.dpy, 1);
+
+ display->egl.create_image =
+ (void *) eglGetProcAddress("eglCreateImageKHR");
+ assert(display->egl.create_image);
+
+ display->egl.image_texture_2d =
+ (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
+ assert(display->egl.image_texture_2d);
+
+ display->egl.destroy_image =
+ (void *) eglGetProcAddress("eglDestroyImageKHR");
+ assert(display->egl.destroy_image);
+}
+
+GLuint load_shader(GLenum type, const char *shaderSrc)
+{
+ wth_verbose("%s >>> \n",__func__);
+ GLuint shader;
+ GLint compiled;
+
+ /* Create the shader object */
+ shader = glCreateShader(type);
+ if (shader == 0)
+ {
+ printf("\n Failed to create shader \n");
+ return 0;
+ }
+ /* Load the shader source */
+ glShaderSource(shader, 1, &shaderSrc, NULL);
+ /* Compile the shader */
+ glCompileShader(shader);
+ /* Check the compile status */
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled)
+ {
+ GLint infoLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen > 1)
+ {
+ char* infoLog = (char*)malloc (sizeof(char) * infoLen );
+ glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
+ fprintf(stderr, "Error compiling shader:%s\n",infoLog);
+ free(infoLog);
+ }
+ glDeleteShader(shader);
+ return 0;
+ }
+ return shader;
+}
+
+void init_gl(struct display *display)
+{
+ wth_verbose("%s >>> \n",__func__);
+ GLint linked;
+
+ /* load vertext/fragment shader */
+ display->gl.vertex_shader = load_shader(GL_VERTEX_SHADER, vertex_shader_str);
+ display->gl.fragment_shader = load_shader(GL_FRAGMENT_SHADER, fragment_shader_str);
+
+ /* Create the program object */
+ display->gl.program_object = glCreateProgram();
+ if (display->gl.program_object == 0)
+ {
+ fprintf(stderr, "error program object\n");
+ return;
+ }
+
+ glAttachShader(display->gl.program_object, display->gl.vertex_shader);
+ glAttachShader(display->gl.program_object, display->gl.fragment_shader);
+ /* Bind vPosition to attribute 0 */
+ glBindAttribLocation(display->gl.program_object, 0, "a_position");
+ /* Link the program */
+ glLinkProgram(display->gl.program_object);
+ /* Check the link status */
+ glGetProgramiv(display->gl.program_object, GL_LINK_STATUS, &linked);
+ if (!linked)
+ {
+ GLint infoLen = 0;
+ glGetProgramiv(display->gl.program_object, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen > 1)
+ {
+ char* infoLog = (char*)malloc(sizeof(char) * infoLen);
+ glGetProgramInfoLog(display->gl.program_object, infoLen, NULL, infoLog);
+ fprintf(stderr, "Error linking program:%s\n", infoLog);
+ free(infoLog);
+ }
+ glDeleteProgram(display->gl.program_object);
+ }
+
+ glGenTextures(1, &display->gl.texture);
+
+ return;
+}
+
+static void
+create_surface(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct display *display = window->display;
+ int ret;
+
+ window->surface = wl_compositor_create_surface(display->compositor);
+ assert(window->surface);
+
+ window->native = wl_egl_window_create(window->surface,
+ window->width, window->height);
+ assert(window->native);
+
+ window->egl_surface = eglCreateWindowSurface(display->egl.dpy,
+ display->egl.conf,
+ (NativeWindowType)window->native, NULL);
+
+ wl_display_roundtrip(display->display);
+ if (display->ivi_application ) {
+ uint32_t id_ivisurf = window->id_ivisurf;
+ window->ivi_surface =
+ ivi_application_surface_create(display->ivi_application,
+ id_ivisurf, window->surface);
+ if (window->ivi_surface == NULL) {
+ wth_error("Failed to create ivi_client_surface\n");
+ abort();
+ }
+
+ ivi_surface_add_listener(window->ivi_surface,
+ &ivi_surface_listener, window);
+ } else {
+ assert(0);
+ }
+ ret = eglMakeCurrent(display->egl.dpy, window->egl_surface,
+ window->egl_surface, display->egl.ctx);
+ assert(ret == EGL_TRUE);
+
+ glClearColor(0.5, 0.5, 0.5, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ eglSwapBuffers(display->egl.dpy, window->egl_surface);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+create_window(struct window *window, struct display *display, int width, int height)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ window->callback = NULL;
+
+ window->display = display;
+ window->width = width;
+ window->height = height;
+ window->window_frames = 0;
+ window->window_benchmark_time = 0;
+
+ create_surface(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+static void
+destroy_window(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ if (window->callback)
+ wl_callback_destroy(window->callback);
+
+ if (window->buffers[0].buffer)
+ wl_buffer_destroy(window->buffers[0].buffer);
+ if (window->buffers[1].buffer)
+ wl_buffer_destroy(window->buffers[1].buffer);
+
+ wl_surface_destroy(window->surface);
+ free(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+signal_int(int signum)
+{
+ running = 0;
+}
+
+void *stream_thread(void *data)
+{
+ wth_verbose("%s >>> \n",__func__);
+ GMainLoop *loop = data;
+ g_main_loop_run(loop);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+
+
+static GstPadProbeReturn
+pad_probe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
+{
+ wth_verbose("%s >>> \n",__func__);
+ GstAppContext *dec = user_data;
+ GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info);
+ GstCaps *caps;
+
+ (void)pad;
+
+ if (GST_EVENT_TYPE(event) != GST_EVENT_CAPS)
+ return GST_PAD_PROBE_OK;
+
+ gst_event_parse_caps(event, &caps);
+
+ if (!caps) {
+ GST_ERROR("caps event without caps");
+ return GST_PAD_PROBE_OK;
+ }
+
+ if (!gst_video_info_from_caps(&dec->info, caps)) {
+ GST_ERROR("caps event with invalid video caps");
+ return GST_PAD_PROBE_OK;
+ }
+
+ switch (GST_VIDEO_INFO_FORMAT(&(dec->info))) {
+ case GST_VIDEO_FORMAT_I420:
+ dec->format = DRM_FORMAT_YUV420;
+ break;
+ case GST_VIDEO_FORMAT_NV12:
+ dec->format = DRM_FORMAT_NV12;
+ break;
+ case GST_VIDEO_FORMAT_YUY2:
+ dec->format = DRM_FORMAT_YUYV;
+ break;
+ default:
+ GST_ERROR("unknown format\n");
+ return GST_PAD_PROBE_OK;
+ }
+ wth_verbose(" <<< %s \n",__func__);
+ return GST_PAD_PROBE_OK;
+}
+
+/**
+ * wth_server_weston_main
+ *
+ * This is the main function which will handle connection to the compositor at server side
+ *
+ * @param names void *data
+ * @param value struct window data
+ * @return 0 on success, -1 on error
+ */
+int
+wth_server_weston_main(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct sigaction sigint;
+ pthread_t pthread;
+ GstAppContext gstctx;
+ int ret = 0;
+ GError *gerror = NULL;
+ char * pipe = NULL;
+ FILE *pFile;
+ long lSize;
+ size_t res;
+
+ memset(&gstctx, 0, sizeof(gstctx));
+ /* Initialization for window creation */
+ gstctx.display = create_display();
+ init_egl(gstctx.display);
+ /* ToDo: fix the hardcoded value of width, height */
+ create_window(window, gstctx.display,1920,1080);
+ init_gl(gstctx.display);
+ gstctx.window = window;
+
+ gstctx.display->window = window;
+
+ wth_verbose("display %p\n", gstctx.display);
+ wth_verbose("display->window %p\n", gstctx.display->window);
+ wth_verbose("window %p\n", window);
+
+ sigint.sa_handler = signal_int;
+ sigemptyset(&sigint.sa_mask);
+ sigint.sa_flags = SA_RESETHAND;
+ sigaction(SIGINT, &sigint, NULL);
+
+ /* create gstreamer pipeline */
+ gst_init(NULL, NULL);
+ gstctx.loop = g_main_loop_new(NULL, FALSE);
+
+ /* Read pipeline from file */
+ pFile = fopen ( "/etc/xdg/weston/pipeline.cfg" , "rb" );
+ if (pFile==NULL){
+ fprintf(stderr, "failed to open file\n");
+ return -1;
+ }
+
+ /* obtain file size */
+ fseek (pFile , 0 , SEEK_END);
+ lSize = ftell (pFile);
+ rewind (pFile);
+
+ /* allocate memory to contain the whole file */
+ pipe = (char*) zalloc (sizeof(char)*lSize);
+ if (pipe == NULL){
+ fprintf(stderr,"Cannot allocate memory\n");
+ return -1;
+ }
+
+ /* copy the file into the buffer */
+ res = fread (pipe,1,lSize,pFile);
+ if (res != lSize){
+ fprintf(stderr,"File read error\n");
+ return -1;
+ }
+
+ wth_verbose("Gst Pipeline=%s",pipe);
+ /* close file */
+ fclose (pFile);
+
+ /* parse the pipeline */
+ gstctx.pipeline = gst_parse_launch(pipe, &gerror);
+
+ if(!gstctx.pipeline)
+ fprintf(stderr,"Could not create gstreamer pipeline.\n");
+ free(pipe);
+
+ gstctx.bus = gst_pipeline_get_bus((GstPipeline*)((void*)gstctx.pipeline));
+ gst_bus_add_watch(gstctx.bus, bus_message, &gstctx);
+ fprintf(stderr, "registered bus signal\n");
+
+ gstctx.sink = gst_bin_get_by_name(GST_BIN(gstctx.pipeline), "sink");
+ g_object_set(G_OBJECT(gstctx.sink), "emit-signals", TRUE, NULL);
+ g_signal_connect(gstctx.sink, "new-sample", G_CALLBACK(appsink_callback), &gstctx);
+ g_object_set(G_OBJECT(gstctx.sink), "drop", TRUE, "max-buffers",-1, NULL);
+ gst_pad_add_probe(gst_element_get_static_pad(gstctx.sink, "sink"),
+ GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+ pad_probe, &gstctx, NULL);
+
+ fprintf(stderr, "set state as playing\n");
+ gst_element_set_state((GstElement*)((void*)gstctx.pipeline), GST_STATE_PLAYING);
+
+ pthread_mutex_init(&gstctx.mutex, NULL);
+ pthread_cond_init(&gstctx.cond, NULL);
+
+ pthread_create(&pthread, NULL, &stream_thread, gstctx.loop);
+
+ fprintf(stderr, "rendering part\n");
+
+ gstctx.wait = 1;
+ pthread_mutex_lock(&gstctx.mutex);
+
+ while (running && ret != -1) {
+ wth_verbose("in render loop\n");
+ ret = wl_display_dispatch(gstctx.display->display);
+ if(gstctx.wait == 1) {
+ wth_verbose("cond wait\n");
+ pthread_cond_wait(&gstctx.cond, &gstctx.mutex);
+ }
+
+ if(gstctx.no_dma_buf == false)
+ {
+ wth_verbose("create egl image\n");
+ window->egl_img = create_eglImage(&gstctx);
+ }
+
+ wth_verbose("redraw\n");
+ redraw(&gstctx);
+ wth_verbose("fin redraw\n");
+ gstctx.display->egl.destroy_image(gstctx.display->egl.dpy, window->egl_img);
+ gst_buffer_unref(gstctx.gstbuffer);
+ gst_sample_unref(gstctx.sample);
+ gstctx.wait = 1;
+ }
+ pthread_mutex_unlock(&gstctx.mutex);
+
+ wth_verbose("wth_server_gst_main exiting\n");
+
+ if (window->display->ivi_application) {
+ ivi_surface_destroy(window->ivi_surface);
+ ivi_application_destroy(window->display->ivi_application);
+ }
+
+ destroy_window(window);
+ destroy_display(gstctx.display);
+
+ wth_verbose(" <<< %s \n",__func__);
+
+ return 0;
+}
diff --git a/demo3/horizontal/waltham-server/orig/src/wth-server-main.c b/demo3/horizontal/waltham-server/orig/src/wth-server-main.c
new file mode 100644
index 0000000..4bbf399
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/src/wth-server-main.c
@@ -0,0 +1,344 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+** **
+** SRC-MODULE: **
+** **
+** TARGET : linux **
+** **
+** PROJECT : waltham-server **
+** **
+** AUTHOR : **
+** **
+** **
+** **
+** PURPOSE : This file handles connection with remote-client **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+#include <signal.h>
+#include "wth-server-waltham-comm.h"
+
+#define MAX_EPOLL_WATCHES 2
+
+int verbose=0;
+uint16_t tcp_port;
+
+
+
+/** get verbosity
+ */
+bool
+get_verbosity()
+{
+ if (verbose == 1)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/** Print out the application help
+ */
+static void usage(void)
+{
+ printf("Usage: waltham server [options]\n");
+ printf("Options:\n");
+ printf(" -p --port number TCP port number\n");
+ printf(" -h --help Usage\n");
+ printf(" -v --verbose Set verbose flag (Default:%d)\n", get_verbosity());
+}
+
+static struct option long_options[] = {
+ {"port", required_argument, 0, 'p'},
+ {"verbose", no_argument, 0, 'v'},
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0}
+};
+
+/**
+ * parse_args
+ *
+ * Parses the application arguments
+ * The arguments are parsed and saved in static structure for future use.
+ *
+ * @param argc The amount of arguments
+ * @param argv The table of arguments
+ *
+ * @return 0 on success, -1 otherwise
+ */
+static int parse_args(int argc, char *argv[])
+{
+ int c = -1;
+ int long_index = 0;
+
+ while ((c = getopt_long(argc,
+ argv,
+ "p:vh",
+ long_options,
+ &long_index)) != -1)
+ {
+ switch (c)
+ {
+ case 'p':
+ tcp_port = atoi(optarg);
+ break;
+ case 'v':
+ verbose=1;
+ break;
+ case 'h':
+ usage();
+ return -1;
+ default:
+ wth_error("Try %s -h for more information.\n", argv[0]);
+ return -1;
+ }
+ }
+
+ if (tcp_port == 0)
+ {
+ wth_error("TCP port not set \n");
+ wth_error("Try %s -h for more information.\n", argv[0]);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+watch_ctl(struct watch *w, int op, uint32_t events)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct epoll_event ee;
+
+ ee.events = events;
+ ee.data.ptr = w;
+ wth_verbose(" <<< %s \n",__func__);
+ return epoll_ctl(w->server->epoll_fd, op, w->fd, &ee);
+}
+
+/**
+* listen_socket_handle_data
+*
+* Handles all incoming events on socket
+*
+* @param names struct watch *w ,uint32_t events
+* @param value pointer to watch connection it holds server information, Incoming events information
+* @return none
+*/
+static void
+listen_socket_handle_data(struct watch *w, uint32_t events)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct server *srv = container_of(w, struct server, listen_watch);
+
+ if (events & EPOLLERR) {
+ wth_error("Listening socket errored out.\n");
+ srv->running = false;
+
+ return;
+ }
+
+ if (events & EPOLLHUP) {
+ wth_error("Listening socket hung up.\n");
+ srv->running = false;
+
+ return;
+ }
+
+ if (events & EPOLLIN)
+ {
+ wth_verbose("EPOLLIN evnet received. \n");
+ server_accept_client(srv);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/**
+* server_mainloop
+*
+* This is the main loop, which will flush all pending clients requests and
+* listen to input events from socket
+*
+* @param names void *data
+* @param value pointer to server struct -
+* struct holds the client connection information
+* @return none
+*/
+static void
+server_mainloop(struct server *srv)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct epoll_event ee[MAX_EPOLL_WATCHES];
+ struct watch *w;
+ int count;
+ int i;
+
+ srv->running = true;
+
+ while (srv->running) {
+ /* Run any idle tasks at this point. */
+
+ server_flush_clients(srv);
+
+ /* Wait for events or signals */
+ count = epoll_wait(srv->epoll_fd,
+ ee, ARRAY_LENGTH(ee), -1);
+ if (count < 0 && errno != EINTR) {
+ perror("Error with epoll_wait");
+ break;
+ }
+
+ /* Handle all fds, both the listening socket
+ * (see listen_socket_handle_data()) and clients
+ * (see connection_handle_data()).
+ */
+ for (i = 0; i < count; i++) {
+ w = ee[i].data.ptr;
+ w->cb(w, ee[i].events);
+ }
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static int
+server_listen(uint16_t tcp_port)
+{
+ wth_verbose("%s >>> \n",__func__);
+ int fd;
+ int reuse = 1;
+ struct sockaddr_in addr;
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(tcp_port);
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof reuse);
+
+ if (bind(fd, (struct sockaddr *)&addr, sizeof addr) < 0) {
+ wth_error("Failed to bind to port %d", tcp_port);
+ close(fd);
+ return -1;
+ }
+
+ if (listen(fd, 1024) < 0) {
+ wth_error("Failed to listen to port %d", tcp_port);
+ close (fd);
+ return -1;
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+ return fd;
+}
+
+static bool *signal_int_handler_run_flag;
+
+static void
+signal_int_handler(int signum)
+{
+ wth_verbose("%s >>> \n",__func__);
+ if (!*signal_int_handler_run_flag)
+ abort();
+
+ *signal_int_handler_run_flag = false;
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+set_sigint_handler(bool *running)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct sigaction sigint;
+
+ signal_int_handler_run_flag = running;
+ sigint.sa_handler = signal_int_handler;
+ sigemptyset(&sigint.sa_mask);
+ sigint.sa_flags = SA_RESETHAND;
+ sigaction(SIGINT, &sigint, NULL);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/**
+* main
+*
+* waltham server main function, it accepts tcp port number as argument.
+* Establishes connection on the port and listen to port for incoming connection
+* request from waltham clients
+*
+* @param names argv - argument list and argc -argument count
+* @param value tcp port number as argument
+* @return 0 on success, -1 on error
+*/
+int
+main(int argc, char *argv[])
+{
+ struct server srv = { 0 };
+ struct client *c;
+
+ wth_verbose("%s >>> \n",__func__);
+
+ /* Get command line arguments */
+ if (parse_args(argc, argv) != 0)
+ {
+ return -1;
+ }
+
+ set_sigint_handler(&srv.running);
+
+ wl_list_init(&srv.client_list);
+
+ srv.epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+ if (srv.epoll_fd == -1) {
+ perror("Error on epoll_create1");
+ exit(1);
+ }
+
+ srv.listen_fd = server_listen(tcp_port);
+ if (srv.listen_fd < 0) {
+ perror("Error setting up listening socket");
+ exit(1);
+ }
+
+ srv.listen_watch.server = &srv;
+ srv.listen_watch.cb = listen_socket_handle_data;
+ srv.listen_watch.fd = srv.listen_fd;
+ if (watch_ctl(&srv.listen_watch, EPOLL_CTL_ADD, EPOLLIN) < 0) {
+ perror("Error setting up listen polling");
+ exit(1);
+ }
+
+ wth_verbose("Waltham server listening on TCP port %u...\n",tcp_port);
+
+
+ server_mainloop(&srv);
+
+ /* destroy all things */
+ wl_list_last_until_empty(c, &srv.client_list, link)
+ client_destroy(c);
+
+ close(srv.listen_fd);
+ close(srv.epoll_fd);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return 0;
+}
diff --git a/demo3/horizontal/waltham-server/orig/src/wth-server-waltham-comm.c b/demo3/horizontal/waltham-server/orig/src/wth-server-waltham-comm.c
new file mode 100644
index 0000000..bcd2cd4
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/src/wth-server-waltham-comm.c
@@ -0,0 +1,1179 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+** **
+** SRC-MODULE: **
+** **
+** TARGET : linux **
+** **
+** PROJECT : waltham-server **
+** **
+** AUTHOR : **
+** **
+** **
+** **
+** PURPOSE : This file acts as interface to waltham IPC library **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+#include "wth-server-waltham-comm.h"
+
+extern int wth_server_weston_main(struct window *);
+
+extern void wth_server_weston_shm_attach(struct window *, uint32_t data_sz, void * data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format);
+extern void wth_server_weston_shm_damage(struct window *);
+extern void wth_server_weston_shm_commit(struct window *);
+
+extern bool get_verbosity(void);
+extern int verbose;
+
+/*
+ * utility functions
+ */
+static int
+watch_ctl(struct watch *w, int op, uint32_t events)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct epoll_event ee;
+
+ ee.events = events;
+ ee.data.ptr = w;
+ wth_verbose(" <<< %s \n",__func__);
+ return epoll_ctl(w->server->epoll_fd, op, w->fd, &ee);
+}
+
+static void
+client_post_out_of_memory(struct client *c)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct wth_display *disp;
+
+ disp = wth_connection_get_display(c->connection);
+ wth_object_post_error((struct wth_object *)disp, 1,
+ "out of memory");
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * waltham surface implementation
+ */
+static void
+surface_destroy(struct surface *surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("surface %p destroy\n", surface->obj);
+
+ wthp_surface_free(surface->obj);
+ wl_list_remove(&surface->link);
+ free(surface);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_destroy(struct wthp_surface *wthp_surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = wth_object_get_user_data((struct wth_object *)wthp_surface);
+
+ assert(wthp_surface == surface->obj);
+
+ surface_destroy(surface);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_attach(struct wthp_surface *wthp_surface,
+ struct wthp_buffer *wthp_buffer, int32_t x, int32_t y)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct buffer *buffr = wth_object_get_user_data((struct wth_object *)wthp_buffer);
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ struct buffer *buf = NULL;
+
+ buf = container_of(wthp_buffer, struct buffer, obj);
+
+ if (surf->ivi_id != 0) {
+ wth_server_weston_shm_attach(surf->shm_window,
+ buf->data_sz,
+ buf->data,
+ buf->width,
+ buf->height,
+ buf->stride,
+ buf->format);
+
+ wthp_buffer_send_complete(wthp_buffer, 0);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_damage(struct wthp_surface *wthp_surface,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("surface %p damage(%d, %d, %d, %d)\n",
+ wthp_surface, x, y, width, height);
+
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+
+ if (surf->ivi_id != 0) {
+ wth_server_weston_shm_damage(surf->shm_window);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_frame(struct wthp_surface *wthp_surface,
+ struct wthp_callback *callback)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ wth_verbose("surface %p callback(%p)\n",wthp_surface, callback);
+
+ surf->cb = callback;
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_set_opaque_region(struct wthp_surface *wthp_surface,
+ struct wthp_region *region)
+{
+ wth_verbose("surface %p set_opaque_region(%p)\n",
+ wthp_surface, region);
+}
+
+static void
+surface_handle_set_input_region(struct wthp_surface *wthp_surface,
+ struct wthp_region *region)
+{
+ wth_verbose("surface %p set_input_region(%p)\n",
+ wthp_surface, region);
+}
+
+static void
+surface_handle_commit(struct wthp_surface *wthp_surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ wth_verbose("commit %p\n",wthp_surface);
+
+ if (surf->ivi_id != 0) {
+ wth_server_weston_shm_commit(surf->shm_window);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_set_buffer_transform(struct wthp_surface *wthp_surface,
+ int32_t transform)
+{
+ wth_verbose("surface %p et_buffer_transform(%d)\n",
+ wthp_surface, transform);
+}
+
+static void
+surface_handle_set_buffer_scale(struct wthp_surface *wthp_surface,
+ int32_t scale)
+{
+ wth_verbose("surface %p set_buffer_scale(%d)\n",
+ wthp_surface, scale);
+}
+
+static void
+surface_handle_damage_buffer(struct wthp_surface *wthp_surface,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ wth_verbose("surface %p damage_buffer(%d, %d, %d, %d)\n",
+ wthp_surface, x, y, width, height);
+}
+
+static const struct wthp_surface_interface surface_implementation = {
+ surface_handle_destroy,
+ surface_handle_attach,
+ surface_handle_damage,
+ surface_handle_frame,
+ surface_handle_set_opaque_region,
+ surface_handle_set_input_region,
+ surface_handle_commit,
+ surface_handle_set_buffer_transform,
+ surface_handle_set_buffer_scale,
+ surface_handle_damage_buffer
+};
+
+
+/* BEGIN wthp_region implementation */
+
+static void
+buffer_handle_destroy(struct wthp_buffer *wthp_buffer)
+{
+ struct buffer *buf = wth_object_get_user_data((struct wth_object *)wthp_buffer);
+
+ wthp_buffer_free(wthp_buffer);
+ wl_list_remove(&buf->link);
+ free(buf);
+}
+
+static const struct wthp_buffer_interface buffer_implementation = {
+ buffer_handle_destroy
+};
+
+/* END wthp_region implementation */
+
+/* BEGIN wthp_blob_factory implementation */
+
+static void
+blob_factory_create_buffer(struct wthp_blob_factory *blob_factory,
+ struct wthp_buffer *wthp_buffer, uint32_t data_sz, void *data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format)
+{
+ struct blob_factory *blob = wth_object_get_user_data((struct wth_object *)blob_factory);
+ struct buffer *buffer;
+
+
+ wth_verbose("wthp_blob_factory %p create_buffer(%p, %d, %p, %d, %d, %d, %d)\n",
+ blob_factory, wthp_buffer, data_sz, data, width, height, stride, format);
+
+ buffer = zalloc(sizeof *buffer);
+ if (!buffer) {
+ client_post_out_of_memory(blob->client);
+ return;
+ }
+
+ wl_list_insert(&blob->client->buffer_list, &buffer->link);
+
+ buffer->data_sz = data_sz;
+ buffer->data = data;
+ buffer->width = width;
+ buffer->height = height;
+ buffer->stride = stride;
+ buffer->format = format;
+ buffer->obj = wthp_buffer;
+
+ wthp_buffer_set_interface(wthp_buffer, &buffer_implementation, buffer);
+}
+
+static const struct wthp_blob_factory_interface blob_factory_implementation = {
+ blob_factory_create_buffer
+};
+
+static void
+client_bind_blob_factory(struct client *c, struct wthp_blob_factory *obj)
+{
+ struct blob_factory *blob;
+
+ blob = zalloc(sizeof *blob);
+ if (!blob) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ blob->obj = obj;
+ blob->client = c;
+ wl_list_insert(&c->compositor_list, &blob->link);
+
+ wthp_blob_factory_set_interface(obj, &blob_factory_implementation,
+ blob);
+ fprintf(stderr, "client %p bound wthp_blob_factory\n", c);
+}
+
+/*
+ * waltam ivi surface implementation
+ */
+static void
+wthp_ivi_surface_destroy(struct wthp_ivi_surface * ivi_surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct ivisurface *ivisurf = wth_object_get_user_data((struct wth_object *)ivi_surface);
+ free(ivisurf);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_ivi_surface_interface wthp_ivi_surface_implementation = {
+ wthp_ivi_surface_destroy,
+};
+
+
+/*
+ * waltham ivi application implementation
+ */
+static void
+wthp_ivi_application_surface_create(struct wthp_ivi_application * ivi_application, uint32_t ivi_id,
+ struct wthp_surface * wthp_surface, struct wthp_ivi_surface *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("ivi_application %p surface_create(%d, %p, %p)\n",
+ ivi_application, ivi_id, wthp_surface, obj);
+ struct application *app = wth_object_get_user_data((struct wth_object *)ivi_application);
+ struct surface *surface = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ wth_verbose("----------------------------------\n\n\n");
+ wth_verbose("surface [%p]\n", surface);
+ wth_verbose("shm_window [%p]\n\n\n", surface->shm_window);
+ wth_verbose("----------------------------------\n");
+
+ surface->ivi_id = ivi_id + 100;
+ surface->shm_window->id_ivisurf = surface->ivi_id;
+ struct ivisurface *ivisurf;
+
+ ivisurf = zalloc(sizeof *ivisurf);
+ if (!ivisurf) {
+ return;
+ }
+
+ ivisurf->obj = obj;
+ ivisurf->surf = surface;
+
+ wth_server_weston_main(surface->shm_window);
+
+ while (!surface->shm_window->ready)
+ usleep(1);
+
+ wthp_ivi_surface_set_interface(obj, &wthp_ivi_surface_implementation,
+ ivisurf);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_ivi_application_interface wthp_ivi_application_implementation = {
+ wthp_ivi_application_surface_create,
+};
+
+static void
+client_bind_wthp_ivi_application(struct client *c, struct wthp_ivi_application *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct application *app;
+
+ app = zalloc(sizeof *app);
+ if (!app) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ app->obj = obj;
+ app->client = c;
+ wl_list_insert(&c->compositor_list, &app->link);
+
+ wthp_ivi_application_set_interface(obj, &wthp_ivi_application_implementation,
+ app);
+ wth_verbose("client %p bound wthp_ivi_application\n", c);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * APIs to send pointer events to waltham client
+ */
+
+void
+waltham_pointer_enter(struct window *window, uint32_t serial,
+ wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wth_verbose("waltham_pointer_enter [%d]\n", window->server_surf->ivi_id);
+
+ wthp_pointer_send_enter (pointer->obj, serial, surface->obj, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_leave(struct window *window, uint32_t serial)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wth_verbose("waltham_pointer_leave [%d]\n", window->server_surf->ivi_id);
+
+ wthp_pointer_send_leave (pointer->obj, serial, surface->obj);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_motion(struct window *window, uint32_t time,
+ wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wthp_pointer_send_motion (pointer->obj, time, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_button(struct window *window, uint32_t serial,
+ uint32_t time, uint32_t button,
+ uint32_t state)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wthp_pointer_send_button (pointer->obj, serial, time, button, state);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_axis(struct window *window, uint32_t time,
+ uint32_t axis, wl_fixed_t value)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wthp_pointer_send_axis (pointer->obj, time, axis, value);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+/*
+ * waltham pointer implementation
+ */
+static void
+pointer_set_cursor(struct wthp_pointer *wthp_pointer, int32_t serial, struct wthp_surface *surface,
+ int32_t hotspot_x, int32_t hotspot_y)
+{
+ struct pointer *pointer = wth_object_get_user_data((struct wth_object *)wthp_pointer);
+
+ wth_verbose("wthp_pointer %p (%d, %p, %d, %d)\n",
+ wthp_pointer, serial, surface, hotspot_x, hotspot_y);
+
+}
+
+static void
+pointer_release(struct wthp_pointer *wthp_pointer)
+{
+ struct pointer *pointer = wth_object_get_user_data((struct wth_object *)wthp_pointer);
+
+ wth_verbose("wthp_pointer %p\n",wthp_pointer);
+}
+
+static const struct wthp_pointer_interface pointer_implementation = {
+ pointer_set_cursor,
+ pointer_release
+};
+
+/*
+ * APIs to send touch events to waltham client
+ */
+
+void
+waltham_touch_down(struct window *window, uint32_t serial,
+ uint32_t time, int32_t id,
+ wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wth_verbose("touch_handle_down surface [%d]\n", surface->ivi_id);
+ wthp_touch_send_down(touch->obj, serial, time, surface->obj, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_up(struct window *window, uint32_t serial,
+ uint32_t time, int32_t id)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_up(touch->obj, serial, time, id);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_motion(struct window *window, uint32_t time,
+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_motion(touch->obj, time, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_frame(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_frame(touch->obj);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_cancel(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_cancel(touch->obj);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+/*
+ * waltham touch implementation
+ */
+static void
+touch_release(struct wthp_touch *wthp_touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct touch *touch = wth_object_get_user_data((struct wth_object *)wthp_touch);
+
+ wth_verbose("%p\n",wthp_touch);
+}
+
+static const struct wthp_touch_interface touch_implementation = {
+ touch_release,
+};
+
+/*
+ * waltham seat implementation
+ */
+static void
+seat_get_pointer(struct wthp_seat *wthp_seat, struct wthp_pointer *wthp_pointer)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("wthp_seat %p get_pointer(%p)\n",
+ wthp_seat, wthp_pointer);
+
+ struct seat *seat = wth_object_get_user_data((struct wth_object *)wthp_seat);
+ struct pointer *pointer;
+
+ pointer = zalloc(sizeof *pointer);
+ if (!pointer) {
+ client_post_out_of_memory(seat->client);
+ return;
+ }
+
+ pointer->obj = wthp_pointer;
+ pointer->seat = seat;
+ seat->pointer = pointer;
+ wl_list_insert(&seat->client->pointer_list, &pointer->link);
+
+ wthp_pointer_set_interface(wthp_pointer, &pointer_implementation, pointer);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+seat_get_touch(struct wthp_seat *wthp_seat, struct wthp_touch *wthp_touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("wthp_seat %p get_touch(%p)\n",
+ wthp_seat, wthp_touch);
+
+ struct seat *seat = wth_object_get_user_data((struct wth_object *)wthp_seat);
+ struct touch *touch;
+
+ touch = zalloc(sizeof *touch);
+ if (!touch) {
+ client_post_out_of_memory(seat->client);
+ return;
+ }
+
+ touch->obj = wthp_touch;
+ touch->seat = seat;
+ seat->touch = touch;
+ wl_list_insert(&seat->client->touch_list, &touch->link);
+
+ wthp_touch_set_interface(wthp_touch, &touch_implementation, touch);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+seat_release(struct wthp_seat *wthp_seat)
+{
+}
+
+static const struct wthp_seat_interface seat_implementation = {
+ seat_get_pointer,
+ NULL,
+ seat_get_touch,
+ seat_release,
+ NULL
+};
+
+static void
+seat_send_updated_caps(struct seat *seat)
+{
+ wth_verbose("%s >>> \n",__func__);
+ enum wthp_seat_capability caps = 0;
+
+ caps |= WTHP_SEAT_CAPABILITY_POINTER;
+ wth_verbose("WTHP_SEAT_CAPABILITY_POINTER %d\n", caps);
+
+ caps |= WTHP_SEAT_CAPABILITY_TOUCH;
+ wth_verbose("WTHP_SEAT_CAPABILITY_TOUCH %d\n", caps);
+
+ wthp_seat_send_capabilities(seat->obj, caps);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+client_bind_seat(struct client *c, struct wthp_seat *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat;
+
+ seat = zalloc(sizeof *seat);
+ if (!seat) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ seat->obj = obj;
+ seat->client = c;
+ wl_list_insert(&c->seat_list, &seat->link);
+ wth_verbose("wthp_seat object=%p and seat=%p\n",obj,seat);
+ wthp_seat_set_interface(obj, &seat_implementation,
+ seat);
+ wth_verbose("client %p bound wthp_seat\n", c);
+ seat_send_updated_caps(seat);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * waltham region implementation
+ */
+
+static void
+region_destroy(struct region *region)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("region %p destroy\n", region->obj);
+
+ wthp_region_free(region->obj);
+ wl_list_remove(&region->link);
+ free(region);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+region_handle_destroy(struct wthp_region *wthp_region)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct region *region = wth_object_get_user_data((struct wth_object *)wthp_region);
+
+ assert(wthp_region == region->obj);
+
+ region_destroy(region);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+region_handle_add(struct wthp_region *wthp_region,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ wth_verbose("region %p add(%d, %d, %d, %d)\n",
+ wthp_region, x, y, width, height);
+}
+
+static void
+region_handle_subtract(struct wthp_region *wthp_region,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ wth_verbose("region %p subtract(%d, %d, %d, %d)\n",
+ wthp_region, x, y, width, height);
+}
+
+static const struct wthp_region_interface region_implementation = {
+ region_handle_destroy,
+ region_handle_add,
+ region_handle_subtract
+};
+
+/*
+ * waltham compositor implementation
+ */
+static void
+compositor_destroy(struct compositor *comp)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("%s: %p\n", __func__, comp->obj);
+
+ wthp_compositor_free(comp->obj);
+ wl_list_remove(&comp->link);
+ free(comp);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+compositor_handle_create_surface(struct wthp_compositor *compositor,
+ struct wthp_surface *id)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct compositor *comp = wth_object_get_user_data((struct wth_object *)compositor);
+ struct client *client = comp->client;
+ struct surface *surface;
+ struct seat *seat, *tmp;
+
+ wth_verbose("client %p create surface %p\n",
+ comp->client, id);
+
+ surface = zalloc(sizeof *surface);
+ if (!surface) {
+ client_post_out_of_memory(comp->client);
+ return;
+ }
+
+ surface->obj = id;
+ wl_list_insert(&comp->client->surface_list, &surface->link);
+
+ wthp_surface_set_interface(id, &surface_implementation, surface);
+
+ surface->shm_window = calloc(1, sizeof *surface->shm_window);
+ if (!surface->shm_window)
+ return;
+
+ surface->shm_window->server_surf = surface;
+ surface->shm_window->ready = false;
+ surface->ivi_id = 0;
+
+ wl_list_for_each_safe(seat, tmp, &client->seat_list, link) {
+ surface->shm_window->server_seat = seat;
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+compositor_handle_create_region(struct wthp_compositor *compositor,
+ struct wthp_region *id)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct compositor *comp = wth_object_get_user_data((struct wth_object *)compositor);
+ struct region *region;
+
+ wth_verbose("client %p create region %p\n",
+ comp->client, id);
+
+ region = zalloc(sizeof *region);
+ if (!region) {
+ client_post_out_of_memory(comp->client);
+ return;
+ }
+
+ region->obj = id;
+ wl_list_insert(&comp->client->region_list, &region->link);
+
+ wthp_region_set_interface(id, &region_implementation, region);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_compositor_interface compositor_implementation = {
+ compositor_handle_create_surface,
+ compositor_handle_create_region
+};
+
+static void
+client_bind_compositor(struct client *c, struct wthp_compositor *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct compositor *comp;
+
+ comp = zalloc(sizeof *comp);
+ if (!comp) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ comp->obj = obj;
+ comp->client = c;
+ wl_list_insert(&c->compositor_list, &comp->link);
+
+ wthp_compositor_set_interface(obj, &compositor_implementation,
+ comp);
+ wth_verbose("client %p bound wthp_compositor\n", c);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * waltham registry implementation
+ */
+static void
+registry_destroy(struct registry *reg)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("%s: %p\n", __func__, reg->obj);
+
+ wthp_registry_free(reg->obj);
+ wl_list_remove(&reg->link);
+ free(reg);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+registry_handle_destroy(struct wthp_registry *registry)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct registry *reg = wth_object_get_user_data((struct wth_object *)registry);
+
+ registry_destroy(reg);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+registry_handle_bind(struct wthp_registry *registry,
+ uint32_t name,
+ struct wth_object *id,
+ const char *interface,
+ uint32_t version)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct registry *reg = wth_object_get_user_data((struct wth_object *)registry);
+ wth_verbose("Recieved registry : %s\n", interface);
+
+ if (strcmp(interface, "wthp_compositor") == 0) {
+ client_bind_compositor(reg->client, (struct wthp_compositor *)id);
+ } else if (strcmp(interface, "wthp_blob_factory") == 0) {
+ client_bind_blob_factory(reg->client, (struct wthp_blob_factory *)id);
+ struct client *client = reg->client;
+ struct seat *seat, *tmp,*get_seat;
+ wl_list_for_each_safe(seat, tmp, &client->seat_list, link) {
+ get_seat = seat;
+ }
+ wth_verbose("get_seat : %p\n", get_seat);
+ seat_send_updated_caps(get_seat);
+ } else if (strcmp(interface, "wthp_ivi_application") == 0) {
+ client_bind_wthp_ivi_application(reg->client, (struct wthp_ivi_application *)id);
+ } else if (strcmp(interface, "wthp_seat") == 0) {
+ client_bind_seat(reg->client, (struct wthp_seat *)id);
+ } else {
+ wth_object_post_error((struct wth_object *)registry, 0,
+ "%s: unknown name %u", __func__, name);
+ wth_object_delete(id);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_registry_interface registry_implementation = {
+ registry_handle_destroy,
+ registry_handle_bind
+};
+
+/*
+ * waltham display implementation
+ */
+
+static void
+display_handle_client_version(struct wth_display *wth_display,
+ uint32_t client_version)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_object_post_error((struct wth_object *)wth_display, 0,
+ "unimplemented: %s", __func__);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+display_handle_sync(struct wth_display * wth_display, struct wthp_callback * callback)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c = wth_object_get_user_data((struct wth_object *)wth_display);
+
+ wth_verbose("Client %p requested wth_display.sync\n", c);
+ wthp_callback_send_done(callback, 0);
+ wthp_callback_free(callback);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+display_handle_get_registry(struct wth_display *wth_display,
+ struct wthp_registry *registry)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c = wth_object_get_user_data((struct wth_object *)wth_display);
+ struct registry *reg;
+
+ reg = zalloc(sizeof *reg);
+ if (!reg) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ reg->obj = registry;
+ reg->client = c;
+ wl_list_insert(&c->registry_list, &reg->link);
+ wthp_registry_set_interface(registry,
+ &registry_implementation, reg);
+
+ wthp_registry_send_global(registry, 1, "wthp_compositor", 4);
+ wthp_registry_send_global(registry, 1, "wthp_ivi_application", 1);
+ wthp_registry_send_global(registry, 1, "wthp_seat", 4);
+ wthp_registry_send_global(registry, 1, "wthp_blob_factory", 4);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+const struct wth_display_interface display_implementation = {
+ display_handle_client_version,
+ display_handle_sync,
+ display_handle_get_registry
+};
+
+/*
+ * functions to handle waltham client connections
+ */
+static void
+connection_handle_data(struct watch *w, uint32_t events)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c = container_of(w, struct client, conn_watch);
+ int ret;
+
+ if (events & EPOLLERR) {
+ wth_error("Client %p errored out.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+
+ if (events & EPOLLHUP) {
+ wth_error("Client %p hung up.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+
+ if (events & EPOLLOUT) {
+ ret = wth_connection_flush(c->connection);
+ if (ret == 0)
+ watch_ctl(&c->conn_watch, EPOLL_CTL_MOD, EPOLLIN);
+ else if (ret < 0 && errno != EAGAIN){
+ wth_error("Client %p flush error.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+ }
+
+ if (events & EPOLLIN) {
+ ret = wth_connection_read(c->connection);
+ if (ret < 0) {
+ wth_error("Client %p read error.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+
+ ret = wth_connection_dispatch(c->connection);
+ if (ret < 0 && errno != EPROTO) {
+ wth_error("Client %p dispatch error.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/**
+* client_create
+*
+* Create new client connection
+*
+* @param srv Server structure
+* @param wth_connection Waltham connection handle
+* @return Pointer to client structure
+*/
+static struct client *
+client_create(struct server *srv, struct wth_connection *conn)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c;
+ struct wth_display *disp;
+
+ c = zalloc(sizeof *c);
+ if (!c)
+ return NULL;
+
+ c->server = srv;
+ c->connection = conn;
+
+ c->conn_watch.server = srv;
+ c->conn_watch.fd = wth_connection_get_fd(conn);
+ c->conn_watch.cb = connection_handle_data;
+ if (watch_ctl(&c->conn_watch, EPOLL_CTL_ADD, EPOLLIN) < 0) {
+ free(c);
+ return NULL;
+ }
+
+ wth_verbose("Client %p connected.\n", c);
+
+ wl_list_insert(&srv->client_list, &c->link);
+
+ wl_list_init(&c->registry_list);
+ wl_list_init(&c->compositor_list);
+ wl_list_init(&c->seat_list);
+ wl_list_init(&c->pointer_list);
+ wl_list_init(&c->touch_list);
+ wl_list_init(&c->region_list);
+ wl_list_init(&c->surface_list);
+ wl_list_init(&c->buffer_list);
+
+ disp = wth_connection_get_display(c->connection);
+ wth_display_set_interface(disp, &display_implementation, c);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return c;
+}
+
+/**
+* client_destroy
+*
+* Destroy client connection
+*
+* @param names struct client *c
+* @param value client data
+* @return none
+*/
+void
+client_destroy(struct client *c)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct region *region;
+ struct compositor *comp;
+ struct registry *reg;
+ struct surface *surface;
+
+ wth_verbose("Client %p disconnected.\n", c);
+
+ /* clean up remaining client resources in case the client
+ * did not.
+ */
+ wl_list_last_until_empty(region, &c->region_list, link)
+ region_destroy(region);
+
+ wl_list_last_until_empty(comp, &c->compositor_list, link)
+ compositor_destroy(comp);
+
+ wl_list_last_until_empty(reg, &c->registry_list, link)
+ registry_destroy(reg);
+
+ wl_list_last_until_empty(surface, &c->surface_list, link)
+ surface_destroy(surface);
+
+ wl_list_remove(&c->link);
+ watch_ctl(&c->conn_watch, EPOLL_CTL_DEL, 0);
+ wth_connection_destroy(c->connection);
+ free(c);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/**
+* server_flush_clients
+*
+* write all the pending requests from the clients to socket
+*
+* @param names struct server *srv
+* @param value socket connection info and client data
+* @return none
+*/
+void
+server_flush_clients(struct server *srv)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c, *tmp;
+ int ret;
+
+ wl_list_for_each_safe(c, tmp, &srv->client_list, link) {
+ /* Flush out buffered requests. If the Waltham socket is
+ * full, poll it for writable too.
+ */
+ ret = wth_connection_flush(c->connection);
+ if (ret < 0 && errno == EAGAIN) {
+ watch_ctl(&c->conn_watch, EPOLL_CTL_MOD, EPOLLIN | EPOLLOUT);
+ } else if (ret < 0) {
+ perror("Connection flush failed");
+ client_destroy(c);
+ return;
+ }
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+
+}
+
+/**
+* server_accept_client
+*
+* Accepts new waltham client connection and instantiates client structure
+*
+* @param names struct server *srv
+* @param value socket connection info and client data
+* @return none
+*/
+void
+server_accept_client(struct server *srv)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *client;
+ struct wth_connection *conn;
+ struct sockaddr_in addr;
+ socklen_t len;
+
+ len = sizeof addr;
+ conn = wth_accept(srv->listen_fd, (struct sockaddr *)&addr, &len);
+ if (!conn) {
+ wth_error("Failed to accept a connection.\n");
+ return;
+ }
+
+ client = client_create(srv, conn);
+ if (!client) {
+ wth_error("Failed client_create().\n");
+ return;
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
diff --git a/demo3/horizontal/waltham-server/orig/src/wth-server-weston.c b/demo3/horizontal/waltham-server/orig/src/wth-server-weston.c
new file mode 100644
index 0000000..6cc309c
--- /dev/null
+++ b/demo3/horizontal/waltham-server/orig/src/wth-server-weston.c
@@ -0,0 +1,811 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+** **
+** SRC-MODULE: **
+** **
+** TARGET : linux **
+** **
+** PROJECT : waltham-server **
+** **
+** AUTHOR : **
+** **
+** **
+** **
+** PURPOSE : This file is acts as interface to weston compositor at server **
+** side **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+#include <sys/mman.h>
+#include <signal.h>
+#include <sys/time.h>
+
+#include "wth-server-weston.h"
+#include "os-compatibility.h"
+#include "ivi-application-client-protocol.h"
+#include "bitmap.h"
+
+
+static int running = 1;
+extern bool get_verbosity(void);
+extern int verbose;
+/*
+ * buffer callback
+ */
+static void
+buffer_release(void *data, struct wl_buffer *buffer)
+{
+ struct shm_buffer *mybuf = data;
+
+ wth_verbose("%s >>> \n",__func__);
+
+ mybuf->busy = 0;
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+ buffer_release
+};
+
+static int
+create_shm_buffer(struct display *display, struct shm_buffer *buffer,
+ int width, int height, uint32_t format)
+{
+ struct wl_shm_pool *pool;
+ int fd, size, stride;
+ void *data;
+
+ wth_verbose("%s >>> \n",__func__);
+ stride = width * 4;
+ size = stride * height;
+
+ fd = os_create_anonymous_file(size);
+ if (fd < 0) {
+ wth_error("creating a buffer file for %d B failed: %m\n",
+ size);
+ return -1;
+ }
+
+ data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (data == MAP_FAILED) {
+ wth_error("mmap failed: %m\n");
+ close(fd);
+ return -1;
+ }
+
+ pool = wl_shm_create_pool(display->shm, fd, size);
+ buffer->buffer = wl_shm_pool_create_buffer(pool, 0,
+ width, height,
+ stride, format);
+ wl_buffer_add_listener(buffer->buffer, &buffer_listener, buffer);
+ wl_shm_pool_destroy(pool);
+ close(fd);
+
+ buffer->shm_data = data;
+
+ wth_verbose(" <<< %s \n",__func__);
+ return 0;
+}
+
+/*
+ * ivi surface callback
+ */
+static void
+handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface,
+ int32_t width, int32_t height)
+{
+ /* Simple-shm is resizable */
+}
+
+static const struct ivi_surface_listener ivi_surface_listener = {
+ handle_ivi_surface_configure,
+};
+
+static void
+create_window(struct window *window, struct display *display, int width, int height)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ window->callback = NULL;
+ window->display = display;
+ window->width = width;
+ window->height = height;
+ window->surface = wl_compositor_create_surface(display->compositor);
+ window->window_frames = 0;
+ window->window_benchmark_time = 0;
+
+ wl_display_roundtrip(display->display);
+ if (display->ivi_application ) {
+ uint32_t id_ivisurf = window->id_ivisurf;
+ window->ivi_surface =
+ ivi_application_surface_create(display->ivi_application,
+ id_ivisurf, window->surface);
+ if (window->ivi_surface == NULL) {
+ wth_error("Failed to create ivi_client_surface\n");
+ abort();
+ }
+
+ ivi_surface_add_listener(window->ivi_surface,
+ &ivi_surface_listener, window);
+
+ } else {
+ assert(0);
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+static void
+destroy_window(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ if (window->callback)
+ wl_callback_destroy(window->callback);
+
+ if (window->buffers[0].buffer)
+ wl_buffer_destroy(window->buffers[0].buffer);
+ if (window->buffers[1].buffer)
+ wl_buffer_destroy(window->buffers[1].buffer);
+
+ wl_surface_destroy(window->surface);
+ free(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static struct shm_buffer *
+window_next_buffer(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct shm_buffer *buffer;
+ int ret = 0;
+
+ if (!window->buffers[0].busy)
+ buffer = &window->buffers[0];
+ else if (!window->buffers[1].busy)
+ buffer = &window->buffers[1];
+ else {
+ window->buffers[0].busy = 0;
+ window->buffers[0].busy = 1;
+ buffer = &window->buffers[0];
+ }
+
+ if (!buffer->buffer) {
+ ret = create_shm_buffer(window->display, buffer,
+ window->width, window->height,
+ WL_SHM_FORMAT_XRGB8888);
+
+ if (ret < 0)
+ return NULL;
+
+ /* paint the padding */
+ memset(buffer->shm_data, 0xff,
+ window->width * window->height * 4);
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+ return buffer;
+}
+
+static void
+paint_pixels(void *image, int padding, int width, int height, uint32_t time)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ const int halfh = padding + (height - padding * 2) / 2;
+ const int halfw = padding + (width - padding * 2) / 2;
+ int ir, or;
+ uint32_t *pixel = image;
+ int y;
+
+ /* squared radii thresholds */
+ or = (halfw < halfh ? halfw : halfh) - 8;
+ ir = or - 32;
+ or *= or;
+ ir *= ir;
+
+ pixel += padding * width;
+ for (y = padding; y < height - padding; y++) {
+ int x;
+ int y2 = (y - halfh) * (y - halfh);
+
+ pixel += padding;
+ for (x = padding; x < width - padding; x++) {
+ uint32_t v;
+
+ /* squared distance from center */
+ int r2 = (x - halfw) * (x - halfw) + y2;
+
+ if (r2 < ir)
+ v = (r2 / 32 + time / 64) * 0x0080401;
+ else if (r2 < or)
+ v = (y + time / 32) * 0x0080401;
+ else
+ v = (x + time / 16) * 0x0080401;
+ v &= 0x00ffffff;
+
+ /* cross if compositor uses X from XRGB as alpha */
+ if (abs(x - y) > 6 && abs(x + y - height) > 6)
+ v |= 0xff000000;
+
+ *pixel++ = v;
+ }
+
+ pixel += padding;
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+void
+wth_server_weston_shm_attach(struct window *window, uint32_t data_sz, void * data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct timeval tv;
+ uint32_t time;
+ struct shm_buffer *buffer;
+ static int ss_count = 0;
+
+ gettimeofday(&tv, NULL);
+ time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+
+ buffer = window_next_buffer(window);
+ if (!buffer) {
+ wth_error("Both buffers busy at redraw().\n");
+ return;
+ }
+
+ char *bitmap;
+ bitmap = getenv("BITMAP");
+ if (bitmap) {
+ if (!strcmp(bitmap, "1")) {
+ int len;
+ const char *path = "/tmp/bitmap";
+ len = strlen(path);
+ char *filename;
+ filename = (char *)malloc(len + 10);
+ sprintf(filename, "%s%d.bmp", path, ss_count);
+ wth_verbose("%s\n", filename);
+
+ save_as_bitmap(filename, data, data_sz, width, height, format);
+ ss_count++;
+ free(filename);
+ }
+ }
+ buffer->shm_data = data;
+ window->width = width;
+ window->height = height;
+ paint_pixels(buffer->shm_data, 20, window->width, window->height, time);
+
+ wl_surface_attach(window->surface, buffer->buffer, 0, 0);
+
+ buffer->busy = 1;
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+void
+wth_server_weston_shm_damage(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wl_surface_damage(window->surface,
+ 0, 0, window->width, window->height);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+void
+wth_server_weston_shm_commit(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ static const uint32_t benchmark_interval = 5;
+ struct timeval tv;
+ uint32_t time;
+
+ gettimeofday(&tv, NULL);
+ time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+ if (window->window_frames == 0)
+ window->window_benchmark_time = time;
+ if (time - window->window_benchmark_time > (benchmark_interval * 1000)) {
+ wth_verbose("-------------------------------%d frames in %d seconds: %f fps\n",
+ window->window_frames,
+ benchmark_interval,
+ (float) window->window_frames / benchmark_interval);
+
+ window->window_benchmark_time = time;
+ window->window_frames = 0;
+ }
+
+ wl_surface_commit(window->surface);
+
+ wl_display_flush(window->display->display);
+
+ if (window->wait)
+ window->wait = 0;
+
+ window->window_frames++;
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * frame callback function - this function will display buffer to surface
+ */
+
+static const struct wl_callback_listener frame_listener;
+static void
+redraw(void *data, struct wl_callback *callback, uint32_t time)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct window *window = data;
+ struct shm_buffer *buffer;
+
+ buffer = window_next_buffer(window);
+ if (!buffer) {
+ if(!callback)
+ {
+ wth_error("Failed to create the first buffer.\n");
+ }
+ else
+ {
+ wth_error("Both buffers busy at redraw(). Server bug?\n");
+ }
+ abort();
+ }
+
+ paint_pixels(buffer->shm_data, 20, window->width, window->height, time);
+
+ wl_surface_attach(window->surface, buffer->buffer, 0, 0);
+ wl_surface_damage(window->surface,
+ 20, 20, window->width - 40, window->height - 40);
+
+ if (callback)
+ wl_callback_destroy(callback);
+
+ window->callback = wl_surface_frame(window->surface);
+ wl_callback_add_listener(window->callback, &frame_listener, window);
+ wl_surface_commit(window->surface);
+ buffer->busy = 1;
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_callback_listener frame_listener = {
+ redraw
+};
+
+/*
+ * shm callbcak function
+ */
+
+static void
+shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *d = data;
+
+ if (format == WL_SHM_FORMAT_XRGB8888)
+ d->has_xrgb = true;
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+struct wl_shm_listener shm_listener = {
+ shm_format
+};
+
+/*
+ * pointer callbcak functions
+ */
+static void
+pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
+ uint32_t serial, struct wl_surface *wl_surface,
+ wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("data [%p]\n", data);
+
+ struct display *display = data;
+ struct window *window = display->window;
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+
+ waltham_pointer_enter(window, serial, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_leave(void *data, struct wl_pointer *pointer,
+ uint32_t serial, struct wl_surface *surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("data [%p]\n", data);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_leave(window, serial);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_motion(void *data, struct wl_pointer *pointer,
+ uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_motion(window, time, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
+ uint32_t serial, uint32_t time, uint32_t button,
+ uint32_t state)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_button(window, serial, time, button, state);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
+ uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_axis(window, time, axis, value);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+ pointer_handle_enter,
+ pointer_handle_leave,
+ pointer_handle_motion,
+ pointer_handle_button,
+ pointer_handle_axis,
+};
+
+/*
+ * touch callbcak functions
+ */
+
+static void
+touch_handle_down(void *data, struct wl_touch *touch, uint32_t serial,
+ uint32_t time, struct wl_surface *surface, int32_t id,
+ wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ int x = (int)wl_fixed_to_double(x_w);
+ int y = (int)wl_fixed_to_double(y_w);
+ wth_verbose("%p x %d y %d\n",window, x, y);
+
+ waltham_touch_down(window, serial, time, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_up(void *data, struct wl_touch *touch, uint32_t serial,
+ uint32_t time, int32_t id)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_up(window, serial, time, id);
+}
+
+static void
+touch_handle_motion(void *data, struct wl_touch *touch, uint32_t time,
+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_motion(window, time, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_frame(void *data, struct wl_touch *touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_frame(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_cancel(void *data, struct wl_touch *touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_cancel(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_touch_listener touch_listener = {
+ touch_handle_down,
+ touch_handle_up,
+ touch_handle_motion,
+ touch_handle_frame,
+ touch_handle_cancel
+};
+
+/*
+ * seat callback
+ */
+static void
+seat_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+
+ wth_verbose("caps = %d\n", caps);
+
+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !display->wl_pointer)
+ {
+ wth_verbose("WL_SEAT_CAPABILITY_POINTER\n");
+ display->wl_pointer = wl_seat_get_pointer(wl_seat);
+ wl_pointer_set_user_data(display->wl_pointer, display);
+ wl_pointer_add_listener(display->wl_pointer, &pointer_listener, display);
+ wl_display_roundtrip(display->display);
+ } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && display->wl_pointer) {
+ wth_verbose("!WL_SEAT_CAPABILITY_POINTER\n");
+ wl_pointer_destroy(display->wl_pointer);
+ display->wl_pointer = NULL;
+ }
+
+ if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !display->wl_touch)
+ {
+ wth_verbose("WL_SEAT_CAPABILITY_TOUCH\n");
+ display->wl_touch = wl_seat_get_touch(wl_seat);
+ wl_touch_set_user_data(display->wl_touch, display);
+ wl_touch_add_listener(display->wl_touch, &touch_listener, display);
+ wl_display_roundtrip(display->display);
+ } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && display->wl_touch) {
+ wth_verbose("!WL_SEAT_CAPABILITY_TOUCH\n");
+ wl_touch_destroy(display->wl_touch);
+ display->wl_touch = NULL;
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_seat_listener seat_listener = {
+ seat_capabilities,
+ NULL
+};
+
+static void
+add_seat(struct display *display, uint32_t id, uint32_t version)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ display->wl_pointer = NULL;
+ display->seat = wl_registry_bind(display->registry, id,
+ &wl_seat_interface, 1);
+ wl_seat_add_listener(display->seat, &seat_listener, display);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * registry callback
+ */
+static void
+registry_handle_global(void *data, struct wl_registry *registry,
+ uint32_t id, const char *interface, uint32_t version)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *d = data;
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ d->compositor =
+ wl_registry_bind(registry,
+ id, &wl_compositor_interface, 1);
+ } else if (strcmp(interface, "wl_shm") == 0) {
+ d->shm = wl_registry_bind(registry,
+ id, &wl_shm_interface, 1);
+ wl_shm_add_listener(d->shm, &shm_listener, d);
+ } else if (strcmp(interface, "ivi_application") == 0) {
+ d->ivi_application =
+ wl_registry_bind(registry, id,
+ &ivi_application_interface, 1);
+ } else if (strcmp(interface, "wl_seat") == 0) {
+ add_seat(d, id, version);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+ uint32_t name)
+{
+}
+
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ registry_handle_global_remove
+};
+
+static struct display *
+create_display(void)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display;
+
+ display = malloc(sizeof *display);
+ if (display == NULL) {
+ wth_error("out of memory\n");
+ exit(1);
+ }
+ display->display = wl_display_connect(NULL);
+ assert(display->display);
+
+ display->has_xrgb = false;
+ display->registry = wl_display_get_registry(display->display);
+ wl_registry_add_listener(display->registry,
+ &registry_listener, display);
+ wl_display_roundtrip(display->display);
+ if (display->shm == NULL) {
+ wth_error("No wl_shm global\n");
+ exit(1);
+ }
+
+ wl_display_roundtrip(display->display);
+
+ if (!display->has_xrgb) {
+ wth_error("WL_SHM_FORMAT_XRGB32 not available\n");
+ exit(1);
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+ return display;
+}
+
+static void
+destroy_display(struct display *display)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ if (display->shm)
+ wl_shm_destroy(display->shm);
+
+ if (display->compositor)
+ wl_compositor_destroy(display->compositor);
+
+ wl_registry_destroy(display->registry);
+ wl_display_flush(display->display);
+ wl_display_disconnect(display->display);
+ free(display);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+signal_int(int signum)
+{
+ running = 0;
+}
+
+/**
+* wth_server_weston_main
+*
+* This is the main function which will handle connection to the compositor at server side
+*
+* @param names void *data
+* @param value struct window data
+* @return 0 on success, -1 on error
+*/
+int
+wth_server_weston_main(void *data)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct window *window = (struct window *) data;
+ struct sigaction sigint;
+ struct display *display;
+ int ret = 0;
+
+ display = create_display();
+ create_window(window, display, 400, 400);
+ if (!window)
+ return -1;
+ wl_display_roundtrip(display->display);
+ wth_verbose("data %p\n", data);
+ wth_verbose("window %p\n", window);
+
+ display->window = window;
+
+ sigint.sa_handler = signal_int;
+ sigemptyset(&sigint.sa_mask);
+ sigint.sa_flags = SA_RESETHAND;
+ sigaction(SIGINT, &sigint, NULL);
+
+ /* Initialise damage to full surface, so the padding gets painted */
+ wl_surface_damage(window->surface, 0, 0,
+ window->width, window->height);
+
+ redraw(window, NULL, 0);
+
+ window->wait = 1;
+ window->ready = true;
+ while (window->wait)
+ {
+ ret = wl_display_dispatch(display->display);
+ usleep(1);
+ }
+ wth_verbose("debug\n");
+ while (running && ret != -1)
+ ret = wl_display_dispatch(display->display);
+
+ wth_verbose("wth_server_weston_main exiting\n");
+
+ if (window->display->ivi_application) {
+ ivi_surface_destroy(window->ivi_surface);
+ ivi_application_destroy(window->display->ivi_application);
+ }
+
+ destroy_window(window);
+ destroy_display(display);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return 0;
+}
diff --git a/demo3/horizontal/waltham-server/package/receiver/config.xml b/demo3/horizontal/waltham-server/package/receiver/config.xml
new file mode 100644
index 0000000..640108a
--- /dev/null
+++ b/demo3/horizontal/waltham-server/package/receiver/config.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" id="receiver" version="0.1">
+ <name>receiver</name>
+ <icon src="icon.svg"/>
+ <content src="bin/receiver" type="application/vnd.agl.native"/>
+ <description>This is a demo application for waltham-server</description>
+ <author>TOYOA</author>
+ <license>APL 2.0 + MIT</license>
+ <feature name="urn:AGL:widget:required-api">
+ <param name="homescreen" value="ws" />
+ <param name="windowmanager" value="ws" />
+ </feature>
+ <feature name="urn:AGL:widget:required-permission">
+ <param name="urn:AGL:permission::public:no-htdocs" value="required" />
+ <param name="urn:AGL:permission::system:run-by-default" value="required" />
+ </feature>
+</widget>
diff --git a/demo3/horizontal/waltham-server/package/receiver/icon.svg b/demo3/horizontal/waltham-server/package/receiver/icon.svg
new file mode 100644
index 0000000..91661a7
--- /dev/null
+++ b/demo3/horizontal/waltham-server/package/receiver/icon.svg
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:i="&amp;ns_ai;"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 320 320"
+ style="enable-background:new 0 0 320 320;"
+ xml:space="preserve"
+ id="svg2"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="icon.svg"><metadata
+ id="metadata1292"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs1290" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2560"
+ inkscape:window-height="1464"
+ id="namedview1288"
+ showgrid="false"
+ inkscape:zoom="0.7375"
+ inkscape:cx="-572.20339"
+ inkscape:cy="160"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" /><style
+ type="text/css"
+ id="style4">
+ .st0{display:none;}
+ .st1{display:inline;}
+ .st2{opacity:0.4;fill:url(#SVGID_1_);}
+ .st3{fill:url(#SVGID_2_);}
+ .st4{fill:#FFFFFF;}
+ .st5{font-family:'Roboto-Regular';}
+ .st6{font-size:25px;}
+ .st7{letter-spacing:6;}
+ .st8{fill:url(#SVGID_3_);}
+ .st9{fill:url(#SVGID_4_);}
+ .st10{fill:url(#SVGID_5_);}
+ .st11{fill:url(#SVGID_6_);}
+ .st12{fill:url(#SVGID_7_);}
+ .st13{fill:url(#SVGID_8_);}
+ .st14{fill:url(#SVGID_9_);}
+ .st15{fill:url(#SVGID_10_);}
+ .st16{fill:url(#SVGID_11_);}
+ .st17{fill:url(#SVGID_12_);}
+ .st18{fill:url(#SVGID_13_);}
+ .st19{fill:url(#SVGID_14_);}
+ .st20{fill:url(#SVGID_15_);}
+ .st21{fill:url(#SVGID_16_);}
+ .st22{fill:url(#SVGID_17_);}
+ .st23{fill:url(#SVGID_18_);}
+ .st24{opacity:0.29;}
+ .st25{fill:url(#SVGID_19_);}
+ .st26{fill:url(#SVGID_20_);}
+ .st27{fill:url(#SVGID_21_);}
+ .st28{fill:url(#SVGID_22_);}
+ .st29{fill:url(#SVGID_23_);}
+ .st30{fill:url(#SVGID_24_);}
+ .st31{fill:url(#SVGID_25_);}
+ .st32{fill:url(#SVGID_26_);}
+ .st33{fill:url(#SVGID_27_);}
+ .st34{fill:url(#SVGID_28_);}
+ .st35{fill:url(#SVGID_29_);}
+ .st36{fill:url(#SVGID_30_);}
+ .st37{fill:url(#SVGID_31_);}
+ .st38{fill:url(#SVGID_32_);}
+ .st39{fill:url(#SVGID_33_);}
+ .st40{fill:url(#SVGID_34_);}
+ .st41{fill:url(#SVGID_35_);}
+ .st42{fill:url(#SVGID_36_);}
+ .st43{opacity:0.4;fill:url(#SVGID_37_);}
+ .st44{fill:url(#SVGID_38_);}
+ .st45{fill:url(#SVGID_39_);}
+ .st46{fill:url(#SVGID_40_);}
+ .st47{fill:url(#SVGID_41_);}
+ .st48{fill:url(#SVGID_42_);}
+ .st49{fill:url(#SVGID_43_);}
+ .st50{fill:url(#SVGID_44_);}
+ .st51{display:inline;opacity:0.29;}
+ .st52{display:inline;fill:url(#SVGID_45_);}
+ .st53{display:inline;fill:url(#SVGID_46_);}
+ .st54{display:inline;fill:#FFFFFF;}
+ .st55{display:inline;fill:url(#SVGID_47_);}
+ .st56{display:inline;fill:url(#SVGID_48_);}
+ .st57{display:inline;fill:url(#SVGID_49_);}
+ .st58{display:inline;fill:url(#SVGID_50_);}
+ .st59{display:inline;fill:url(#SVGID_51_);}
+ .st60{display:inline;fill:url(#SVGID_52_);}
+ .st61{opacity:0.4;fill:url(#SVGID_53_);}
+ .st62{fill:url(#SVGID_54_);}
+ .st63{fill:url(#SVGID_55_);}
+ .st64{fill:url(#SVGID_56_);}
+ .st65{fill:url(#SVGID_57_);}
+ .st66{fill:url(#SVGID_58_);}
+ .st67{opacity:0.4;fill:url(#SVGID_59_);}
+ .st68{fill:url(#SVGID_60_);}
+ .st69{fill:url(#SVGID_61_);}
+ .st70{fill:url(#SVGID_62_);}
+ .st71{fill:url(#SVGID_63_);}
+ .st72{fill:url(#SVGID_64_);}
+ .st73{fill:url(#SVGID_65_);}
+ .st74{fill:url(#SVGID_66_);}
+ .st75{fill:url(#SVGID_67_);}
+ .st76{fill:url(#SVGID_68_);}
+ .st77{fill:url(#SVGID_69_);}
+ .st78{fill:url(#SVGID_70_);}
+ .st79{fill:url(#SVGID_71_);}
+ .st80{fill:url(#SVGID_72_);}
+ .st81{fill:url(#SVGID_73_);}
+ .st82{fill:url(#SVGID_74_);}
+ .st83{fill:url(#SVGID_75_);}
+ .st84{fill:url(#SVGID_76_);}
+ .st85{fill:url(#SVGID_77_);}
+ .st86{fill:url(#SVGID_78_);}
+ .st87{fill:url(#SVGID_79_);}
+ .st88{fill:url(#SVGID_80_);}
+ .st89{fill:url(#SVGID_81_);}
+ .st90{fill:url(#SVGID_82_);}
+ .st91{fill:url(#SVGID_83_);}
+ .st92{fill:url(#SVGID_84_);}
+ .st93{fill:url(#SVGID_85_);}
+ .st94{fill:url(#SVGID_86_);}
+ .st95{opacity:0.4;fill:url(#SVGID_87_);}
+ .st96{fill:url(#SVGID_88_);}
+ .st97{fill:url(#SVGID_89_);}
+ .st98{fill:url(#SVGID_90_);}
+ .st99{fill:url(#SVGID_91_);}
+ .st100{fill:url(#SVGID_92_);}
+ .st101{fill:url(#SVGID_93_);}
+ .st102{fill:url(#SVGID_94_);}
+ .st103{opacity:0.4;fill:url(#SVGID_95_);}
+ .st104{fill:url(#SVGID_96_);}
+ .st105{fill:url(#SVGID_97_);}
+ .st106{fill:url(#SVGID_98_);}
+ .st107{fill:url(#SVGID_99_);}
+ .st108{fill:url(#SVGID_100_);}
+ .st109{fill:url(#SVGID_101_);}
+ .st110{display:inline;fill:url(#SVGID_102_);}
+ .st111{display:inline;fill:url(#SVGID_103_);}
+ .st112{fill:url(#SVGID_104_);}
+ .st113{fill:url(#SVGID_105_);}
+ .st114{fill:url(#SVGID_106_);}
+ .st115{fill:url(#SVGID_107_);}
+ .st116{fill:url(#SVGID_108_);}
+ .st117{opacity:0.4;fill:url(#SVGID_109_);}
+ .st118{fill:url(#SVGID_110_);}
+ .st119{fill:url(#SVGID_111_);}
+ .st120{fill:url(#SVGID_112_);}
+ .st121{fill:url(#SVGID_113_);}
+ .st122{fill:url(#SVGID_114_);}
+ .st123{opacity:0.4;fill:url(#SVGID_115_);}
+ .st124{fill:url(#SVGID_116_);}
+ .st125{fill:url(#SVGID_117_);}
+ .st126{fill:url(#SVGID_118_);}
+ .st127{display:inline;fill:url(#SVGID_119_);}
+ .st128{display:inline;fill:url(#SVGID_120_);}
+ .st129{fill:url(#SVGID_121_);}
+ .st130{fill:url(#SVGID_122_);}
+</style><switch
+ id="switch6"><g
+ i:extraneous="self"
+ id="g8"><g
+ id="Multimedia_Inactive_copy"><circle
+ class="st24"
+ cx="159.7"
+ cy="133.4"
+ r="101.9"
+ id="circle884" /><linearGradient
+ id="SVGID_91_"
+ gradientUnits="userSpaceOnUse"
+ x1="115.9317"
+ y1="254.1836"
+ x2="256.3852"
+ y2="-133.5267"><stop
+ offset="0"
+ style="stop-color:#8BC53F"
+ id="stop887" /><stop
+ offset="2.015080e-02"
+ style="stop-color:#7CCB56;stop-opacity:0.9678"
+ id="stop889" /><stop
+ offset="6.089833e-02"
+ style="stop-color:#62D67D;stop-opacity:0.9028"
+ id="stop891" /><stop
+ offset="0.1057"
+ style="stop-color:#4BDFA0;stop-opacity:0.8312"
+ id="stop893" /><stop
+ offset="0.1543"
+ style="stop-color:#38E7BE;stop-opacity:0.7537"
+ id="stop895" /><stop
+ offset="0.2077"
+ style="stop-color:#28EED6;stop-opacity:0.6684"
+ id="stop897" /><stop
+ offset="0.2681"
+ style="stop-color:#1CF3E8;stop-opacity:0.572"
+ id="stop899" /><stop
+ offset="0.3394"
+ style="stop-color:#13F6F5;stop-opacity:0.4581"
+ id="stop901" /><stop
+ offset="0.4323"
+ style="stop-color:#0EF8FD;stop-opacity:0.3098"
+ id="stop903" /><stop
+ offset="0.6264"
+ style="stop-color:#0DF9FF;stop-opacity:0"
+ id="stop905" /></linearGradient><circle
+ class="st99"
+ cx="159.7"
+ cy="133.4"
+ r="101.9"
+ id="circle907" /><linearGradient
+ id="SVGID_92_"
+ gradientUnits="userSpaceOnUse"
+ x1="4.0481"
+ y1="287.9492"
+ x2="320.4859"
+ y2="-15.4029"
+ gradientTransform="matrix(1 5.464556e-03 -5.464556e-03 1 -2.0192 -3.0212)"><stop
+ offset="0"
+ style="stop-color:#59FF7F"
+ id="stop910" /><stop
+ offset="1"
+ style="stop-color:#6BFBFF"
+ id="stop912" /></linearGradient><path
+ class="st100"
+ d="M160,238.8c-0.2,0-0.4,0-0.6,0c-58-0.3-104.9-47.7-104.6-105.7C55.2,75.3,102.3,28.5,160,28.5 c0.2,0,0.4,0,0.6,0c58,0.3,104.9,47.7,104.6,105.7l0,0C264.8,192,217.7,238.8,160,238.8z M160,32.2 c-55.7,0-101.2,45.2-101.5,100.9c-0.3,55.9,45,101.7,100.9,102c0.2,0,0.4,0,0.6,0c55.7,0,101.2-45.2,101.5-100.9 c0.3-55.9-45-101.7-100.9-102C160.4,32.2,160.2,32.2,160,32.2z"
+ id="path914" /><g
+ id="g916"><text
+ transform="matrix(1 0 0 1 53.5841 284.7119)"
+ class="st4 st5 st6 st7"
+ id="text918">MULTIMEDIA</text>
+<linearGradient
+ id="SVGID_93_"
+ gradientUnits="userSpaceOnUse"
+ x1="140.5445"
+ y1="202.2363"
+ x2="186.8444"
+ y2="68.7049"><stop
+ offset="0"
+ style="stop-color:#59FF7F"
+ id="stop921" /><stop
+ offset="1"
+ style="stop-color:#6BFBFF"
+ id="stop923" /></linearGradient><path
+ class="st101"
+ d="M114.5,190.9c-6.4,0-12-2.6-14.8-7.5c-2.9-4.9-5.4-14.5,9.6-23.2c4.8-2.8,17.1-3.9,20.8-4l0.1,3.6 c-4.6,0.1-15.5,1.4-19.1,3.5c-9.4,5.4-12.1,11.5-8.3,18.3c3.8,6.6,14.6,7.6,24,2.2c6.6-3.8,10.6-10.5,10.7-17.9l-0.1-0.7V95.4 l71.9-14.2l0.1,71.3c0,6.7-3.3,16.4-12.5,21.8c-11.1,6.4-24.1,4.8-28.9-3.5c-2.9-4.9-5.4-14.5,9.6-23.2 c4.4-2.5,14.4-3.8,18.8-3.9l0.1,3.6c-4.2,0.1-13.5,1.4-17.1,3.5c-6.4,3.7-13.1,9.9-8.3,18.3c3.8,6.6,14.6,7.6,24,2.2 c7.9-4.5,10.7-12.8,10.7-18.5l-0.1-0.8V85.6l-64.7,12.7v66.8l0.1,0.7c0,8.7-4.7,16.6-12.5,21.1 C123.9,189.6,119,190.9,114.5,190.9z"
+ id="path925" /><linearGradient
+ id="SVGID_94_"
+ gradientUnits="userSpaceOnUse"
+ x1="145.3286"
+ y1="203.8951"
+ x2="191.6285"
+ y2="70.3637"><stop
+ offset="0"
+ style="stop-color:#59FF7F"
+ id="stop928" /><stop
+ offset="1"
+ style="stop-color:#6BFBFF"
+ id="stop930" /></linearGradient><polygon
+ class="st102"
+ points="155.6,123.3 154.8,119.8 195.5,110.2 196.3,113.7 "
+ id="polygon932" /></g></g></g></switch></svg> \ No newline at end of file
diff --git a/demo3/horizontal/waltham-server/package/root/config.xml b/demo3/horizontal/waltham-server/package/root/config.xml
new file mode 100644
index 0000000..41f49ca
--- /dev/null
+++ b/demo3/horizontal/waltham-server/package/root/config.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" id="waltham-server" version="0.1">
+ <name>WALTHAM-SERVER</name>
+ <icon src="icon.svg"/>
+ <content src="bin/waltham-server" type="application/vnd.agl.native"/>
+ <description>This is a demo application for waltham-server</description>
+ <author>TOYOA</author>
+ <license>APL 2.0 + MIT</license>
+ <feature name="urn:AGL:widget:required-api">
+ <param name="homescreen" value="ws" />
+ <param name="windowmanager" value="ws" />
+ </feature>
+ <feature name="urn:AGL:widget:required-permission">
+ <param name="urn:AGL:permission::public:no-htdocs" value="required" />
+ <param name="urn:AGL:permission::system:run-by-default" value="required" />
+ </feature>
+</widget>
diff --git a/demo3/horizontal/waltham-server/package/root/icon.svg b/demo3/horizontal/waltham-server/package/root/icon.svg
new file mode 100644
index 0000000..91661a7
--- /dev/null
+++ b/demo3/horizontal/waltham-server/package/root/icon.svg
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:i="&amp;ns_ai;"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 320 320"
+ style="enable-background:new 0 0 320 320;"
+ xml:space="preserve"
+ id="svg2"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="icon.svg"><metadata
+ id="metadata1292"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs1290" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2560"
+ inkscape:window-height="1464"
+ id="namedview1288"
+ showgrid="false"
+ inkscape:zoom="0.7375"
+ inkscape:cx="-572.20339"
+ inkscape:cy="160"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" /><style
+ type="text/css"
+ id="style4">
+ .st0{display:none;}
+ .st1{display:inline;}
+ .st2{opacity:0.4;fill:url(#SVGID_1_);}
+ .st3{fill:url(#SVGID_2_);}
+ .st4{fill:#FFFFFF;}
+ .st5{font-family:'Roboto-Regular';}
+ .st6{font-size:25px;}
+ .st7{letter-spacing:6;}
+ .st8{fill:url(#SVGID_3_);}
+ .st9{fill:url(#SVGID_4_);}
+ .st10{fill:url(#SVGID_5_);}
+ .st11{fill:url(#SVGID_6_);}
+ .st12{fill:url(#SVGID_7_);}
+ .st13{fill:url(#SVGID_8_);}
+ .st14{fill:url(#SVGID_9_);}
+ .st15{fill:url(#SVGID_10_);}
+ .st16{fill:url(#SVGID_11_);}
+ .st17{fill:url(#SVGID_12_);}
+ .st18{fill:url(#SVGID_13_);}
+ .st19{fill:url(#SVGID_14_);}
+ .st20{fill:url(#SVGID_15_);}
+ .st21{fill:url(#SVGID_16_);}
+ .st22{fill:url(#SVGID_17_);}
+ .st23{fill:url(#SVGID_18_);}
+ .st24{opacity:0.29;}
+ .st25{fill:url(#SVGID_19_);}
+ .st26{fill:url(#SVGID_20_);}
+ .st27{fill:url(#SVGID_21_);}
+ .st28{fill:url(#SVGID_22_);}
+ .st29{fill:url(#SVGID_23_);}
+ .st30{fill:url(#SVGID_24_);}
+ .st31{fill:url(#SVGID_25_);}
+ .st32{fill:url(#SVGID_26_);}
+ .st33{fill:url(#SVGID_27_);}
+ .st34{fill:url(#SVGID_28_);}
+ .st35{fill:url(#SVGID_29_);}
+ .st36{fill:url(#SVGID_30_);}
+ .st37{fill:url(#SVGID_31_);}
+ .st38{fill:url(#SVGID_32_);}
+ .st39{fill:url(#SVGID_33_);}
+ .st40{fill:url(#SVGID_34_);}
+ .st41{fill:url(#SVGID_35_);}
+ .st42{fill:url(#SVGID_36_);}
+ .st43{opacity:0.4;fill:url(#SVGID_37_);}
+ .st44{fill:url(#SVGID_38_);}
+ .st45{fill:url(#SVGID_39_);}
+ .st46{fill:url(#SVGID_40_);}
+ .st47{fill:url(#SVGID_41_);}
+ .st48{fill:url(#SVGID_42_);}
+ .st49{fill:url(#SVGID_43_);}
+ .st50{fill:url(#SVGID_44_);}
+ .st51{display:inline;opacity:0.29;}
+ .st52{display:inline;fill:url(#SVGID_45_);}
+ .st53{display:inline;fill:url(#SVGID_46_);}
+ .st54{display:inline;fill:#FFFFFF;}
+ .st55{display:inline;fill:url(#SVGID_47_);}
+ .st56{display:inline;fill:url(#SVGID_48_);}
+ .st57{display:inline;fill:url(#SVGID_49_);}
+ .st58{display:inline;fill:url(#SVGID_50_);}
+ .st59{display:inline;fill:url(#SVGID_51_);}
+ .st60{display:inline;fill:url(#SVGID_52_);}
+ .st61{opacity:0.4;fill:url(#SVGID_53_);}
+ .st62{fill:url(#SVGID_54_);}
+ .st63{fill:url(#SVGID_55_);}
+ .st64{fill:url(#SVGID_56_);}
+ .st65{fill:url(#SVGID_57_);}
+ .st66{fill:url(#SVGID_58_);}
+ .st67{opacity:0.4;fill:url(#SVGID_59_);}
+ .st68{fill:url(#SVGID_60_);}
+ .st69{fill:url(#SVGID_61_);}
+ .st70{fill:url(#SVGID_62_);}
+ .st71{fill:url(#SVGID_63_);}
+ .st72{fill:url(#SVGID_64_);}
+ .st73{fill:url(#SVGID_65_);}
+ .st74{fill:url(#SVGID_66_);}
+ .st75{fill:url(#SVGID_67_);}
+ .st76{fill:url(#SVGID_68_);}
+ .st77{fill:url(#SVGID_69_);}
+ .st78{fill:url(#SVGID_70_);}
+ .st79{fill:url(#SVGID_71_);}
+ .st80{fill:url(#SVGID_72_);}
+ .st81{fill:url(#SVGID_73_);}
+ .st82{fill:url(#SVGID_74_);}
+ .st83{fill:url(#SVGID_75_);}
+ .st84{fill:url(#SVGID_76_);}
+ .st85{fill:url(#SVGID_77_);}
+ .st86{fill:url(#SVGID_78_);}
+ .st87{fill:url(#SVGID_79_);}
+ .st88{fill:url(#SVGID_80_);}
+ .st89{fill:url(#SVGID_81_);}
+ .st90{fill:url(#SVGID_82_);}
+ .st91{fill:url(#SVGID_83_);}
+ .st92{fill:url(#SVGID_84_);}
+ .st93{fill:url(#SVGID_85_);}
+ .st94{fill:url(#SVGID_86_);}
+ .st95{opacity:0.4;fill:url(#SVGID_87_);}
+ .st96{fill:url(#SVGID_88_);}
+ .st97{fill:url(#SVGID_89_);}
+ .st98{fill:url(#SVGID_90_);}
+ .st99{fill:url(#SVGID_91_);}
+ .st100{fill:url(#SVGID_92_);}
+ .st101{fill:url(#SVGID_93_);}
+ .st102{fill:url(#SVGID_94_);}
+ .st103{opacity:0.4;fill:url(#SVGID_95_);}
+ .st104{fill:url(#SVGID_96_);}
+ .st105{fill:url(#SVGID_97_);}
+ .st106{fill:url(#SVGID_98_);}
+ .st107{fill:url(#SVGID_99_);}
+ .st108{fill:url(#SVGID_100_);}
+ .st109{fill:url(#SVGID_101_);}
+ .st110{display:inline;fill:url(#SVGID_102_);}
+ .st111{display:inline;fill:url(#SVGID_103_);}
+ .st112{fill:url(#SVGID_104_);}
+ .st113{fill:url(#SVGID_105_);}
+ .st114{fill:url(#SVGID_106_);}
+ .st115{fill:url(#SVGID_107_);}
+ .st116{fill:url(#SVGID_108_);}
+ .st117{opacity:0.4;fill:url(#SVGID_109_);}
+ .st118{fill:url(#SVGID_110_);}
+ .st119{fill:url(#SVGID_111_);}
+ .st120{fill:url(#SVGID_112_);}
+ .st121{fill:url(#SVGID_113_);}
+ .st122{fill:url(#SVGID_114_);}
+ .st123{opacity:0.4;fill:url(#SVGID_115_);}
+ .st124{fill:url(#SVGID_116_);}
+ .st125{fill:url(#SVGID_117_);}
+ .st126{fill:url(#SVGID_118_);}
+ .st127{display:inline;fill:url(#SVGID_119_);}
+ .st128{display:inline;fill:url(#SVGID_120_);}
+ .st129{fill:url(#SVGID_121_);}
+ .st130{fill:url(#SVGID_122_);}
+</style><switch
+ id="switch6"><g
+ i:extraneous="self"
+ id="g8"><g
+ id="Multimedia_Inactive_copy"><circle
+ class="st24"
+ cx="159.7"
+ cy="133.4"
+ r="101.9"
+ id="circle884" /><linearGradient
+ id="SVGID_91_"
+ gradientUnits="userSpaceOnUse"
+ x1="115.9317"
+ y1="254.1836"
+ x2="256.3852"
+ y2="-133.5267"><stop
+ offset="0"
+ style="stop-color:#8BC53F"
+ id="stop887" /><stop
+ offset="2.015080e-02"
+ style="stop-color:#7CCB56;stop-opacity:0.9678"
+ id="stop889" /><stop
+ offset="6.089833e-02"
+ style="stop-color:#62D67D;stop-opacity:0.9028"
+ id="stop891" /><stop
+ offset="0.1057"
+ style="stop-color:#4BDFA0;stop-opacity:0.8312"
+ id="stop893" /><stop
+ offset="0.1543"
+ style="stop-color:#38E7BE;stop-opacity:0.7537"
+ id="stop895" /><stop
+ offset="0.2077"
+ style="stop-color:#28EED6;stop-opacity:0.6684"
+ id="stop897" /><stop
+ offset="0.2681"
+ style="stop-color:#1CF3E8;stop-opacity:0.572"
+ id="stop899" /><stop
+ offset="0.3394"
+ style="stop-color:#13F6F5;stop-opacity:0.4581"
+ id="stop901" /><stop
+ offset="0.4323"
+ style="stop-color:#0EF8FD;stop-opacity:0.3098"
+ id="stop903" /><stop
+ offset="0.6264"
+ style="stop-color:#0DF9FF;stop-opacity:0"
+ id="stop905" /></linearGradient><circle
+ class="st99"
+ cx="159.7"
+ cy="133.4"
+ r="101.9"
+ id="circle907" /><linearGradient
+ id="SVGID_92_"
+ gradientUnits="userSpaceOnUse"
+ x1="4.0481"
+ y1="287.9492"
+ x2="320.4859"
+ y2="-15.4029"
+ gradientTransform="matrix(1 5.464556e-03 -5.464556e-03 1 -2.0192 -3.0212)"><stop
+ offset="0"
+ style="stop-color:#59FF7F"
+ id="stop910" /><stop
+ offset="1"
+ style="stop-color:#6BFBFF"
+ id="stop912" /></linearGradient><path
+ class="st100"
+ d="M160,238.8c-0.2,0-0.4,0-0.6,0c-58-0.3-104.9-47.7-104.6-105.7C55.2,75.3,102.3,28.5,160,28.5 c0.2,0,0.4,0,0.6,0c58,0.3,104.9,47.7,104.6,105.7l0,0C264.8,192,217.7,238.8,160,238.8z M160,32.2 c-55.7,0-101.2,45.2-101.5,100.9c-0.3,55.9,45,101.7,100.9,102c0.2,0,0.4,0,0.6,0c55.7,0,101.2-45.2,101.5-100.9 c0.3-55.9-45-101.7-100.9-102C160.4,32.2,160.2,32.2,160,32.2z"
+ id="path914" /><g
+ id="g916"><text
+ transform="matrix(1 0 0 1 53.5841 284.7119)"
+ class="st4 st5 st6 st7"
+ id="text918">MULTIMEDIA</text>
+<linearGradient
+ id="SVGID_93_"
+ gradientUnits="userSpaceOnUse"
+ x1="140.5445"
+ y1="202.2363"
+ x2="186.8444"
+ y2="68.7049"><stop
+ offset="0"
+ style="stop-color:#59FF7F"
+ id="stop921" /><stop
+ offset="1"
+ style="stop-color:#6BFBFF"
+ id="stop923" /></linearGradient><path
+ class="st101"
+ d="M114.5,190.9c-6.4,0-12-2.6-14.8-7.5c-2.9-4.9-5.4-14.5,9.6-23.2c4.8-2.8,17.1-3.9,20.8-4l0.1,3.6 c-4.6,0.1-15.5,1.4-19.1,3.5c-9.4,5.4-12.1,11.5-8.3,18.3c3.8,6.6,14.6,7.6,24,2.2c6.6-3.8,10.6-10.5,10.7-17.9l-0.1-0.7V95.4 l71.9-14.2l0.1,71.3c0,6.7-3.3,16.4-12.5,21.8c-11.1,6.4-24.1,4.8-28.9-3.5c-2.9-4.9-5.4-14.5,9.6-23.2 c4.4-2.5,14.4-3.8,18.8-3.9l0.1,3.6c-4.2,0.1-13.5,1.4-17.1,3.5c-6.4,3.7-13.1,9.9-8.3,18.3c3.8,6.6,14.6,7.6,24,2.2 c7.9-4.5,10.7-12.8,10.7-18.5l-0.1-0.8V85.6l-64.7,12.7v66.8l0.1,0.7c0,8.7-4.7,16.6-12.5,21.1 C123.9,189.6,119,190.9,114.5,190.9z"
+ id="path925" /><linearGradient
+ id="SVGID_94_"
+ gradientUnits="userSpaceOnUse"
+ x1="145.3286"
+ y1="203.8951"
+ x2="191.6285"
+ y2="70.3637"><stop
+ offset="0"
+ style="stop-color:#59FF7F"
+ id="stop928" /><stop
+ offset="1"
+ style="stop-color:#6BFBFF"
+ id="stop930" /></linearGradient><polygon
+ class="st102"
+ points="155.6,123.3 154.8,119.8 195.5,110.2 196.3,113.7 "
+ id="polygon932" /></g></g></g></switch></svg> \ No newline at end of file
diff --git a/demo3/horizontal/waltham-server/protocol/ivi-application.xml b/demo3/horizontal/waltham-server/protocol/ivi-application.xml
new file mode 100644
index 0000000..78e2569
--- /dev/null
+++ b/demo3/horizontal/waltham-server/protocol/ivi-application.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="ivi_application">
+
+ <copyright>
+ Copyright (C) 2013 DENSO CORPORATION
+ Copyright (c) 2013 BMW Car IT GmbH
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice (including the next
+ paragraph) shall be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ </copyright>
+
+ <interface name="ivi_surface" version="1">
+ <description summary="application interface to surface in ivi compositor"/>
+
+ <request name="destroy" type="destructor">
+ <description summary="destroy ivi_surface">
+ This removes link from ivi_id to wl_surface and destroys ivi_surface.
+ The ID, ivi_id, is free and can be used for surface_create again.
+ </description>
+ </request>
+
+ <event name="configure">
+ <description summary="suggest resize">
+ The configure event asks the client to resize its surface.
+
+ The size is a hint, in the sense that the client is free to
+ ignore it if it doesn't resize, pick a smaller size (to
+ satisfy aspect ratio or resize in steps of NxM pixels).
+
+ The client is free to dismiss all but the last configure
+ event it received.
+
+ The width and height arguments specify the size of the window
+ in surface-local coordinates.
+ </description>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ </event>
+ </interface>
+
+ <interface name="ivi_application" version="1">
+ <description summary="create ivi-style surfaces">
+ This interface is exposed as a global singleton.
+ This interface is implemented by servers that provide IVI-style user interfaces.
+ It allows clients to associate a ivi_surface with wl_surface.
+ </description>
+
+ <enum name="error">
+ <entry name="role" value="0" summary="given wl_surface has another role"/>
+ <entry name="ivi_id" value="1" summary="given ivi_id is assigned to another wl_surface"/>
+ </enum>
+
+ <request name="surface_create">
+ <description summary="create ivi_surface with numeric ID in ivi compositor">
+ This request gives the wl_surface the role of an IVI Surface. Creating more than
+ one ivi_surface for a wl_surface is not allowed. Note, that this still allows the
+ following example:
+
+ 1. create a wl_surface
+ 2. create ivi_surface for the wl_surface
+ 3. destroy the ivi_surface
+ 4. create ivi_surface for the wl_surface (with the same or another ivi_id as before)
+
+ surface_create will create a interface:ivi_surface with numeric ID; ivi_id in
+ ivi compositor. These ivi_ids are defined as unique in the system to identify
+ it inside of ivi compositor. The ivi compositor implements business logic how to
+ set properties of the surface with ivi_id according to status of the system.
+ E.g. a unique ID for Car Navigation application is used for implementing special
+ logic of the application about where it shall be located.
+ The server regards following cases as protocol errors and disconnects the client.
+ - wl_surface already has an nother role.
+ - ivi_id is already assigned to an another wl_surface.
+
+ If client destroys ivi_surface or wl_surface which is assigne to the ivi_surface,
+ ivi_id which is assigned to the ivi_surface is free for reuse.
+ </description>
+ <arg name="ivi_id" type="uint"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="id" type="new_id" interface="ivi_surface"/>
+ </request>
+
+ </interface>
+
+</protocol>
diff --git a/demo3/horizontal/waltham-server/screenshot/waltham-server.png b/demo3/horizontal/waltham-server/screenshot/waltham-server.png
new file mode 100644
index 0000000..75b892c
--- /dev/null
+++ b/demo3/horizontal/waltham-server/screenshot/waltham-server.png
Binary files differ
diff --git a/demo3/horizontal/waltham-server/src/utils/bitmap.c b/demo3/horizontal/waltham-server/src/utils/bitmap.c
new file mode 100644
index 0000000..2c7fdb5
--- /dev/null
+++ b/demo3/horizontal/waltham-server/src/utils/bitmap.c
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+#include "bitmap.h"
+#include <stdio.h>
+
+struct __attribute__ ((__packed__)) BITMAPFILEHEADER {
+ char bfType[2];
+ uint32_t bfSize;
+ uint16_t bfReserved1;
+ uint16_t bfReserved2;
+ uint32_t bfOffBits;
+};
+
+struct __attribute__ ((__packed__)) BITMAPINFOHEADER {
+ uint32_t biSize;
+ uint32_t biWidth;
+ uint32_t biHeight;
+ uint16_t biPlanes;
+ uint16_t biBitCount;
+ uint32_t biCompression;
+ uint32_t biSizeImage;
+ uint32_t biXPixPerMeter;
+ uint32_t biYPixPerMeter;
+ uint32_t biClrUsed;
+ uint32_t biClrImporant;
+};
+
+static void
+create_file_header(struct BITMAPFILEHEADER *file_header, int32_t image_size)
+{
+ file_header->bfType[0] = 'B';
+ file_header->bfType[1] = 'M';
+ file_header->bfSize = sizeof(struct BITMAPFILEHEADER)
+ + sizeof(struct BITMAPINFOHEADER)
+ + image_size;
+ file_header->bfOffBits = sizeof(struct BITMAPFILEHEADER)
+ + sizeof(struct BITMAPINFOHEADER);
+}
+
+static void
+create_info_header(struct BITMAPINFOHEADER *info_header, int32_t image_size, int32_t width, int32_t height, int16_t bpp)
+{
+ info_header->biSize = sizeof(struct BITMAPINFOHEADER);
+ info_header->biWidth = width;
+ info_header->biHeight = height;
+ info_header->biPlanes = 1;
+ info_header->biBitCount = bpp;
+ info_header->biSizeImage = image_size;
+}
+
+static int
+write_bitmap(const char *filename,
+ const struct BITMAPFILEHEADER *file_header,
+ const struct BITMAPINFOHEADER *info_header,
+ const char *buffer)
+{
+ FILE *fp = fopen(filename, "w");
+ if (fp == NULL) {
+ return -1;
+ }
+
+ fwrite(file_header, sizeof(struct BITMAPFILEHEADER), 1, fp);
+ fwrite(info_header, sizeof(struct BITMAPINFOHEADER), 1, fp);
+ fwrite(buffer, info_header->biSizeImage, 1, fp);
+
+ fclose(fp);
+ return 0;
+}
+
+int
+save_as_bitmap(const char *filename,
+ const char *buffer,
+ int32_t image_size,
+ int32_t width,
+ int32_t height,
+ int16_t bpp)
+{
+ if ((filename == NULL) || (buffer == NULL)) {
+ return -1;
+ }
+
+ struct BITMAPFILEHEADER file_header = {};
+ struct BITMAPINFOHEADER info_header = {};
+
+ create_file_header(&file_header, image_size);
+ create_info_header(&info_header, image_size, width, height, bpp);
+ return write_bitmap(filename, &file_header, &info_header, buffer);
+}
diff --git a/demo3/horizontal/waltham-server/src/utils/os-compatibility.c b/demo3/horizontal/waltham-server/src/utils/os-compatibility.c
new file mode 100644
index 0000000..d9502e5
--- /dev/null
+++ b/demo3/horizontal/waltham-server/src/utils/os-compatibility.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright © 2012 Collabora, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/epoll.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "os-compatibility.h"
+
+int
+os_fd_set_cloexec(int fd)
+{
+ long flags;
+
+ if (fd == -1)
+ return -1;
+
+ flags = fcntl(fd, F_GETFD);
+ if (flags == -1)
+ return -1;
+
+ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
+ return -1;
+
+ return 0;
+}
+
+static int
+set_cloexec_or_close(int fd)
+{
+ if (os_fd_set_cloexec(fd) != 0) {
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+int
+os_socketpair_cloexec(int domain, int type, int protocol, int *sv)
+{
+ int ret;
+
+#ifdef SOCK_CLOEXEC
+ ret = socketpair(domain, type | SOCK_CLOEXEC, protocol, sv);
+ if (ret == 0 || errno != EINVAL)
+ return ret;
+#endif
+
+ ret = socketpair(domain, type, protocol, sv);
+ if (ret < 0)
+ return ret;
+
+ sv[0] = set_cloexec_or_close(sv[0]);
+ sv[1] = set_cloexec_or_close(sv[1]);
+
+ if (sv[0] != -1 && sv[1] != -1)
+ return 0;
+
+ close(sv[0]);
+ close(sv[1]);
+ return -1;
+}
+
+int
+os_epoll_create_cloexec(void)
+{
+ int fd;
+
+#ifdef EPOLL_CLOEXEC
+ fd = epoll_create1(EPOLL_CLOEXEC);
+ if (fd >= 0)
+ return fd;
+ if (errno != EINVAL)
+ return -1;
+#endif
+
+ fd = epoll_create(1);
+ return set_cloexec_or_close(fd);
+}
+
+static int
+create_tmpfile_cloexec(char *tmpname)
+{
+ int fd;
+
+#ifdef HAVE_MKOSTEMP
+ fd = mkostemp(tmpname, O_CLOEXEC);
+ if (fd >= 0)
+ unlink(tmpname);
+#else
+ fd = mkstemp(tmpname);
+ if (fd >= 0) {
+ fd = set_cloexec_or_close(fd);
+ unlink(tmpname);
+ }
+#endif
+
+ return fd;
+}
+
+/*
+ * Create a new, unique, anonymous file of the given size, and
+ * return the file descriptor for it. The file descriptor is set
+ * CLOEXEC. The file is immediately suitable for mmap()'ing
+ * the given size at offset zero.
+ *
+ * The file should not have a permanent backing store like a disk,
+ * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
+ *
+ * The file name is deleted from the file system.
+ *
+ * The file is suitable for buffer sharing between processes by
+ * transmitting the file descriptor over Unix sockets using the
+ * SCM_RIGHTS methods.
+ *
+ * If the C library implements posix_fallocate(), it is used to
+ * guarantee that disk space is available for the file at the
+ * given size. If disk space is insufficent, errno is set to ENOSPC.
+ * If posix_fallocate() is not supported, program may receive
+ * SIGBUS on accessing mmap()'ed file contents instead.
+ */
+int
+os_create_anonymous_file(off_t size)
+{
+ static const char template[] = "/weston-shared-XXXXXX";
+ const char *path;
+ char *name;
+ int fd;
+ int ret;
+
+ path = getenv("XDG_RUNTIME_DIR");
+ if (!path) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ name = malloc(strlen(path) + sizeof(template));
+ if (!name)
+ return -1;
+
+ strcpy(name, path);
+ strcat(name, template);
+
+ fd = create_tmpfile_cloexec(name);
+
+ free(name);
+
+ if (fd < 0)
+ return -1;
+
+#ifdef HAVE_POSIX_FALLOCATE
+ ret = posix_fallocate(fd, 0, size);
+ if (ret != 0) {
+ close(fd);
+ errno = ret;
+ return -1;
+ }
+#else
+ ret = ftruncate(fd, size);
+ if (ret < 0) {
+ close(fd);
+ return -1;
+ }
+#endif
+
+ return fd;
+}
+
+#ifndef HAVE_STRCHRNUL
+char *
+strchrnul(const char *s, int c)
+{
+ while (*s && *s != c)
+ s++;
+ return (char *)s;
+}
+#endif
diff --git a/demo3/horizontal/waltham-server/src/wth-server-gst.cpp b/demo3/horizontal/waltham-server/src/wth-server-gst.cpp
new file mode 100644
index 0000000..c282773
--- /dev/null
+++ b/demo3/horizontal/waltham-server/src/wth-server-gst.cpp
@@ -0,0 +1,1326 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+ ** **
+ ** SRC-MODULE: **
+ ** **
+ ** TARGET : linux **
+ ** **
+ ** PROJECT : waltham-server **
+ ** **
+ ** AUTHOR : **
+ ** **
+ ** **
+ ** **
+ ** PURPOSE : This file is acts as interface to weston compositor at server **
+ ** side **
+ ** **
+ ** REMARKS : **
+ ** **
+ ** PLATFORM DEPENDANT [yes/no]: yes **
+ ** **
+ ** TO BE CHANGED BY USER [yes/no]: no **
+ ** **
+ *******************************************************************************/
+
+#include <sys/mman.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <gst/gst.h>
+#include <gst/gl/gl.h>
+//#include <GL/gl.h>
+#include <gst/video/gstvideometa.h>
+#include <gst/allocators/gstdmabuf.h>
+#include <gst/app/gstappsink.h>
+#include <pthread.h>
+
+#include <xf86drm.h>
+#include <drm.h>
+#include <drm_fourcc.h>
+
+#include <string>
+
+// Error avoidance for dual declaration of strchrnul()
+#define HAVE_STRCHRNUL 1
+
+extern "C" {
+#include "wth-server-waltham-comm.h"
+#include "os-compatibility.h"
+#include "ivi-application-client-protocol.h"
+#include "bitmap.h"
+}
+
+// Applied to Windowmanager, HomeScreen
+#include "libwindowmanager.h"
+#include <libhomescreen.hpp>
+#include "hmi-debug.h"
+
+
+LibHomeScreen* hs;
+LibWindowmanager *wm;
+extern bool gIsDraw;
+extern uint32_t g_id_ivisurf;
+
+long port = 1700;
+std::string token = "wm";
+std::string app_name = "receiver";
+
+static int running = 1;
+
+extern bool get_verbosity(void);
+extern int verbose;
+
+typedef struct _GstAppContext
+{
+ GMainLoop *loop;
+ GstBus *bus;
+ GstElement *pipeline;
+ GstElement *sink;
+ GstSample *sample;
+ GstBuffer *gstbuffer;
+ GstVideoMeta *vmeta;
+
+ int dma_fd[2];
+
+ struct display *display;
+ struct window *window;
+
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int wait;
+
+ GstVideoInfo info;
+ uint32_t format;
+ bool no_dma_buf;
+}GstAppContext;
+
+static const gchar *vertex_shader_str =
+"attribute vec4 a_position; \n"
+"attribute vec2 a_texCoord; \n"
+"varying vec2 v_texCoord; \n"
+"void main() \n"
+"{ \n"
+" gl_Position = a_position; \n"
+" v_texCoord = a_texCoord; \n"
+"} \n";
+
+static const gchar *fragment_shader_str =
+"#ifdef GL_ES \n"
+"precision mediump float; \n"
+"#endif \n"
+"varying vec2 v_texCoord; \n"
+"uniform sampler2D tex; \n"
+"void main() \n"
+"{ \n"
+"vec2 uv; \n"
+"uv = v_texCoord.xy; \n"
+"vec4 c = texture2D(tex, uv); \n"
+"gl_FragColor = c; \n"
+"} \n";
+
+/*
+ * pointer callbcak functions
+ */
+ static void
+pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
+ uint32_t serial, struct wl_surface *wl_surface,
+ wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("data [%p]\n", data);
+
+ struct display *display = data;
+ struct window *window = display->window;
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+
+ waltham_pointer_enter(window, serial, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_leave(void *data, struct wl_pointer *pointer,
+ uint32_t serial, struct wl_surface *surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("data [%p]\n", data);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_leave(window, serial);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_motion(void *data, struct wl_pointer *pointer,
+ uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_motion(window, time, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
+ uint32_t serial, uint32_t time, uint32_t button,
+ uint32_t state)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_button(window, serial, time, button, state);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
+ uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_axis(window, time, axis, value);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+ pointer_handle_enter,
+ pointer_handle_leave,
+ pointer_handle_motion,
+ pointer_handle_button,
+ pointer_handle_axis,
+};
+
+/*
+ * touch callbcak functions
+ */
+
+static void
+touch_handle_down(void *data, struct wl_touch *touch, uint32_t serial,
+ uint32_t time, struct wl_surface *surface, int32_t id,
+ wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ int x = (int)wl_fixed_to_double(x_w);
+ int y = (int)wl_fixed_to_double(y_w);
+ wth_verbose("%p x %d y %d\n",window, x, y);
+
+ waltham_touch_down(window, serial, time, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_up(void *data, struct wl_touch *touch, uint32_t serial,
+ uint32_t time, int32_t id)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_up(window, serial, time, id);
+}
+
+static void
+touch_handle_motion(void *data, struct wl_touch *touch, uint32_t time,
+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_motion(window, time, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_frame(void *data, struct wl_touch *touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_frame(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_cancel(void *data, struct wl_touch *touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_cancel(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_touch_listener touch_listener = {
+ touch_handle_down,
+ touch_handle_up,
+ touch_handle_motion,
+ touch_handle_frame,
+ touch_handle_cancel
+};
+
+/*
+ * seat callback
+ */
+static void
+seat_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+
+ wth_verbose("caps = %d\n", caps);
+
+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !display->wl_pointer)
+ {
+ wth_verbose("WL_SEAT_CAPABILITY_POINTER\n");
+ display->wl_pointer = wl_seat_get_pointer(wl_seat);
+ wl_pointer_set_user_data(display->wl_pointer, display);
+ wl_pointer_add_listener(display->wl_pointer, &pointer_listener, display);
+ wl_display_roundtrip(display->display);
+ } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && display->wl_pointer) {
+ wth_verbose("!WL_SEAT_CAPABILITY_POINTER\n");
+ wl_pointer_destroy(display->wl_pointer);
+ display->wl_pointer = NULL;
+ }
+
+ if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !display->wl_touch)
+ {
+ wth_verbose("WL_SEAT_CAPABILITY_TOUCH\n");
+ display->wl_touch = wl_seat_get_touch(wl_seat);
+ wl_touch_set_user_data(display->wl_touch, display);
+ wl_touch_add_listener(display->wl_touch, &touch_listener, display);
+ wl_display_roundtrip(display->display);
+ } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && display->wl_touch) {
+ wth_verbose("!WL_SEAT_CAPABILITY_TOUCH\n");
+ wl_touch_destroy(display->wl_touch);
+ display->wl_touch = NULL;
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_seat_listener seat_listener = {
+ seat_capabilities,
+ NULL
+};
+
+static void
+add_seat(struct display *display, uint32_t id, uint32_t version)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ display->wl_pointer = NULL;
+ display->seat = wl_registry_bind(display->registry, id,
+ &wl_seat_interface, 1);
+ wl_seat_add_listener(display->seat, &seat_listener, display);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static int
+drm_fourcc_from_gst_format(GstVideoFormat format)
+{
+ switch (format) {
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ return DRM_FORMAT_RGB565;
+
+ case GST_VIDEO_FORMAT_RGB:
+ case GST_VIDEO_FORMAT_BGR:
+ return DRM_FORMAT_BGR888;
+
+ case GST_VIDEO_FORMAT_RGBA:
+ case GST_VIDEO_FORMAT_RGBx:
+ case GST_VIDEO_FORMAT_BGRA:
+ case GST_VIDEO_FORMAT_BGRx:
+ case GST_VIDEO_FORMAT_ARGB:
+ case GST_VIDEO_FORMAT_xRGB:
+ case GST_VIDEO_FORMAT_ABGR:
+ case GST_VIDEO_FORMAT_xBGR:
+ case GST_VIDEO_FORMAT_AYUV:
+ return DRM_FORMAT_ARGB8888;
+
+ case GST_VIDEO_FORMAT_GRAY8:
+ return DRM_FORMAT_R8;
+
+ case GST_VIDEO_FORMAT_YUY2:
+ case GST_VIDEO_FORMAT_UYVY:
+ case GST_VIDEO_FORMAT_GRAY16_LE:
+ case GST_VIDEO_FORMAT_GRAY16_BE:
+ return DRM_FORMAT_GR88;
+
+ case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_YV12:
+ case GST_VIDEO_FORMAT_Y41B:
+ case GST_VIDEO_FORMAT_Y42B:
+ case GST_VIDEO_FORMAT_Y444:
+ return DRM_FORMAT_R8;
+
+ case GST_VIDEO_FORMAT_NV12:
+ return DRM_FORMAT_NV12;
+
+ default:
+ return -1;
+ }
+}
+
+gboolean bus_message(GstBus *bus, GstMessage *message, gpointer p)
+{
+ GstAppContext *gstctx = p;
+
+ fprintf(stderr, "mesage: %s\n", GST_MESSAGE_TYPE_NAME(message));
+
+ switch( GST_MESSAGE_TYPE(message)) {
+ case GST_MESSAGE_ERROR:
+ {
+ GError *err;
+ gchar *debug;
+
+ gst_message_parse_error(message, &err, &debug);
+ g_print("ERROR: %s\n", err->message);
+
+ g_error_free(err);
+ g_free(debug);
+ g_main_loop_quit(gstctx->loop);
+ break;
+ }
+
+ case GST_MESSAGE_STATE_CHANGED:
+ {
+ GstState oldstate, newstate;
+
+ gst_message_parse_state_changed(message, &oldstate, &newstate, NULL);
+ fprintf(stderr, "#%s state changed\n", GST_MESSAGE_SRC_NAME(message));
+ switch (newstate){
+ case GST_STATE_NULL:
+ fprintf(stderr, "%s: state is NULL\n", GST_MESSAGE_SRC_NAME(message));
+ break;
+ case GST_STATE_READY:
+ fprintf(stderr, "%s: state is READY\n", GST_MESSAGE_SRC_NAME(message));
+ break;
+ case GST_STATE_PAUSED:
+ fprintf(stderr, "%s: state is PAUSED\n", GST_MESSAGE_SRC_NAME(message));
+ break;
+ case GST_STATE_PLAYING:
+ fprintf(stderr, "%s: state is PLAYING\n", GST_MESSAGE_SRC_NAME(message));
+ break;
+ }
+ break;
+ }
+ default:
+ fprintf(stderr, "Unhandled message\n");
+ break;
+ }
+ fprintf(stderr, "-----------------\n");
+}
+
+EGLImageKHR create_eglImage(GstAppContext* gstctx)
+{
+ struct display *display = gstctx->display;
+ GstVideoMeta *vmeta = gstctx->vmeta;
+
+ uint32_t n_planes = vmeta->n_planes;
+ EGLint attribs[30];
+ int fourcc;
+ int atti = 0;
+
+ fourcc = drm_fourcc_from_gst_format(vmeta->format);
+
+ n_planes = GST_VIDEO_INFO_N_PLANES(&(gstctx->info));
+
+ int width = GST_VIDEO_INFO_WIDTH(&(gstctx->info));
+ int height = GST_VIDEO_INFO_HEIGHT(&(gstctx->info));
+
+ attribs[atti++] = EGL_WIDTH;
+ attribs[atti++] = vmeta->width;
+ attribs[atti++] = EGL_HEIGHT;
+ attribs[atti++] = vmeta->height;
+ attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
+ attribs[atti++] = fourcc;
+
+ /*
+ * Offset value for both the planes i.e Y and UV is "0"
+ * The omxdec gives the output is 2 different memory blocks,
+ * One for Y -> dmafd[0] and other for UV -> dmafd[1]
+ */
+
+ if (n_planes > 0) {
+ attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
+ attribs[atti++] = gstctx->dma_fd[0];
+ attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
+ attribs[atti++] = 0;
+ attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
+ attribs[atti++] = vmeta->stride[0];
+ }
+
+ if (n_planes > 1) {
+ attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT;
+ attribs[atti++] = gstctx->dma_fd[1];
+ attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
+ attribs[atti++] = 0;
+ attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
+ attribs[atti++] = vmeta->stride[1];
+ }
+
+ attribs[atti++] = EGL_NONE;
+
+ return display->egl.create_image(display->egl.dpy, EGL_NO_CONTEXT,
+ EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)NULL,
+ attribs);
+}
+
+static int
+redraw(GstAppContext* gstctx)
+{
+ struct display *display = gstctx->display;
+ GstVideoMeta *vmeta = gstctx->vmeta;
+ struct window *window = display->window;
+ GLfloat vVertices[] = { -1.0f, 1.0f, 1.0f, // Position 0
+ 0.0f, 0.0f, // TexCoord 0
+ -1.0f, -1.0f, 1.0f, // Position 1
+ 0.0f, 1.0f, // TexCoord 1
+ 1.0f, -1.0f, 1.0f, // Position 2
+ 1.0f, 1.0f, // TexCoord 2
+ 1.0f, 1.0f, 1.0f, // Position 3, skewed a bit
+ 1.0f, 0.0f // TexCoord 3
+ };
+
+ GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
+ glViewport(0,0,vmeta->width,vmeta->height);
+ wl_egl_window_resize(window->native,vmeta->width,vmeta->height,0,0);
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glUseProgram(display->gl.program_object);
+
+ /* Load the vertex position */
+ GLint positionLoc = glGetAttribLocation(display->gl.program_object, "a_position");
+ glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vVertices);
+ /* Load the texture coordinate */
+ GLint texCoordLoc = glGetAttribLocation(display->gl.program_object, "a_texCoord");
+ glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3]);
+ glEnableVertexAttribArray(positionLoc);
+ glEnableVertexAttribArray(texCoordLoc);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, display->gl.texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+
+ if(gstctx->no_dma_buf == false && window->egl_img != NULL )
+ {
+ display->egl.image_texture_2d(GL_TEXTURE_2D, window->egl_img);
+ }
+ else
+ {
+ GstMapInfo map;
+ gst_buffer_map(gstctx->gstbuffer, &map, GST_MAP_READ);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, vmeta->width, vmeta->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)map.data);
+ gst_buffer_unmap(gstctx->gstbuffer, &map);
+ }
+
+ /* Set the texture sampler to texture unit 0 */
+ GLint tex = glGetUniformLocation(display->gl.program_object, "tex");
+ glUniform1i(tex, 0);
+
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+
+ eglSwapBuffers(display->egl.dpy, window->egl_surface);
+}
+
+static GstFlowReturn
+appsink_callback(GstElement *object, gpointer *data)
+{
+ wth_verbose("%s >>> \n",__func__);
+ int ret;
+ //GstAppContext *gstctx = (struct gstApplContext *)data;
+ GstAppContext *gstctx = (GstAppContext *)data;
+ GstSample *sample;
+ GstBuffer *gstbuffer;
+ GstMemory *mem;
+ int i;
+ int n_mem;
+
+ sample = gst_app_sink_pull_sample((GstAppSink*)((void*)object));
+ if(sample == NULL) {
+ wth_error("No frame received\n");
+ return -1;
+ }
+ else {
+ wth_verbose("Frame received\n");
+ }
+
+ /* get dmabuf fd from gstbuffer */
+ gstbuffer = gst_sample_get_buffer(sample);
+ if(!gstbuffer){
+ wth_error("Cannot get buffer from sample\n");
+ }
+ gstctx->vmeta = gst_buffer_get_video_meta(gstbuffer);
+ if(gstctx->vmeta==NULL){
+ wth_error("no metadata on buffer\n");
+ }
+
+ n_mem = gst_buffer_n_memory(gstbuffer);
+ if (n_mem < 1) {
+ wth_error("Buffer with no mem!\n");
+ }
+
+ for (i = 0; i < n_mem; i++) {
+ /* get dmabuf fd from gstbuffer */
+ mem = gst_buffer_peek_memory (gstbuffer, i);
+ if (!gst_is_dmabuf_memory(mem)) {
+ wth_verbose("Memory is not of dmabuf type \n");
+ gstctx->no_dma_buf = true;
+
+ gst_buffer_ref(gstbuffer);
+ gstctx->gstbuffer = gstbuffer;
+ gstctx->sample = sample;
+
+ /* wake render thread up */
+ gstctx->wait = 0;
+ pthread_cond_signal(&gstctx->cond);
+ wth_verbose(" <<< %s \n",__func__);
+ return GST_FLOW_OK;
+ }
+ gstctx->dma_fd[i] = gst_dmabuf_memory_get_fd(mem);
+ }
+
+ if (gstctx->dma_fd[0] < 0 || gstctx->dma_fd[1] < 0 ) {
+ wth_error("dma fd is null \n");
+ return GST_FLOW_ERROR;
+ }
+
+ gst_buffer_ref(gstbuffer);
+ gstctx->gstbuffer = gstbuffer;
+ gstctx->sample = sample;
+
+ /* wake render thread up */
+ gstctx->wait = 0;
+ pthread_cond_signal(&gstctx->cond);
+ wth_verbose(" <<< %s \n",__func__);
+ return GST_FLOW_OK;
+}
+
+/*
+ * registry callback
+ */
+static void
+registry_handle_global(void *data, struct wl_registry *registry,
+ uint32_t id, const char *interface, uint32_t version)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *d = data;
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ d->compositor =
+ wl_registry_bind(registry,
+ id, &wl_compositor_interface, 1);
+ } else if (strcmp(interface, "ivi_application") == 0) {
+ d->ivi_application =
+ wl_registry_bind(registry, id,
+ &ivi_application_interface, 1);
+ } else if (strcmp(interface, "wl_seat") == 0) {
+ add_seat(d, id, version);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+ uint32_t name)
+{
+ /* stub */
+}
+
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ registry_handle_global_remove
+};
+
+wth_server_weston_shm_attach(struct window *window, uint32_t data_sz, void * data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format)
+{
+ /* stub */
+}
+void
+wth_server_weston_shm_damage(struct window *window)
+{
+ /* stub */
+}
+
+void
+wth_server_weston_shm_commit(struct window *window)
+{
+ /* stub */
+}
+
+static struct display *
+create_display(void)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display;
+
+ display = malloc(sizeof *display);
+ if (display == NULL) {
+ wth_error("out of memory\n");
+ exit(1);
+ }
+ display->display = wl_display_connect(NULL);
+ assert(display->display);
+
+ display->has_xrgb = false;
+ display->registry = wl_display_get_registry(display->display);
+ wl_registry_add_listener(display->registry,
+ &registry_listener, display);
+ wl_display_roundtrip(display->display);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return display;
+}
+
+static void
+destroy_display(struct display *display)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ if (display->compositor)
+ wl_compositor_destroy(display->compositor);
+
+ wl_registry_destroy(display->registry);
+ wl_display_flush(display->display);
+ wl_display_disconnect(display->display);
+ free(display);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * ivi surface callback
+ */
+static void
+handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface,
+ int32_t width, int32_t height)
+{
+ /* Simple-shm is resizable */
+}
+
+static const struct ivi_surface_listener ivi_surface_listener = {
+ handle_ivi_surface_configure,
+};
+
+static void
+init_egl(struct display *display)
+{
+ wth_verbose("%s >>> \n",__func__);
+ EGLint config_attribs[] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_NONE
+ };
+
+ static const EGLint context_attribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ EGLint major, minor, count;
+ EGLBoolean ret;
+
+ display->egl.dpy = eglGetDisplay(display->display);
+ assert(display->egl.dpy);
+
+ ret = eglInitialize(display->egl.dpy, &major, &minor);
+ assert(ret == EGL_TRUE);
+ ret = eglBindAPI(EGL_OPENGL_ES_API);
+ assert(ret == EGL_TRUE);
+
+ ret = eglChooseConfig(display->egl.dpy, config_attribs,
+ &display->egl.conf, 1, &count);
+ assert(ret && count >= 1);
+
+ display->egl.ctx = eglCreateContext(display->egl.dpy,
+ display->egl.conf,
+ EGL_NO_CONTEXT, context_attribs);
+ assert(display->egl.ctx);
+
+ eglSwapInterval(display->egl.dpy, 1);
+
+ display->egl.create_image =
+ (void *) eglGetProcAddress("eglCreateImageKHR");
+ assert(display->egl.create_image);
+
+ display->egl.image_texture_2d =
+ (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
+ assert(display->egl.image_texture_2d);
+
+ display->egl.destroy_image =
+ (void *) eglGetProcAddress("eglDestroyImageKHR");
+ assert(display->egl.destroy_image);
+}
+
+GLuint load_shader(GLenum type, const char *shaderSrc)
+{
+ wth_verbose("%s >>> \n",__func__);
+ GLuint shader;
+ GLint compiled;
+
+ /* Create the shader object */
+ shader = glCreateShader(type);
+ if (shader == 0)
+ {
+ printf("\n Failed to create shader \n");
+ return 0;
+ }
+ /* Load the shader source */
+ glShaderSource(shader, 1, &shaderSrc, NULL);
+ /* Compile the shader */
+ glCompileShader(shader);
+ /* Check the compile status */
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled)
+ {
+ GLint infoLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen > 1)
+ {
+ char* infoLog = (char*)malloc (sizeof(char) * infoLen );
+ glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
+ fprintf(stderr, "Error compiling shader:%s\n",infoLog);
+ free(infoLog);
+ }
+ glDeleteShader(shader);
+ return 0;
+ }
+ return shader;
+}
+
+void init_gl(struct display *display)
+{
+ wth_verbose("%s >>> \n",__func__);
+ GLint linked;
+
+ /* load vertext/fragment shader */
+ display->gl.vertex_shader = load_shader(GL_VERTEX_SHADER, vertex_shader_str);
+ display->gl.fragment_shader = load_shader(GL_FRAGMENT_SHADER, fragment_shader_str);
+
+ /* Create the program object */
+ display->gl.program_object = glCreateProgram();
+ if (display->gl.program_object == 0)
+ {
+ fprintf(stderr, "error program object\n");
+ return;
+ }
+
+ glAttachShader(display->gl.program_object, display->gl.vertex_shader);
+ glAttachShader(display->gl.program_object, display->gl.fragment_shader);
+ /* Bind vPosition to attribute 0 */
+ glBindAttribLocation(display->gl.program_object, 0, "a_position");
+ /* Link the program */
+ glLinkProgram(display->gl.program_object);
+ /* Check the link status */
+ glGetProgramiv(display->gl.program_object, GL_LINK_STATUS, &linked);
+ if (!linked)
+ {
+ GLint infoLen = 0;
+ glGetProgramiv(display->gl.program_object, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen > 1)
+ {
+ char* infoLog = (char*)malloc(sizeof(char) * infoLen);
+ glGetProgramInfoLog(display->gl.program_object, infoLen, NULL, infoLog);
+ fprintf(stderr, "Error linking program:%s\n", infoLog);
+ free(infoLog);
+ }
+ glDeleteProgram(display->gl.program_object);
+ }
+
+ glGenTextures(1, &display->gl.texture);
+
+ return;
+}
+
+static void
+create_surface(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct display *display = window->display;
+ int ret;
+
+ window->surface = wl_compositor_create_surface(display->compositor);
+ assert(window->surface);
+
+ window->native = wl_egl_window_create(window->surface,
+ window->width, window->height);
+ assert(window->native);
+
+ window->egl_surface = eglCreateWindowSurface(display->egl.dpy,
+ display->egl.conf,
+ (NativeWindowType)window->native, NULL);
+
+ wl_display_roundtrip(display->display);
+ if (display->ivi_application ) {
+ uint32_t id_ivisurf = g_id_ivisurf; //window->id_ivisurf;
+ window->ivi_surface =
+ ivi_application_surface_create(display->ivi_application,
+ id_ivisurf, window->surface);
+ if (window->ivi_surface == NULL) {
+ wth_error("Failed to create ivi_client_surface\n");
+ abort();
+ }
+
+ ivi_surface_add_listener(window->ivi_surface,
+ &ivi_surface_listener, window);
+ } else {
+ assert(0);
+ }
+ ret = eglMakeCurrent(display->egl.dpy, window->egl_surface,
+ window->egl_surface, display->egl.ctx);
+ assert(ret == EGL_TRUE);
+
+ glClearColor(0.5, 0.5, 0.5, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ eglSwapBuffers(display->egl.dpy, window->egl_surface);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+create_window(struct window *window, struct display *display, int width, int height)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ window->callback = NULL;
+
+ window->display = display;
+ window->width = width;
+ window->height = height;
+ window->window_frames = 0;
+ window->window_benchmark_time = 0;
+
+ create_surface(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+static void
+destroy_window(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ if (window->callback)
+ wl_callback_destroy(window->callback);
+
+ if (window->buffers[0].buffer)
+ wl_buffer_destroy(window->buffers[0].buffer);
+ if (window->buffers[1].buffer)
+ wl_buffer_destroy(window->buffers[1].buffer);
+
+ wl_surface_destroy(window->surface);
+ free(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+signal_int(int signum)
+{
+ running = 0;
+}
+
+void *stream_thread(void *data)
+{
+ wth_verbose("%s >>> \n",__func__);
+ GMainLoop *loop = data;
+ g_main_loop_run(loop);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+
+
+static GstPadProbeReturn
+pad_probe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
+{
+ wth_verbose("%s >>> \n",__func__);
+ GstAppContext *dec = user_data;
+ GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info);
+ GstCaps *caps;
+
+ (void)pad;
+
+ if (GST_EVENT_TYPE(event) != GST_EVENT_CAPS)
+ return GST_PAD_PROBE_OK;
+
+ gst_event_parse_caps(event, &caps);
+
+ if (!caps) {
+ GST_ERROR("caps event without caps");
+ return GST_PAD_PROBE_OK;
+ }
+
+ if (!gst_video_info_from_caps(&dec->info, caps)) {
+ GST_ERROR("caps event with invalid video caps");
+ return GST_PAD_PROBE_OK;
+ }
+
+ switch (GST_VIDEO_INFO_FORMAT(&(dec->info))) {
+ case GST_VIDEO_FORMAT_I420:
+ dec->format = DRM_FORMAT_YUV420;
+ break;
+ case GST_VIDEO_FORMAT_NV12:
+ dec->format = DRM_FORMAT_NV12;
+ break;
+ case GST_VIDEO_FORMAT_YUY2:
+ dec->format = DRM_FORMAT_YUYV;
+ break;
+ default:
+ GST_ERROR("unknown format\n");
+ return GST_PAD_PROBE_OK;
+ }
+ wth_verbose(" <<< %s \n",__func__);
+ return GST_PAD_PROBE_OK;
+}
+
+// Applied to WM, HS
+int
+init_wm(LibWindowmanager *wm, struct window *window)
+{
+ HMI_DEBUG("waltham-server","called");
+ char* surfaceIdStr;
+
+ wth_verbose("app:%s port:%d token:%s \n", app_name.c_str(), port, token.c_str());
+
+ if (wm->init(port, token.c_str()) != 0) {
+ HMI_ERROR("waltham-server","wm init failed. ");
+ return -1;
+ }
+
+ json_object *obj = json_object_new_object();
+ json_object_object_add(obj, wm->kKeyDrawingName, json_object_new_string(app_name.c_str()));
+ g_id_ivisurf = wm->requestSurface(obj);
+ if(g_id_ivisurf < 0)
+ {
+ HMI_ERROR("waltham-server","requestSurface failed: %d ", g_id_ivisurf);
+ return -1;
+ }
+ HMI_DEBUG("waltham-server","IVI_SURFACE_ID: %d ", g_id_ivisurf);
+
+ wm->set_event_handler(LibWindowmanager::Event_Active, [wm](json_object *object) {
+ const char *label = json_object_get_string(
+ json_object_object_get(object, wm->kKeyDrawingName));
+ HMI_DEBUG("waltham-server","Surface %s got activated! ", label);
+ });
+
+ wm->set_event_handler(LibWindowmanager::Event_Inactive, [wm](json_object *object) {
+ const char *label = json_object_get_string(
+ json_object_object_get(object, wm->kKeyDrawingName));
+ HMI_DEBUG("waltham-server","Surface %s got inactivated!", label);
+ });
+
+ wm->set_event_handler(LibWindowmanager::Event_Visible, [wm](json_object *object) {
+ const char *label = json_object_get_string(
+ json_object_object_get(object, wm->kKeyDrawingName));
+ HMI_DEBUG("waltham-server","Surface %s got visibled!", label);
+ });
+
+ wm->set_event_handler(LibWindowmanager::Event_Invisible, [wm](json_object *object) {
+ const char *label = json_object_get_string(
+ json_object_object_get(object, wm->kKeyDrawingName));
+ HMI_DEBUG("waltham-server","Surface %s got invisibled!", label);
+ gIsDraw = false;
+ });
+
+ wm->set_event_handler(LibWindowmanager::Event_SyncDraw, [wm, window](json_object *object) {
+ const char *label = json_object_get_string(
+ json_object_object_get(object, wm->kKeyDrawingName));
+ const char *area = json_object_get_string(
+ json_object_object_get(object, wm->kKeyDrawingArea));
+
+ HMI_DEBUG("waltham-server","Layout:%s x:%d y:%d w:%d h:%d ", area, 0, 0, 640, 720);
+ wl_egl_window_resize(window->native, 640, 720, 0, 0);
+ window->width = 640;
+ window->height = 720;
+ //if (!window->fullscreen)
+ // window->window_size = window->geometry;
+ gIsDraw = true;
+ json_object *obj = json_object_new_object();
+ json_object_object_add(obj, wm->kKeyDrawingName, json_object_new_string(app_name.c_str()));
+ wm->endDraw(obj);
+ });
+
+ wm->set_event_handler(LibWindowmanager::Event_FlushDraw, [wm](json_object *object) {
+ const char *label = json_object_get_string(
+ json_object_object_get(object, wm->kKeyDrawingName));
+ HMI_DEBUG("waltham-server","Surface %s got flushdraw! ", label);
+ });
+
+ return 0;
+}
+
+int
+init_hs(LibHomeScreen* hs)
+{
+ if(hs->init(port, token)!=0)
+ {
+ HMI_ERROR("waltham-server","homescreen init failed. ");
+ return -1;
+ }
+
+ hs->set_event_handler(LibHomeScreen::Event_TapShortcut, [](json_object *object){
+ const char *application_name = json_object_get_string(
+ json_object_object_get(object, "application_name"));
+ HMI_DEBUG("waltham-server","Event_TapShortcut application_name = %s ", application_name);
+ if(strcmp(application_name, app_name.c_str()) == 0)
+ {
+ HMI_DEBUG("waltham-server","try to activesurface %s ", app_name.c_str());
+ json_object *obj = json_object_new_object();
+ json_object_object_add(obj, wm->kKeyDrawingName, json_object_new_string(app_name.c_str()));
+ json_object_object_add(obj, wm->kKeyDrawingArea, json_object_new_string("split.sub"));
+ gIsDraw = false;
+ fprintf(stderr, "@@@@@ called activate in tapshortcut handler\n");
+ wm->activateWindow(obj);
+ }
+ });
+
+ hs->set_event_handler(LibHomeScreen::Event_OnScreenMessage, [](json_object *object){
+ const char *display_message = json_object_get_string(
+ json_object_object_get(object, "display_message"));
+ HMI_DEBUG("waltham-server","Event_OnScreenMessage display_message = %s ", display_message);
+ });
+
+ return 0;
+}
+
+GstAppContext gstctx; // @@@@@
+void init_receiver(struct window *window)
+{
+ struct sigaction sigint;
+ GError *gerror = NULL;
+ char * pipe = NULL;
+ FILE *pFile;
+ long lSize;
+ size_t res;
+
+ memset(&gstctx, 0, sizeof(gstctx));
+ /* Initialization for window creation */
+ gstctx.display = create_display();
+ init_egl(gstctx.display);
+
+ /* windowmanager, homescreen */
+ wm = new LibWindowmanager();
+ hs = new LibHomeScreen();
+
+ if(init_wm(wm, window)!=0){
+ // error process
+ wth_verbose("Error in init_wm.\n");
+ return -1;
+ }
+
+ if(init_hs(hs)!=0){
+ // error process
+ wth_verbose("Error in init_hs.\n");
+ return -1;
+ }
+
+ /* ToDo: fix the hardcoded value of width, height */
+// create_window(window, gstctx.display,1920,1080);
+ create_window(window, gstctx.display,640,720);
+ init_gl(gstctx.display);
+ gstctx.window = window;
+
+ gstctx.display->window = window;
+
+ wth_verbose("display %p\n", gstctx.display);
+ wth_verbose("display->window %p\n", gstctx.display->window);
+ wth_verbose("window %p\n", window);
+
+ sigint.sa_handler = signal_int;
+ sigemptyset(&sigint.sa_mask);
+ sigint.sa_flags = SA_RESETHAND;
+ sigaction(SIGINT, &sigint, NULL);
+
+ /* create gstreamer pipeline */
+ gst_init(NULL, NULL);
+ gstctx.loop = g_main_loop_new(NULL, FALSE);
+
+ /* Read pipeline from file */
+ pFile = fopen ( "/etc/xdg/weston/pipeline.cfg" , "rb" );
+ if (pFile==NULL){
+ fprintf(stderr, "failed to open file\n");
+ return -1;
+ }
+
+ /* obtain file size */
+ fseek (pFile , 0 , SEEK_END);
+ lSize = ftell (pFile);
+ rewind (pFile);
+
+ /* allocate memory to contain the whole file */
+ pipe = (char*) zalloc (sizeof(char)*lSize);
+ if (pipe == NULL){
+ fprintf(stderr,"Cannot allocate memory\n");
+ return -1;
+ }
+
+ /* copy the file into the buffer */
+ res = fread (pipe,1,lSize,pFile);
+ if (res != lSize){
+ fprintf(stderr,"File read error\n");
+ return -1;
+ }
+
+ wth_verbose("Gst Pipeline=%s",pipe);
+ /* close file */
+ fclose (pFile);
+
+ /* parse the pipeline */
+ gstctx.pipeline = gst_parse_launch(pipe, &gerror);
+
+ if(!gstctx.pipeline)
+ fprintf(stderr,"Could not create gstreamer pipeline.\n");
+ free(pipe);
+
+ gstctx.bus = gst_pipeline_get_bus((GstPipeline*)((void*)gstctx.pipeline));
+ gst_bus_add_watch(gstctx.bus, bus_message, &gstctx);
+ fprintf(stderr, "registered bus signal\n");
+
+ gstctx.sink = gst_bin_get_by_name(GST_BIN(gstctx.pipeline), "sink");
+ g_object_set(G_OBJECT(gstctx.sink), "emit-signals", TRUE, NULL);
+ g_signal_connect(gstctx.sink, "new-sample", G_CALLBACK(appsink_callback), &gstctx);
+ g_object_set(G_OBJECT(gstctx.sink), "drop", TRUE, "max-buffers",-1, NULL);
+ gst_pad_add_probe(gst_element_get_static_pad(gstctx.sink, "sink"),
+ GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+ pad_probe, &gstctx, NULL);
+
+ fprintf(stderr, "set state as playing\n");
+ gst_element_set_state((GstElement*)((void*)gstctx.pipeline), GST_STATE_PLAYING);
+
+ wth_verbose("wl_display_dispatch_pending >>>\n");
+ wl_display_dispatch_pending(gstctx.display->display);
+ wth_verbose("<<< wl_display_dispatch_pending; redraw >>>\n");
+ //redraw(&gstctx);
+ wth_verbose("<<< redraw\n");
+ json_object *obj = json_object_new_object();
+ json_object_object_add(obj, wm->kKeyDrawingName, json_object_new_string(app_name.c_str()));
+ json_object_object_add(obj, wm->kKeyDrawingArea, json_object_new_string("normal.full"));
+ wth_verbose("activateWindow >>>\n");
+ fprintf(stderr, "@@@@@ called activate in init_receiver\n");
+ wm->activateWindow(obj);
+}
+
+/**
+ * wth_server_weston_main
+ *
+ * This is the main function which will handle connection to the compositor at server side
+ *
+ * @param names void *data
+ * @param value struct window data
+ * @return 0 on success, -1 on error
+ */
+int
+wth_server_weston_main(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct sigaction sigint;
+ pthread_t pthread;
+// GstAppContext gstctx;
+ int ret = 0;
+ GError *gerror = NULL;
+ char * pipe = NULL;
+ FILE *pFile;
+ long lSize;
+ size_t res;
+
+ pthread_mutex_init(&gstctx.mutex, NULL);
+ pthread_cond_init(&gstctx.cond, NULL);
+
+ pthread_create(&pthread, NULL, &stream_thread, gstctx.loop);
+
+ fprintf(stderr, "rendering part\n");
+
+ gstctx.wait = 1;
+ pthread_mutex_lock(&gstctx.mutex);
+
+ while (running && ret != -1) {
+ wth_verbose("in render loop\n");
+ ret = wl_display_dispatch(gstctx.display->display);
+ if(gstctx.wait == 1) {
+ wth_verbose("cond wait\n");
+ pthread_cond_wait(&gstctx.cond, &gstctx.mutex);
+ }
+
+ if(gstctx.no_dma_buf == false)
+ {
+ wth_verbose("create egl image\n");
+ window->egl_img = create_eglImage(&gstctx);
+ }
+
+ wth_verbose("redraw\n");
+ redraw(&gstctx);
+ wth_verbose("fin redraw\n");
+ gstctx.display->egl.destroy_image(gstctx.display->egl.dpy, window->egl_img);
+ gst_buffer_unref(gstctx.gstbuffer);
+ gst_sample_unref(gstctx.sample);
+ gstctx.wait = 1;
+ }
+ pthread_mutex_unlock(&gstctx.mutex);
+
+ wth_verbose("wth_server_gst_main exiting\n");
+
+ if (window->display->ivi_application) {
+ ivi_surface_destroy(window->ivi_surface);
+ ivi_application_destroy(window->display->ivi_application);
+ }
+
+ destroy_window(window);
+ destroy_display(gstctx.display);
+
+ wth_verbose(" <<< %s \n",__func__);
+
+ return 0;
+}
diff --git a/demo3/horizontal/waltham-server/src/wth-server-main.cpp b/demo3/horizontal/waltham-server/src/wth-server-main.cpp
new file mode 100644
index 0000000..ab86304
--- /dev/null
+++ b/demo3/horizontal/waltham-server/src/wth-server-main.cpp
@@ -0,0 +1,372 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+** **
+** SRC-MODULE: **
+** **
+** TARGET : linux **
+** **
+** PROJECT : waltham-server **
+** **
+** AUTHOR : **
+** **
+** **
+** **
+** PURPOSE : This file handles connection with remote-client **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+#include <signal.h>
+extern "C" {
+#include "wth-server-waltham-comm.h"
+}
+#include <string>
+
+// Applied to Windowmanager, HomeScreen
+#include "libwindowmanager.h"
+#include <libhomescreen.hpp>
+
+#define MAX_EPOLL_WATCHES 2
+
+extern long port;
+extern std::string token;
+extern std::string app_name;
+
+int verbose = 0;
+uint16_t tcp_port = 34400;
+
+bool gIsDraw = false;
+
+uint32_t g_id_ivisurf = 9009;
+
+/** get verbosity
+ */
+bool
+get_verbosity()
+{
+ if (verbose == 1)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/** Print out the application help
+ */
+static void usage(void)
+{
+ printf("Usage: waltham server [options]\n");
+ printf("Options:\n");
+ printf(" -p --port number TCP port number\n");
+ printf(" -h --help Usage\n");
+ printf(" -v --verbose Set verbose flag (Default:%d)\n", get_verbosity());
+}
+
+static struct option long_options[] = {
+ {"port", required_argument, 0, 'p'},
+ {"verbose", no_argument, 0, 'v'},
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0}
+};
+
+/**
+ * parse_args
+ *
+ * Parses the application arguments
+ * The arguments are parsed and saved in static structure for future use.
+ *
+ * @param argc The amount of arguments
+ * @param argv The table of arguments
+ *
+ * @return 0 on success, -1 otherwise
+ */
+static int parse_args(int argc, char *argv[])
+{
+ int c = -1;
+ int long_index = 0;
+
+ while ((c = getopt_long(argc,
+ argv,
+ "p:vh",
+ long_options,
+ &long_index)) != -1)
+ {
+ switch (c)
+ {
+ case 'p':
+ tcp_port = atoi(optarg);
+ break;
+ case 'v':
+ verbose=1;
+ break;
+ case 'h':
+ usage();
+ return -1;
+ default:
+ wth_error("Try %s -h for more information.\n", argv[0]);
+ return -1;
+ }
+ }
+
+ if (tcp_port == 0)
+ {
+ wth_error("TCP port not set \n");
+ wth_error("Try %s -h for more information.\n", argv[0]);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+watch_ctl(struct watch *w, int op, uint32_t events)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct epoll_event ee;
+
+ ee.events = events;
+ ee.data.ptr = w;
+ wth_verbose(" <<< %s \n",__func__);
+ return epoll_ctl(w->server->epoll_fd, op, w->fd, &ee);
+}
+
+/**
+* listen_socket_handle_data
+*
+* Handles all incoming events on socket
+*
+* @param names struct watch *w ,uint32_t events
+* @param value pointer to watch connection it holds server information, Incoming events information
+* @return none
+*/
+static void
+listen_socket_handle_data(struct watch *w, uint32_t events)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct server *srv = container_of(w, struct server, listen_watch);
+
+ if (events & EPOLLERR) {
+ wth_error("Listening socket errored out.\n");
+ srv->running = false;
+
+ return;
+ }
+
+ if (events & EPOLLHUP) {
+ wth_error("Listening socket hung up.\n");
+ srv->running = false;
+
+ return;
+ }
+
+ if (events & EPOLLIN)
+ {
+ wth_verbose("EPOLLIN evnet received. \n");
+ server_accept_client(srv);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/**
+* server_mainloop
+*
+* This is the main loop, which will flush all pending clients requests and
+* listen to input events from socket
+*
+* @param names void *data
+* @param value pointer to server struct -
+* struct holds the client connection information
+* @return none
+*/
+static void
+server_mainloop(struct server *srv)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct epoll_event ee[MAX_EPOLL_WATCHES];
+ struct watch *w;
+ int count;
+ int i;
+
+ srv->running = true;
+
+ while (srv->running) {
+ /* Run any idle tasks at this point. */
+
+ server_flush_clients(srv);
+
+ /* Wait for events or signals */
+ count = epoll_wait(srv->epoll_fd,
+ ee, ARRAY_LENGTH(ee), -1);
+ if (count < 0 && errno != EINTR) {
+ perror("Error with epoll_wait");
+ break;
+ }
+
+ /* Handle all fds, both the listening socket
+ * (see listen_socket_handle_data()) and clients
+ * (see connection_handle_data()).
+ */
+ for (i = 0; i < count; i++) {
+ w = ee[i].data.ptr;
+ w->cb(w, ee[i].events);
+ }
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static int
+server_listen(uint16_t tcp_port)
+{
+ wth_verbose("%s >>> \n",__func__);
+ int fd;
+ int reuse = 1;
+ struct sockaddr_in addr;
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(tcp_port);
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof reuse);
+
+ if (bind(fd, (struct sockaddr *)&addr, sizeof addr) < 0) {
+ wth_error("Failed to bind to port %d", tcp_port);
+ close(fd);
+ return -1;
+ }
+
+ if (listen(fd, 1024) < 0) {
+ wth_error("Failed to listen to port %d", tcp_port);
+ close (fd);
+ return -1;
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+ return fd;
+}
+
+static bool *signal_int_handler_run_flag;
+
+static void
+signal_int_handler(int signum)
+{
+ wth_verbose("%s >>> \n",__func__);
+ if (!*signal_int_handler_run_flag)
+ abort();
+
+ *signal_int_handler_run_flag = false;
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+set_sigint_handler(bool *running)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct sigaction sigint;
+
+ signal_int_handler_run_flag = running;
+ sigint.sa_handler = signal_int_handler;
+ sigemptyset(&sigint.sa_mask);
+ sigint.sa_flags = SA_RESETHAND;
+ sigaction(SIGINT, &sigint, NULL);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+
+struct window g_window; // @@@@@
+extern void init_receiver(struct window *window);// @@@@@
+/**
+* main
+*
+* waltham server main function, it accepts tcp port number as argument.
+* Establishes connection on the port and listen to port for incoming connection
+* request from waltham clients
+*
+* @param names argv - argument list and argc -argument count
+* @param value tcp port number as argument
+* @return 0 on success, -1 on error
+*/
+int
+main(int argc, char *argv[])
+{
+ struct server srv = { 0 };
+ struct client *c;
+
+ wth_verbose("%s >>> \n",__func__);
+
+ if(argc > 2)
+ {
+ if(std::string(argv[0]).find("receiver") != std::string::npos)
+ app_name = std::string("receiver");
+ port = strtol(argv[1], NULL, 10);
+ token = argv[2];
+ }
+
+ wth_verbose("app:%s port:%d token:%s \n", app_name.c_str(), port, token.c_str());
+#if 0
+ /* Get command line arguments */
+ if (parse_args(argc, argv) != 0)
+ {
+ return -1;
+ }
+#endif
+
+ set_sigint_handler(&srv.running);
+
+ wl_list_init(&srv.client_list);
+
+ srv.epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+ if (srv.epoll_fd == -1) {
+ perror("Error on epoll_create1");
+ exit(1);
+ }
+
+ srv.listen_fd = server_listen(tcp_port);
+ if (srv.listen_fd < 0) {
+ perror("Error setting up listening socket");
+ exit(1);
+ }
+
+ srv.listen_watch.server = &srv;
+ srv.listen_watch.cb = listen_socket_handle_data;
+ srv.listen_watch.fd = srv.listen_fd;
+ if (watch_ctl(&srv.listen_watch, EPOLL_CTL_ADD, EPOLLIN) < 0) {
+ perror("Error setting up listen polling");
+ exit(1);
+ }
+
+ init_receiver(&g_window);
+
+ wth_verbose("Waltham server listening on TCP port %u...\n",tcp_port);
+
+ server_mainloop(&srv);
+
+ /* destroy all things */
+ wl_list_last_until_empty(c, &srv.client_list, link)
+ client_destroy(c);
+
+ close(srv.listen_fd);
+ close(srv.epoll_fd);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return 0;
+}
diff --git a/demo3/horizontal/waltham-server/src/wth-server-waltham-comm.cpp b/demo3/horizontal/waltham-server/src/wth-server-waltham-comm.cpp
new file mode 100644
index 0000000..6e3b08c
--- /dev/null
+++ b/demo3/horizontal/waltham-server/src/wth-server-waltham-comm.cpp
@@ -0,0 +1,1202 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+** **
+** SRC-MODULE: **
+** **
+** TARGET : linux **
+** **
+** PROJECT : waltham-server **
+** **
+** AUTHOR : **
+** **
+** **
+** **
+** PURPOSE : This file acts as interface to waltham IPC library **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+extern "C" {
+#include "wth-server-waltham-comm.h"
+}
+extern int wth_server_weston_main(struct window *);
+
+extern void wth_server_weston_shm_attach(struct window *, uint32_t data_sz, void * data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format);
+extern void wth_server_weston_shm_damage(struct window *);
+extern void wth_server_weston_shm_commit(struct window *);
+
+extern bool get_verbosity(void);
+extern int verbose;
+
+// container_of modified for C->C++
+/*
+#undef container_of
+#undef offsetof
+
+template<class P, class M>
+size_t offsetof(const M P::*member)
+{
+ return (size_t) &( reinterpret_cast<P*>(0)->*member);
+}
+template<class P, class M>
+P* container_of(M* ptr, const M P::*member)
+{
+ return (P*)( (char*)ptr - offsetof(member));
+}
+*/
+typedef struct buffer Buffer;
+
+/*
+ * utility functions
+ */
+static int
+watch_ctl(struct watch *w, int op, uint32_t events)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct epoll_event ee;
+
+ ee.events = events;
+ ee.data.ptr = w;
+ wth_verbose(" <<< %s \n",__func__);
+ return epoll_ctl(w->server->epoll_fd, op, w->fd, &ee);
+}
+
+static void
+client_post_out_of_memory(struct client *c)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct wth_display *disp;
+
+ disp = wth_connection_get_display(c->connection);
+ wth_object_post_error((struct wth_object *)disp, 1,
+ "out of memory");
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * waltham surface implementation
+ */
+static void
+surface_destroy(struct surface *surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("surface %p destroy\n", surface->obj);
+
+ wthp_surface_free(surface->obj);
+ wl_list_remove(&surface->link);
+ free(surface);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_destroy(struct wthp_surface *wthp_surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = wth_object_get_user_data((struct wth_object *)wthp_surface);
+
+ assert(wthp_surface == surface->obj);
+
+ surface_destroy(surface);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_attach(struct wthp_surface *wthp_surface,
+ struct wthp_buffer *wthp_buf, int32_t x, int32_t y)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct buffer *buffr = wth_object_get_user_data((struct wth_object *)wthp_buf);
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ struct buffer *buf = NULL;
+
+ //buf = container_of(wthp_buf, struct buffer, obj);
+ //buf = container_of(wthp_buf, &buffer::obj);
+ uint32_t *tmp_data_sz = (uint32_t *)wthp_buf + sizeof(struct wthp_buffer *);
+ buf = container_of(tmp_data_sz, struct buffer, data_sz);
+
+ if (surf->ivi_id != 0) {
+ wth_server_weston_shm_attach(surf->shm_window,
+ buf->data_sz,
+ buf->data,
+ buf->width,
+ buf->height,
+ buf->stride,
+ buf->format);
+
+ wthp_buffer_send_complete(wthp_buf, 0);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_damage(struct wthp_surface *wthp_surface,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("surface %p damage(%d, %d, %d, %d)\n",
+ wthp_surface, x, y, width, height);
+
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+
+ if (surf->ivi_id != 0) {
+ wth_server_weston_shm_damage(surf->shm_window);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_frame(struct wthp_surface *wthp_surface,
+ struct wthp_callback *callback)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ wth_verbose("surface %p callback(%p)\n",wthp_surface, callback);
+
+ surf->cb = callback;
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_set_opaque_region(struct wthp_surface *wthp_surface,
+ struct wthp_region *region)
+{
+ wth_verbose("surface %p set_opaque_region(%p)\n",
+ wthp_surface, region);
+}
+
+static void
+surface_handle_set_input_region(struct wthp_surface *wthp_surface,
+ struct wthp_region *region)
+{
+ wth_verbose("surface %p set_input_region(%p)\n",
+ wthp_surface, region);
+}
+
+static void
+surface_handle_commit(struct wthp_surface *wthp_surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct surface *surf = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ wth_verbose("commit %p\n",wthp_surface);
+
+ if (surf->ivi_id != 0) {
+ wth_server_weston_shm_commit(surf->shm_window);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+surface_handle_set_buffer_transform(struct wthp_surface *wthp_surface,
+ int32_t transform)
+{
+ wth_verbose("surface %p et_buffer_transform(%d)\n",
+ wthp_surface, transform);
+}
+
+static void
+surface_handle_set_buffer_scale(struct wthp_surface *wthp_surface,
+ int32_t scale)
+{
+ wth_verbose("surface %p set_buffer_scale(%d)\n",
+ wthp_surface, scale);
+}
+
+static void
+surface_handle_damage_buffer(struct wthp_surface *wthp_surface,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ wth_verbose("surface %p damage_buffer(%d, %d, %d, %d)\n",
+ wthp_surface, x, y, width, height);
+}
+
+static const struct wthp_surface_interface surface_implementation = {
+ surface_handle_destroy,
+ surface_handle_attach,
+ surface_handle_damage,
+ surface_handle_frame,
+ surface_handle_set_opaque_region,
+ surface_handle_set_input_region,
+ surface_handle_commit,
+ surface_handle_set_buffer_transform,
+ surface_handle_set_buffer_scale,
+ surface_handle_damage_buffer
+};
+
+
+/* BEGIN wthp_region implementation */
+
+static void
+buffer_handle_destroy(struct wthp_buffer *wthp_buffer)
+{
+ struct buffer *buf = wth_object_get_user_data((struct wth_object *)wthp_buffer);
+
+ wthp_buffer_free(wthp_buffer);
+ wl_list_remove(&buf->link);
+ free(buf);
+}
+
+static const struct wthp_buffer_interface buffer_implementation = {
+ buffer_handle_destroy
+};
+
+/* END wthp_region implementation */
+
+/* BEGIN wthp_blob_factory implementation */
+
+static void
+blob_factory_create_buffer(struct wthp_blob_factory *blob_factory,
+ struct wthp_buffer *wthp_buffer, uint32_t data_sz, void *data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format)
+{
+ struct blob_factory *blob = wth_object_get_user_data((struct wth_object *)blob_factory);
+ struct buffer *buffer;
+
+
+ wth_verbose("wthp_blob_factory %p create_buffer(%p, %d, %p, %d, %d, %d, %d)\n",
+ blob_factory, wthp_buffer, data_sz, data, width, height, stride, format);
+
+ buffer = zalloc(sizeof *buffer);
+ if (!buffer) {
+ client_post_out_of_memory(blob->client);
+ return;
+ }
+
+ wl_list_insert(&blob->client->buffer_list, &buffer->link);
+
+ buffer->data_sz = data_sz;
+ buffer->data = data;
+ buffer->width = width;
+ buffer->height = height;
+ buffer->stride = stride;
+ buffer->format = format;
+ buffer->obj = wthp_buffer;
+
+ wthp_buffer_set_interface(wthp_buffer, &buffer_implementation, buffer);
+}
+
+static const struct wthp_blob_factory_interface blob_factory_implementation = {
+ blob_factory_create_buffer
+};
+
+static void
+client_bind_blob_factory(struct client *c, struct wthp_blob_factory *obj)
+{
+ struct blob_factory *blob;
+
+ blob = zalloc(sizeof *blob);
+ if (!blob) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ blob->obj = obj;
+ blob->client = c;
+ wl_list_insert(&c->compositor_list, &blob->link);
+
+ wthp_blob_factory_set_interface(obj, &blob_factory_implementation,
+ blob);
+ fprintf(stderr, "client %p bound wthp_blob_factory\n", c);
+}
+
+/*
+ * waltam ivi surface implementation
+ */
+static void
+wthp_ivi_surface_destroy(struct wthp_ivi_surface * ivi_surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct ivisurface *ivisurf = wth_object_get_user_data((struct wth_object *)ivi_surface);
+ free(ivisurf);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_ivi_surface_interface wthp_ivi_surface_implementation = {
+ wthp_ivi_surface_destroy,
+};
+
+
+/*
+ * waltham ivi application implementation
+ */
+static void
+wthp_ivi_application_surface_create(struct wthp_ivi_application * ivi_application, uint32_t ivi_id,
+ struct wthp_surface * wthp_surface, struct wthp_ivi_surface *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("ivi_application %p surface_create(%d, %p, %p)\n",
+ ivi_application, ivi_id, wthp_surface, obj);
+ struct application *app = wth_object_get_user_data((struct wth_object *)ivi_application);
+ struct surface *surface = wth_object_get_user_data((struct wth_object *)wthp_surface);
+ wth_verbose("----------------------------------\n\n\n");
+ wth_verbose("surface [%p]\n", surface);
+ wth_verbose("shm_window [%p]\n\n\n", surface->shm_window);
+ wth_verbose("----------------------------------\n");
+
+ surface->ivi_id = ivi_id + 100;
+ surface->shm_window->id_ivisurf = surface->ivi_id;
+ struct ivisurface *ivisurf;
+
+ ivisurf = zalloc(sizeof *ivisurf);
+ if (!ivisurf) {
+ return;
+ }
+
+ ivisurf->obj = obj;
+ ivisurf->surf = surface;
+
+ wth_server_weston_main(surface->shm_window);
+
+ while (!surface->shm_window->ready)
+ usleep(1);
+
+ wthp_ivi_surface_set_interface(obj, &wthp_ivi_surface_implementation,
+ ivisurf);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_ivi_application_interface wthp_ivi_application_implementation = {
+ wthp_ivi_application_surface_create,
+};
+
+static void
+client_bind_wthp_ivi_application(struct client *c, struct wthp_ivi_application *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct application *app;
+
+ app = zalloc(sizeof *app);
+ if (!app) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ app->obj = obj;
+ app->client = c;
+ wl_list_insert(&c->compositor_list, &app->link);
+
+ wthp_ivi_application_set_interface(obj, &wthp_ivi_application_implementation,
+ app);
+ wth_verbose("client %p bound wthp_ivi_application\n", c);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * APIs to send pointer events to waltham client
+ */
+
+void
+waltham_pointer_enter(struct window *window, uint32_t serial,
+ wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wth_verbose("waltham_pointer_enter [%d]\n", window->server_surf->ivi_id);
+
+ wthp_pointer_send_enter (pointer->obj, serial, surface->obj, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_leave(struct window *window, uint32_t serial)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wth_verbose("waltham_pointer_leave [%d]\n", window->server_surf->ivi_id);
+
+ wthp_pointer_send_leave (pointer->obj, serial, surface->obj);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_motion(struct window *window, uint32_t time,
+ wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wthp_pointer_send_motion (pointer->obj, time, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_button(struct window *window, uint32_t serial,
+ uint32_t time, uint32_t button,
+ uint32_t state)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wthp_pointer_send_button (pointer->obj, serial, time, button, state);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_pointer_axis(struct window *window, uint32_t time,
+ uint32_t axis, wl_fixed_t value)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct pointer *pointer = seat->pointer;
+
+ wthp_pointer_send_axis (pointer->obj, time, axis, value);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+/*
+ * waltham pointer implementation
+ */
+static void
+pointer_set_cursor(struct wthp_pointer *wthp_pointer, int32_t serial, struct wthp_surface *surface,
+ int32_t hotspot_x, int32_t hotspot_y)
+{
+ struct pointer *pointer = wth_object_get_user_data((struct wth_object *)wthp_pointer);
+
+ wth_verbose("wthp_pointer %p (%d, %p, %d, %d)\n",
+ wthp_pointer, serial, surface, hotspot_x, hotspot_y);
+
+}
+
+static void
+pointer_release(struct wthp_pointer *wthp_pointer)
+{
+ struct pointer *pointer = wth_object_get_user_data((struct wth_object *)wthp_pointer);
+
+ wth_verbose("wthp_pointer %p\n",wthp_pointer);
+}
+
+static const struct wthp_pointer_interface pointer_implementation = {
+ pointer_set_cursor,
+ pointer_release
+};
+
+/*
+ * APIs to send touch events to waltham client
+ */
+
+void
+waltham_touch_down(struct window *window, uint32_t serial,
+ uint32_t time, int32_t id,
+ wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wth_verbose("touch_handle_down surface [%d]\n", surface->ivi_id);
+ wthp_touch_send_down(touch->obj, serial, time, surface->obj, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_up(struct window *window, uint32_t serial,
+ uint32_t time, int32_t id)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_up(touch->obj, serial, time, id);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_motion(struct window *window, uint32_t time,
+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_motion(touch->obj, time, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_frame(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_frame(touch->obj);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+void
+waltham_touch_cancel(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat = window->server_seat;
+ struct touch *touch = seat->touch;
+
+ wthp_touch_send_cancel(touch->obj);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+/*
+ * waltham touch implementation
+ */
+static void
+touch_release(struct wthp_touch *wthp_touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct touch *touch = wth_object_get_user_data((struct wth_object *)wthp_touch);
+
+ wth_verbose("%p\n",wthp_touch);
+}
+
+static const struct wthp_touch_interface touch_implementation = {
+ touch_release,
+};
+
+/*
+ * waltham seat implementation
+ */
+static void
+seat_get_pointer(struct wthp_seat *wthp_seat, struct wthp_pointer *wthp_pointer)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("wthp_seat %p get_pointer(%p)\n",
+ wthp_seat, wthp_pointer);
+
+ struct seat *seat = wth_object_get_user_data((struct wth_object *)wthp_seat);
+ struct pointer *pointer;
+
+ pointer = zalloc(sizeof *pointer);
+ if (!pointer) {
+ client_post_out_of_memory(seat->client);
+ return;
+ }
+
+ pointer->obj = wthp_pointer;
+ pointer->seat = seat;
+ seat->pointer = pointer;
+ wl_list_insert(&seat->client->pointer_list, &pointer->link);
+
+ wthp_pointer_set_interface(wthp_pointer, &pointer_implementation, pointer);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+seat_get_touch(struct wthp_seat *wthp_seat, struct wthp_touch *wthp_touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("wthp_seat %p get_touch(%p)\n",
+ wthp_seat, wthp_touch);
+
+ struct seat *seat = wth_object_get_user_data((struct wth_object *)wthp_seat);
+ struct touch *touch;
+
+ touch = zalloc(sizeof *touch);
+ if (!touch) {
+ client_post_out_of_memory(seat->client);
+ return;
+ }
+
+ touch->obj = wthp_touch;
+ touch->seat = seat;
+ seat->touch = touch;
+ wl_list_insert(&seat->client->touch_list, &touch->link);
+
+ wthp_touch_set_interface(wthp_touch, &touch_implementation, touch);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+seat_release(struct wthp_seat *wthp_seat)
+{
+}
+
+static const struct wthp_seat_interface seat_implementation = {
+ seat_get_pointer,
+ NULL,
+ seat_get_touch,
+ seat_release //,
+ //NULL
+};
+
+static void
+seat_send_updated_caps(struct seat *seat)
+{
+ wth_verbose("%s >>> \n",__func__);
+ enum wthp_seat_capability caps = 0;
+
+ caps |= WTHP_SEAT_CAPABILITY_POINTER;
+ wth_verbose("WTHP_SEAT_CAPABILITY_POINTER %d\n", caps);
+
+ caps |= WTHP_SEAT_CAPABILITY_TOUCH;
+ wth_verbose("WTHP_SEAT_CAPABILITY_TOUCH %d\n", caps);
+
+ wthp_seat_send_capabilities(seat->obj, caps);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+client_bind_seat(struct client *c, struct wthp_seat *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct seat *seat;
+
+ seat = zalloc(sizeof *seat);
+ if (!seat) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ seat->obj = obj;
+ seat->client = c;
+ wl_list_insert(&c->seat_list, &seat->link);
+ wth_verbose("wthp_seat object=%p and seat=%p\n",obj,seat);
+ wthp_seat_set_interface(obj, &seat_implementation,
+ seat);
+ wth_verbose("client %p bound wthp_seat\n", c);
+ seat_send_updated_caps(seat);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * waltham region implementation
+ */
+
+static void
+region_destroy(struct region *region)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("region %p destroy\n", region->obj);
+
+ wthp_region_free(region->obj);
+ wl_list_remove(&region->link);
+ free(region);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+region_handle_destroy(struct wthp_region *wthp_region)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct region *region = wth_object_get_user_data((struct wth_object *)wthp_region);
+
+ assert(wthp_region == region->obj);
+
+ region_destroy(region);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+region_handle_add(struct wthp_region *wthp_region,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ wth_verbose("region %p add(%d, %d, %d, %d)\n",
+ wthp_region, x, y, width, height);
+}
+
+static void
+region_handle_subtract(struct wthp_region *wthp_region,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ wth_verbose("region %p subtract(%d, %d, %d, %d)\n",
+ wthp_region, x, y, width, height);
+}
+
+static const struct wthp_region_interface region_implementation = {
+ region_handle_destroy,
+ region_handle_add,
+ region_handle_subtract
+};
+
+/*
+ * waltham compositor implementation
+ */
+static void
+compositor_destroy(struct compositor *comp)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("%s: %p\n", __func__, comp->obj);
+
+ wthp_compositor_free(comp->obj);
+ wl_list_remove(&comp->link);
+ free(comp);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+extern struct window g_window; // @@@@@
+static void
+compositor_handle_create_surface(struct wthp_compositor *compositor,
+ struct wthp_surface *id)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct compositor *comp = wth_object_get_user_data((struct wth_object *)compositor);
+ struct client *client = comp->client;
+ struct surface *surface;
+ struct seat *seat, *tmp;
+
+ wth_verbose("client %p create surface %p\n",
+ comp->client, id);
+
+ surface = zalloc(sizeof *surface);
+ if (!surface) {
+ client_post_out_of_memory(comp->client);
+ return;
+ }
+
+ surface->obj = id;
+ wl_list_insert(&comp->client->surface_list, &surface->link);
+
+ wthp_surface_set_interface(id, &surface_implementation, surface);
+
+// surface->shm_window = calloc(1, sizeof *surface->shm_window);
+ surface->shm_window = &g_window;
+ if (!surface->shm_window)
+ return;
+
+ surface->shm_window->server_surf = surface;
+ surface->shm_window->ready = false;
+ surface->ivi_id = 0;
+
+ wl_list_for_each_safe(seat, tmp, &client->seat_list, link) {
+ surface->shm_window->server_seat = seat;
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+compositor_handle_create_region(struct wthp_compositor *compositor,
+ struct wthp_region *id)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct compositor *comp = wth_object_get_user_data((struct wth_object *)compositor);
+ struct region *region;
+
+ wth_verbose("client %p create region %p\n",
+ comp->client, id);
+
+ region = zalloc(sizeof *region);
+ if (!region) {
+ client_post_out_of_memory(comp->client);
+ return;
+ }
+
+ region->obj = id;
+ wl_list_insert(&comp->client->region_list, &region->link);
+
+ wthp_region_set_interface(id, &region_implementation, region);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_compositor_interface compositor_implementation = {
+ compositor_handle_create_surface,
+ compositor_handle_create_region
+};
+
+static void
+client_bind_compositor(struct client *c, struct wthp_compositor *obj)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct compositor *comp;
+
+ comp = zalloc(sizeof *comp);
+ if (!comp) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ comp->obj = obj;
+ comp->client = c;
+ wl_list_insert(&c->compositor_list, &comp->link);
+
+ wthp_compositor_set_interface(obj, &compositor_implementation,
+ comp);
+ wth_verbose("client %p bound wthp_compositor\n", c);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * waltham registry implementation
+ */
+static void
+registry_destroy(struct registry *reg)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_verbose("%s: %p\n", __func__, reg->obj);
+
+ wthp_registry_free(reg->obj);
+ wl_list_remove(&reg->link);
+ free(reg);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+registry_handle_destroy(struct wthp_registry *registry)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct registry *reg = wth_object_get_user_data((struct wth_object *)registry);
+
+ registry_destroy(reg);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+registry_handle_bind(struct wthp_registry *registry,
+ uint32_t name,
+ struct wth_object *id,
+ const char *interface,
+ uint32_t version)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct registry *reg = wth_object_get_user_data((struct wth_object *)registry);
+ wth_verbose("Recieved registry : %s\n", interface);
+
+ if (strcmp(interface, "wthp_compositor") == 0) {
+ client_bind_compositor(reg->client, (struct wthp_compositor *)id);
+ } else if (strcmp(interface, "wthp_blob_factory") == 0) {
+ client_bind_blob_factory(reg->client, (struct wthp_blob_factory *)id);
+ struct client *client = reg->client;
+ struct seat *seat, *tmp,*get_seat;
+ wl_list_for_each_safe(seat, tmp, &client->seat_list, link) {
+ get_seat = seat;
+ }
+ wth_verbose("get_seat : %p\n", get_seat);
+ seat_send_updated_caps(get_seat);
+ } else if (strcmp(interface, "wthp_ivi_application") == 0) {
+ client_bind_wthp_ivi_application(reg->client, (struct wthp_ivi_application *)id);
+ } else if (strcmp(interface, "wthp_seat") == 0) {
+ client_bind_seat(reg->client, (struct wthp_seat *)id);
+ } else {
+ wth_object_post_error((struct wth_object *)registry, 0,
+ "%s: unknown name %u", __func__, name);
+ wth_object_delete(id);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wthp_registry_interface registry_implementation = {
+ registry_handle_destroy,
+ registry_handle_bind
+};
+
+/*
+ * waltham display implementation
+ */
+
+static void
+display_handle_client_version(struct wth_display *wth_display,
+ uint32_t client_version)
+{
+ wth_verbose("%s >>> \n",__func__);
+ wth_object_post_error((struct wth_object *)wth_display, 0,
+ "unimplemented: %s", __func__);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+display_handle_sync(struct wth_display * wth_display, struct wthp_callback * callback)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c = wth_object_get_user_data((struct wth_object *)wth_display);
+
+ wth_verbose("Client %p requested wth_display.sync\n", c);
+ wthp_callback_send_done(callback, 0);
+ wthp_callback_free(callback);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+display_handle_get_registry(struct wth_display *wth_display,
+ struct wthp_registry *registry)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c = wth_object_get_user_data((struct wth_object *)wth_display);
+ struct registry *reg;
+
+ reg = zalloc(sizeof *reg);
+ if (!reg) {
+ client_post_out_of_memory(c);
+ return;
+ }
+
+ reg->obj = registry;
+ reg->client = c;
+ wl_list_insert(&c->registry_list, &reg->link);
+ wthp_registry_set_interface(registry,
+ &registry_implementation, reg);
+
+ wthp_registry_send_global(registry, 1, "wthp_compositor", 4);
+ wthp_registry_send_global(registry, 1, "wthp_ivi_application", 1);
+ wthp_registry_send_global(registry, 1, "wthp_seat", 4);
+ wthp_registry_send_global(registry, 1, "wthp_blob_factory", 4);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+const struct wth_display_interface display_implementation = {
+ display_handle_client_version,
+ display_handle_sync,
+ display_handle_get_registry
+};
+
+/*
+ * functions to handle waltham client connections
+ */
+static void
+connection_handle_data(struct watch *w, uint32_t events)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c = container_of(w, struct client, conn_watch);
+ int ret;
+
+ if (events & EPOLLERR) {
+ wth_error("Client %p errored out.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+
+ if (events & EPOLLHUP) {
+ wth_error("Client %p hung up.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+
+ if (events & EPOLLOUT) {
+ ret = wth_connection_flush(c->connection);
+ if (ret == 0)
+ watch_ctl(&c->conn_watch, EPOLL_CTL_MOD, EPOLLIN);
+ else if (ret < 0 && errno != EAGAIN){
+ wth_error("Client %p flush error.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+ }
+
+ if (events & EPOLLIN) {
+ ret = wth_connection_read(c->connection);
+ if (ret < 0) {
+ wth_error("Client %p read error.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+
+ ret = wth_connection_dispatch(c->connection);
+ if (ret < 0 && errno != EPROTO) {
+ wth_error("Client %p dispatch error.\n", c);
+ client_destroy(c);
+
+ return;
+ }
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/**
+* client_create
+*
+* Create new client connection
+*
+* @param srv Server structure
+* @param wth_connection Waltham connection handle
+* @return Pointer to client structure
+*/
+static struct client *
+client_create(struct server *srv, struct wth_connection *conn)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c;
+ struct wth_display *disp;
+
+ c = zalloc(sizeof *c);
+ if (!c)
+ return NULL;
+
+ c->server = srv;
+ c->connection = conn;
+
+ c->conn_watch.server = srv;
+ c->conn_watch.fd = wth_connection_get_fd(conn);
+ c->conn_watch.cb = connection_handle_data;
+ if (watch_ctl(&c->conn_watch, EPOLL_CTL_ADD, EPOLLIN) < 0) {
+ free(c);
+ return NULL;
+ }
+
+ wth_verbose("Client %p connected.\n", c);
+
+ wl_list_insert(&srv->client_list, &c->link);
+
+ wl_list_init(&c->registry_list);
+ wl_list_init(&c->compositor_list);
+ wl_list_init(&c->seat_list);
+ wl_list_init(&c->pointer_list);
+ wl_list_init(&c->touch_list);
+ wl_list_init(&c->region_list);
+ wl_list_init(&c->surface_list);
+ wl_list_init(&c->buffer_list);
+
+ disp = wth_connection_get_display(c->connection);
+ wth_display_set_interface(disp, &display_implementation, c);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return c;
+}
+
+/**
+* client_destroy
+*
+* Destroy client connection
+*
+* @param names struct client *c
+* @param value client data
+* @return none
+*/
+void
+client_destroy(struct client *c)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct region *region;
+ struct compositor *comp;
+ struct registry *reg;
+ struct surface *surface;
+
+ wth_verbose("Client %p disconnected.\n", c);
+
+ /* clean up remaining client resources in case the client
+ * did not.
+ */
+ wl_list_last_until_empty(region, &c->region_list, link)
+ region_destroy(region);
+
+ wl_list_last_until_empty(comp, &c->compositor_list, link)
+ compositor_destroy(comp);
+
+ wl_list_last_until_empty(reg, &c->registry_list, link)
+ registry_destroy(reg);
+
+ wl_list_last_until_empty(surface, &c->surface_list, link)
+ surface_destroy(surface);
+
+ wl_list_remove(&c->link);
+ watch_ctl(&c->conn_watch, EPOLL_CTL_DEL, 0);
+ wth_connection_destroy(c->connection);
+ free(c);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/**
+* server_flush_clients
+*
+* write all the pending requests from the clients to socket
+*
+* @param names struct server *srv
+* @param value socket connection info and client data
+* @return none
+*/
+void
+server_flush_clients(struct server *srv)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *c, *tmp;
+ int ret;
+
+ wl_list_for_each_safe(c, tmp, &srv->client_list, link) {
+ /* Flush out buffered requests. If the Waltham socket is
+ * full, poll it for writable too.
+ */
+ ret = wth_connection_flush(c->connection);
+ if (ret < 0 && errno == EAGAIN) {
+ watch_ctl(&c->conn_watch, EPOLL_CTL_MOD, EPOLLIN | EPOLLOUT);
+ } else if (ret < 0) {
+ perror("Connection flush failed");
+ client_destroy(c);
+ return;
+ }
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+
+}
+
+/**
+* server_accept_client
+*
+* Accepts new waltham client connection and instantiates client structure
+*
+* @param names struct server *srv
+* @param value socket connection info and client data
+* @return none
+*/
+void
+server_accept_client(struct server *srv)
+{
+ wth_verbose("%s >>> \n",__func__);
+ struct client *client;
+ struct wth_connection *conn;
+ struct sockaddr_in addr;
+ socklen_t len;
+
+ len = sizeof addr;
+ conn = wth_accept(srv->listen_fd, (struct sockaddr *)&addr, &len);
+ if (!conn) {
+ wth_error("Failed to accept a connection.\n");
+ return;
+ }
+
+ client = client_create(srv, conn);
+ if (!client) {
+ wth_error("Failed client_create().\n");
+ return;
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
diff --git a/demo3/horizontal/waltham-server/src/wth-server-weston.c b/demo3/horizontal/waltham-server/src/wth-server-weston.c
new file mode 100644
index 0000000..6cc309c
--- /dev/null
+++ b/demo3/horizontal/waltham-server/src/wth-server-weston.c
@@ -0,0 +1,811 @@
+/**
+ * @licence app begin@
+ *
+ *
+ * TBD
+ *
+ *
+ * @licence end@
+ */
+/*******************************************************************************
+** **
+** SRC-MODULE: **
+** **
+** TARGET : linux **
+** **
+** PROJECT : waltham-server **
+** **
+** AUTHOR : **
+** **
+** **
+** **
+** PURPOSE : This file is acts as interface to weston compositor at server **
+** side **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+#include <sys/mman.h>
+#include <signal.h>
+#include <sys/time.h>
+
+#include "wth-server-weston.h"
+#include "os-compatibility.h"
+#include "ivi-application-client-protocol.h"
+#include "bitmap.h"
+
+
+static int running = 1;
+extern bool get_verbosity(void);
+extern int verbose;
+/*
+ * buffer callback
+ */
+static void
+buffer_release(void *data, struct wl_buffer *buffer)
+{
+ struct shm_buffer *mybuf = data;
+
+ wth_verbose("%s >>> \n",__func__);
+
+ mybuf->busy = 0;
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+ buffer_release
+};
+
+static int
+create_shm_buffer(struct display *display, struct shm_buffer *buffer,
+ int width, int height, uint32_t format)
+{
+ struct wl_shm_pool *pool;
+ int fd, size, stride;
+ void *data;
+
+ wth_verbose("%s >>> \n",__func__);
+ stride = width * 4;
+ size = stride * height;
+
+ fd = os_create_anonymous_file(size);
+ if (fd < 0) {
+ wth_error("creating a buffer file for %d B failed: %m\n",
+ size);
+ return -1;
+ }
+
+ data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (data == MAP_FAILED) {
+ wth_error("mmap failed: %m\n");
+ close(fd);
+ return -1;
+ }
+
+ pool = wl_shm_create_pool(display->shm, fd, size);
+ buffer->buffer = wl_shm_pool_create_buffer(pool, 0,
+ width, height,
+ stride, format);
+ wl_buffer_add_listener(buffer->buffer, &buffer_listener, buffer);
+ wl_shm_pool_destroy(pool);
+ close(fd);
+
+ buffer->shm_data = data;
+
+ wth_verbose(" <<< %s \n",__func__);
+ return 0;
+}
+
+/*
+ * ivi surface callback
+ */
+static void
+handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface,
+ int32_t width, int32_t height)
+{
+ /* Simple-shm is resizable */
+}
+
+static const struct ivi_surface_listener ivi_surface_listener = {
+ handle_ivi_surface_configure,
+};
+
+static void
+create_window(struct window *window, struct display *display, int width, int height)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ window->callback = NULL;
+ window->display = display;
+ window->width = width;
+ window->height = height;
+ window->surface = wl_compositor_create_surface(display->compositor);
+ window->window_frames = 0;
+ window->window_benchmark_time = 0;
+
+ wl_display_roundtrip(display->display);
+ if (display->ivi_application ) {
+ uint32_t id_ivisurf = window->id_ivisurf;
+ window->ivi_surface =
+ ivi_application_surface_create(display->ivi_application,
+ id_ivisurf, window->surface);
+ if (window->ivi_surface == NULL) {
+ wth_error("Failed to create ivi_client_surface\n");
+ abort();
+ }
+
+ ivi_surface_add_listener(window->ivi_surface,
+ &ivi_surface_listener, window);
+
+ } else {
+ assert(0);
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+ return;
+}
+
+static void
+destroy_window(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ if (window->callback)
+ wl_callback_destroy(window->callback);
+
+ if (window->buffers[0].buffer)
+ wl_buffer_destroy(window->buffers[0].buffer);
+ if (window->buffers[1].buffer)
+ wl_buffer_destroy(window->buffers[1].buffer);
+
+ wl_surface_destroy(window->surface);
+ free(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static struct shm_buffer *
+window_next_buffer(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct shm_buffer *buffer;
+ int ret = 0;
+
+ if (!window->buffers[0].busy)
+ buffer = &window->buffers[0];
+ else if (!window->buffers[1].busy)
+ buffer = &window->buffers[1];
+ else {
+ window->buffers[0].busy = 0;
+ window->buffers[0].busy = 1;
+ buffer = &window->buffers[0];
+ }
+
+ if (!buffer->buffer) {
+ ret = create_shm_buffer(window->display, buffer,
+ window->width, window->height,
+ WL_SHM_FORMAT_XRGB8888);
+
+ if (ret < 0)
+ return NULL;
+
+ /* paint the padding */
+ memset(buffer->shm_data, 0xff,
+ window->width * window->height * 4);
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+ return buffer;
+}
+
+static void
+paint_pixels(void *image, int padding, int width, int height, uint32_t time)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ const int halfh = padding + (height - padding * 2) / 2;
+ const int halfw = padding + (width - padding * 2) / 2;
+ int ir, or;
+ uint32_t *pixel = image;
+ int y;
+
+ /* squared radii thresholds */
+ or = (halfw < halfh ? halfw : halfh) - 8;
+ ir = or - 32;
+ or *= or;
+ ir *= ir;
+
+ pixel += padding * width;
+ for (y = padding; y < height - padding; y++) {
+ int x;
+ int y2 = (y - halfh) * (y - halfh);
+
+ pixel += padding;
+ for (x = padding; x < width - padding; x++) {
+ uint32_t v;
+
+ /* squared distance from center */
+ int r2 = (x - halfw) * (x - halfw) + y2;
+
+ if (r2 < ir)
+ v = (r2 / 32 + time / 64) * 0x0080401;
+ else if (r2 < or)
+ v = (y + time / 32) * 0x0080401;
+ else
+ v = (x + time / 16) * 0x0080401;
+ v &= 0x00ffffff;
+
+ /* cross if compositor uses X from XRGB as alpha */
+ if (abs(x - y) > 6 && abs(x + y - height) > 6)
+ v |= 0xff000000;
+
+ *pixel++ = v;
+ }
+
+ pixel += padding;
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+void
+wth_server_weston_shm_attach(struct window *window, uint32_t data_sz, void * data,
+ int32_t width, int32_t height, int32_t stride, uint32_t format)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct timeval tv;
+ uint32_t time;
+ struct shm_buffer *buffer;
+ static int ss_count = 0;
+
+ gettimeofday(&tv, NULL);
+ time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+
+ buffer = window_next_buffer(window);
+ if (!buffer) {
+ wth_error("Both buffers busy at redraw().\n");
+ return;
+ }
+
+ char *bitmap;
+ bitmap = getenv("BITMAP");
+ if (bitmap) {
+ if (!strcmp(bitmap, "1")) {
+ int len;
+ const char *path = "/tmp/bitmap";
+ len = strlen(path);
+ char *filename;
+ filename = (char *)malloc(len + 10);
+ sprintf(filename, "%s%d.bmp", path, ss_count);
+ wth_verbose("%s\n", filename);
+
+ save_as_bitmap(filename, data, data_sz, width, height, format);
+ ss_count++;
+ free(filename);
+ }
+ }
+ buffer->shm_data = data;
+ window->width = width;
+ window->height = height;
+ paint_pixels(buffer->shm_data, 20, window->width, window->height, time);
+
+ wl_surface_attach(window->surface, buffer->buffer, 0, 0);
+
+ buffer->busy = 1;
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+void
+wth_server_weston_shm_damage(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wl_surface_damage(window->surface,
+ 0, 0, window->width, window->height);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+void
+wth_server_weston_shm_commit(struct window *window)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ static const uint32_t benchmark_interval = 5;
+ struct timeval tv;
+ uint32_t time;
+
+ gettimeofday(&tv, NULL);
+ time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+ if (window->window_frames == 0)
+ window->window_benchmark_time = time;
+ if (time - window->window_benchmark_time > (benchmark_interval * 1000)) {
+ wth_verbose("-------------------------------%d frames in %d seconds: %f fps\n",
+ window->window_frames,
+ benchmark_interval,
+ (float) window->window_frames / benchmark_interval);
+
+ window->window_benchmark_time = time;
+ window->window_frames = 0;
+ }
+
+ wl_surface_commit(window->surface);
+
+ wl_display_flush(window->display->display);
+
+ if (window->wait)
+ window->wait = 0;
+
+ window->window_frames++;
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * frame callback function - this function will display buffer to surface
+ */
+
+static const struct wl_callback_listener frame_listener;
+static void
+redraw(void *data, struct wl_callback *callback, uint32_t time)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct window *window = data;
+ struct shm_buffer *buffer;
+
+ buffer = window_next_buffer(window);
+ if (!buffer) {
+ if(!callback)
+ {
+ wth_error("Failed to create the first buffer.\n");
+ }
+ else
+ {
+ wth_error("Both buffers busy at redraw(). Server bug?\n");
+ }
+ abort();
+ }
+
+ paint_pixels(buffer->shm_data, 20, window->width, window->height, time);
+
+ wl_surface_attach(window->surface, buffer->buffer, 0, 0);
+ wl_surface_damage(window->surface,
+ 20, 20, window->width - 40, window->height - 40);
+
+ if (callback)
+ wl_callback_destroy(callback);
+
+ window->callback = wl_surface_frame(window->surface);
+ wl_callback_add_listener(window->callback, &frame_listener, window);
+ wl_surface_commit(window->surface);
+ buffer->busy = 1;
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_callback_listener frame_listener = {
+ redraw
+};
+
+/*
+ * shm callbcak function
+ */
+
+static void
+shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *d = data;
+
+ if (format == WL_SHM_FORMAT_XRGB8888)
+ d->has_xrgb = true;
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+struct wl_shm_listener shm_listener = {
+ shm_format
+};
+
+/*
+ * pointer callbcak functions
+ */
+static void
+pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
+ uint32_t serial, struct wl_surface *wl_surface,
+ wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("data [%p]\n", data);
+
+ struct display *display = data;
+ struct window *window = display->window;
+ struct surface *surface = window->server_surf;
+ struct seat *seat = window->server_seat;
+
+ waltham_pointer_enter(window, serial, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_leave(void *data, struct wl_pointer *pointer,
+ uint32_t serial, struct wl_surface *surface)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ wth_verbose("data [%p]\n", data);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_leave(window, serial);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_motion(void *data, struct wl_pointer *pointer,
+ uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_motion(window, time, sx, sy);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
+ uint32_t serial, uint32_t time, uint32_t button,
+ uint32_t state)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_button(window, serial, time, button, state);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
+ uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_pointer_axis(window, time, axis, value);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+ pointer_handle_enter,
+ pointer_handle_leave,
+ pointer_handle_motion,
+ pointer_handle_button,
+ pointer_handle_axis,
+};
+
+/*
+ * touch callbcak functions
+ */
+
+static void
+touch_handle_down(void *data, struct wl_touch *touch, uint32_t serial,
+ uint32_t time, struct wl_surface *surface, int32_t id,
+ wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ int x = (int)wl_fixed_to_double(x_w);
+ int y = (int)wl_fixed_to_double(y_w);
+ wth_verbose("%p x %d y %d\n",window, x, y);
+
+ waltham_touch_down(window, serial, time, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_up(void *data, struct wl_touch *touch, uint32_t serial,
+ uint32_t time, int32_t id)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_up(window, serial, time, id);
+}
+
+static void
+touch_handle_motion(void *data, struct wl_touch *touch, uint32_t time,
+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_motion(window, time, id, x_w, y_w);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_frame(void *data, struct wl_touch *touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_frame(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+touch_handle_cancel(void *data, struct wl_touch *touch)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+ struct window *window = display->window;
+
+ waltham_touch_cancel(window);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_touch_listener touch_listener = {
+ touch_handle_down,
+ touch_handle_up,
+ touch_handle_motion,
+ touch_handle_frame,
+ touch_handle_cancel
+};
+
+/*
+ * seat callback
+ */
+static void
+seat_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display = data;
+
+ wth_verbose("caps = %d\n", caps);
+
+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !display->wl_pointer)
+ {
+ wth_verbose("WL_SEAT_CAPABILITY_POINTER\n");
+ display->wl_pointer = wl_seat_get_pointer(wl_seat);
+ wl_pointer_set_user_data(display->wl_pointer, display);
+ wl_pointer_add_listener(display->wl_pointer, &pointer_listener, display);
+ wl_display_roundtrip(display->display);
+ } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && display->wl_pointer) {
+ wth_verbose("!WL_SEAT_CAPABILITY_POINTER\n");
+ wl_pointer_destroy(display->wl_pointer);
+ display->wl_pointer = NULL;
+ }
+
+ if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !display->wl_touch)
+ {
+ wth_verbose("WL_SEAT_CAPABILITY_TOUCH\n");
+ display->wl_touch = wl_seat_get_touch(wl_seat);
+ wl_touch_set_user_data(display->wl_touch, display);
+ wl_touch_add_listener(display->wl_touch, &touch_listener, display);
+ wl_display_roundtrip(display->display);
+ } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && display->wl_touch) {
+ wth_verbose("!WL_SEAT_CAPABILITY_TOUCH\n");
+ wl_touch_destroy(display->wl_touch);
+ display->wl_touch = NULL;
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static const struct wl_seat_listener seat_listener = {
+ seat_capabilities,
+ NULL
+};
+
+static void
+add_seat(struct display *display, uint32_t id, uint32_t version)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ display->wl_pointer = NULL;
+ display->seat = wl_registry_bind(display->registry, id,
+ &wl_seat_interface, 1);
+ wl_seat_add_listener(display->seat, &seat_listener, display);
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+/*
+ * registry callback
+ */
+static void
+registry_handle_global(void *data, struct wl_registry *registry,
+ uint32_t id, const char *interface, uint32_t version)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *d = data;
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ d->compositor =
+ wl_registry_bind(registry,
+ id, &wl_compositor_interface, 1);
+ } else if (strcmp(interface, "wl_shm") == 0) {
+ d->shm = wl_registry_bind(registry,
+ id, &wl_shm_interface, 1);
+ wl_shm_add_listener(d->shm, &shm_listener, d);
+ } else if (strcmp(interface, "ivi_application") == 0) {
+ d->ivi_application =
+ wl_registry_bind(registry, id,
+ &ivi_application_interface, 1);
+ } else if (strcmp(interface, "wl_seat") == 0) {
+ add_seat(d, id, version);
+ }
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+ uint32_t name)
+{
+}
+
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ registry_handle_global_remove
+};
+
+static struct display *
+create_display(void)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct display *display;
+
+ display = malloc(sizeof *display);
+ if (display == NULL) {
+ wth_error("out of memory\n");
+ exit(1);
+ }
+ display->display = wl_display_connect(NULL);
+ assert(display->display);
+
+ display->has_xrgb = false;
+ display->registry = wl_display_get_registry(display->display);
+ wl_registry_add_listener(display->registry,
+ &registry_listener, display);
+ wl_display_roundtrip(display->display);
+ if (display->shm == NULL) {
+ wth_error("No wl_shm global\n");
+ exit(1);
+ }
+
+ wl_display_roundtrip(display->display);
+
+ if (!display->has_xrgb) {
+ wth_error("WL_SHM_FORMAT_XRGB32 not available\n");
+ exit(1);
+ }
+
+ wth_verbose(" <<< %s \n",__func__);
+ return display;
+}
+
+static void
+destroy_display(struct display *display)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ if (display->shm)
+ wl_shm_destroy(display->shm);
+
+ if (display->compositor)
+ wl_compositor_destroy(display->compositor);
+
+ wl_registry_destroy(display->registry);
+ wl_display_flush(display->display);
+ wl_display_disconnect(display->display);
+ free(display);
+
+ wth_verbose(" <<< %s \n",__func__);
+}
+
+static void
+signal_int(int signum)
+{
+ running = 0;
+}
+
+/**
+* wth_server_weston_main
+*
+* This is the main function which will handle connection to the compositor at server side
+*
+* @param names void *data
+* @param value struct window data
+* @return 0 on success, -1 on error
+*/
+int
+wth_server_weston_main(void *data)
+{
+ wth_verbose("%s >>> \n",__func__);
+
+ struct window *window = (struct window *) data;
+ struct sigaction sigint;
+ struct display *display;
+ int ret = 0;
+
+ display = create_display();
+ create_window(window, display, 400, 400);
+ if (!window)
+ return -1;
+ wl_display_roundtrip(display->display);
+ wth_verbose("data %p\n", data);
+ wth_verbose("window %p\n", window);
+
+ display->window = window;
+
+ sigint.sa_handler = signal_int;
+ sigemptyset(&sigint.sa_mask);
+ sigint.sa_flags = SA_RESETHAND;
+ sigaction(SIGINT, &sigint, NULL);
+
+ /* Initialise damage to full surface, so the padding gets painted */
+ wl_surface_damage(window->surface, 0, 0,
+ window->width, window->height);
+
+ redraw(window, NULL, 0);
+
+ window->wait = 1;
+ window->ready = true;
+ while (window->wait)
+ {
+ ret = wl_display_dispatch(display->display);
+ usleep(1);
+ }
+ wth_verbose("debug\n");
+ while (running && ret != -1)
+ ret = wl_display_dispatch(display->display);
+
+ wth_verbose("wth_server_weston_main exiting\n");
+
+ if (window->display->ivi_application) {
+ ivi_surface_destroy(window->ivi_surface);
+ ivi_application_destroy(window->display->ivi_application);
+ }
+
+ destroy_window(window);
+ destroy_display(display);
+
+ wth_verbose(" <<< %s \n",__func__);
+ return 0;
+}