summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ivi-layermanagement-examples/simple-weston-client/CMakeLists.txt57
-rw-r--r--ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c383
-rw-r--r--weston-ivi-shell/src/ivi-controller.c9
-rw-r--r--weston-ivi-shell/src/ivi-controller.h1
4 files changed, 447 insertions, 3 deletions
diff --git a/ivi-layermanagement-examples/simple-weston-client/CMakeLists.txt b/ivi-layermanagement-examples/simple-weston-client/CMakeLists.txt
index 8a29d96..b34633e 100644
--- a/ivi-layermanagement-examples/simple-weston-client/CMakeLists.txt
+++ b/ivi-layermanagement-examples/simple-weston-client/CMakeLists.txt
@@ -22,6 +22,18 @@ project (simple-weston-client)
find_package(PkgConfig)
pkg_check_modules(WAYLAND_CLIENT wayland-client REQUIRED)
pkg_check_modules(WAYLAND_CURSOR wayland-cursor REQUIRED)
+pkg_check_modules(LIBWESTON_PROTOCOLS libweston-6-protocols QUIET)
+
+if(${LIBWESTON_PROTOCOLS_FOUND})
+ #check for DLT
+ pkg_check_modules(DLT automotive-dlt REQUIRED)
+
+ #import the pkgdatadir from libweston-protocols pkgconfig file
+ execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir libweston-6-protocols
+ OUTPUT_VARIABLE WestonProtocols_PKGDATADIR)
+ string(REGEX REPLACE "[\r\n]" "" WestonProtocols_PKGDATADIR "${WestonProtocols_PKGDATADIR}")
+ SET(LIBWESTON_PROTOCOLS_PKGDATADIR ${WestonProtocols_PKGDATADIR})
+endif(${LIBWESTON_PROTOCOLS_FOUND})
find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
@@ -41,20 +53,49 @@ add_custom_command(
DEPENDS ${CMAKE_SOURCE_DIR}/protocol/ivi-application.xml
)
+if(${LIBWESTON_PROTOCOLS_FOUND})
+ add_custom_command(
+ OUTPUT weston-debug-client-protocol.h
+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} client-header
+ < ${LIBWESTON_PROTOCOLS_PKGDATADIR}/weston-debug.xml
+ > ${CMAKE_CURRENT_BINARY_DIR}/weston-debug-client-protocol.h
+ DEPENDS ${LIBWESTON_PROTOCOLS_PKGDATADIR}/weston-debug.xml
+ )
+
+ add_custom_command(
+ OUTPUT weston-debug-server-protocol.h
+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} server-header
+ < ${LIBWESTON_PROTOCOLS_PKGDATADIR}/weston-debug.xml
+ > ${CMAKE_CURRENT_BINARY_DIR}/weston-debug-server-protocol.h
+ DEPENDS ${LIBWESTON_PROTOCOLS_PKGDATADIR}/weston-debug.xml
+ )
+
+ add_custom_command(
+ OUTPUT weston-debug-protocol.c
+ COMMAND ${WAYLAND_SCANNER_EXECUTABLE} code
+ < ${LIBWESTON_PROTOCOLS_PKGDATADIR}/weston-debug.xml
+ > ${CMAKE_CURRENT_BINARY_DIR}/weston-debug-protocol.c
+ DEPENDS ${LIBWESTON_PROTOCOLS_PKGDATADIR}/weston-debug.xml
+ )
+endif(${LIBWESTON_PROTOCOLS_FOUND})
+
include_directories(
${WAYLAND_CLIENT_INCLUDE_DIR}
${WAYLAND_CURSOR_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
+ ${DLT_INCLUDE_DIR}
)
link_directories(
${WAYLAND_CLIENT_LIBRARY_DIRS}
${WAYLAND_CURSOR_LIBRARY_DIRS}
+ ${DLT_LIBRARY_DIRS}
)
SET(LIBS
${WAYLAND_CLIENT_LIBRARIES}
${WAYLAND_CURSOR_LIBRARIES}
+ ${DLT_LIBRARIES}
)
SET(SRC_FILES
@@ -63,10 +104,24 @@ SET(SRC_FILES
ivi-application-client-protocol.h
)
-add_executable(${PROJECT_NAME} ${SRC_FILES})
+if(${LIBWESTON_PROTOCOLS_FOUND})
+ SET(WESTON_DEBUG_SRC_FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/weston-debug-protocol.c
+ ${CMAKE_CURRENT_BINARY_DIR}/weston-debug-client-protocol.h
+ ${CMAKE_CURRENT_BINARY_DIR}/weston-debug-server-protocol.h
+)
+endif(${LIBWESTON_PROTOCOLS_FOUND})
+
+add_executable(${PROJECT_NAME} ${SRC_FILES} ${WESTON_DEBUG_SRC_FILES})
add_dependencies(${PROJECT_NAME} ${LIBS})
+add_definitions(${DLT_CFLAGS})
+
+if(${LIBWESTON_PROTOCOLS_FOUND})
+ add_definitions(-DLIBWESTON_DEBUG_PROTOCOL)
+endif(${LIBWESTON_PROTOCOLS_FOUND})
+
target_link_libraries(${PROJECT_NAME} ${LIBS})
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
diff --git a/ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c b/ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c
index 5b2c960..4093cf2 100644
--- a/ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c
+++ b/ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c
@@ -27,10 +27,34 @@
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
+#include <assert.h>
+#include <pthread.h>
+#include <signal.h>
+#include <poll.h>
#include <wayland-cursor.h>
#include <ivi-application-client-protocol.h>
+#ifdef LIBWESTON_DEBUG_PROTOCOL
+#include "dlt_common.h"
+#include "dlt_user.h"
+#include "weston-debug-client-protocol.h"
+
+#define WESTON_DLT_APP_DESC "messages from weston debug protocol"
+#define WESTON_DLT_CONTEXT_DESC "weston debug context"
+
+#define WESTON_DLT_APP "WESN"
+#define WESTON_DLT_CONTEXT "WESC"
+
+#define MAXSTRLEN 1024
+#endif
+
+#ifndef MIN
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+#endif
+
+static int running = 1;
+
typedef struct _BkGndSettings
{
uint32_t surface_id;
@@ -56,8 +80,23 @@ typedef struct _WaylandContext {
struct wl_cursor *cursor;
void *bkgnddata;
uint32_t formats;
+#ifdef LIBWESTON_DEBUG_PROTOCOL
+ struct weston_debug_v1 *debug_iface;
+ struct wl_list stream_list;
+ int debug_fd;
+ char thread_running;
+ pthread_t dlt_ctx_thread;
+ int pipefd[2];
+#endif
}WaylandContextStruct;
+struct debug_stream {
+ struct wl_list link;
+ int should_bind;
+ char *name;
+ struct weston_debug_stream_v1 *obj;
+};
+
static const char *left_ptrs[] = {
"left_ptr",
"default",
@@ -88,6 +127,118 @@ get_bkgnd_settings(void)
return bkgnd_settings;
}
+#ifdef LIBWESTON_DEBUG_PROTOCOL
+static struct debug_stream *
+stream_alloc(WaylandContextStruct* wlcontext, const char *name)
+{
+ struct debug_stream *stream;
+
+ stream = calloc(1, (sizeof *stream));
+ if (!stream)
+ return NULL;
+
+ stream->name = strdup(name);
+ if (!stream->name) {
+ free(stream);
+ return NULL;
+ }
+
+ stream->should_bind = 0;
+
+ wl_list_insert(wlcontext->stream_list.prev, &stream->link);
+
+ return stream;
+}
+
+static void
+stream_destroy(struct debug_stream *stream)
+{
+ if (stream->obj)
+ weston_debug_stream_v1_destroy(stream->obj);
+
+ wl_list_remove(&stream->link);
+ free(stream->name);
+ free(stream);
+}
+
+static void
+destroy_streams(WaylandContextStruct* wlcontext)
+{
+ struct debug_stream *stream;
+ struct debug_stream *tmp;
+
+ wl_list_for_each_safe(stream, tmp, &wlcontext->stream_list, link) {
+ stream_destroy(stream);
+ }
+}
+
+static void
+handle_stream_complete(void *data, struct weston_debug_stream_v1 *obj)
+{
+ struct debug_stream *stream = data;
+
+ assert(stream->obj == obj);
+
+ stream_destroy(stream);
+}
+
+static void
+handle_stream_failure(void *data, struct weston_debug_stream_v1 *obj,
+ const char *msg)
+{
+ struct debug_stream *stream = data;
+
+ assert(stream->obj == obj);
+
+ fprintf(stderr, "Debug stream '%s' aborted: %s\n", stream->name, msg);
+
+ stream_destroy(stream);
+}
+
+static const struct weston_debug_stream_v1_listener stream_listener = {
+ handle_stream_complete,
+ handle_stream_failure
+};
+
+static void
+start_streams(WaylandContextStruct* wlcontext)
+{
+ struct debug_stream *stream;
+
+ wl_list_for_each(stream, &wlcontext->stream_list, link) {
+ if (stream->should_bind) {
+ stream->obj = weston_debug_v1_subscribe(wlcontext->debug_iface,
+ stream->name,
+ wlcontext->debug_fd);
+ weston_debug_stream_v1_add_listener(stream->obj,
+ &stream_listener, stream);
+ }
+ }
+}
+
+static void
+get_debug_streams(WaylandContextStruct* wlcontext)
+{
+ char *stream_names;
+ char *stream;
+ const char separator[2] = " ";
+
+ stream_names = getenv("IVI_CLIENT_DEBUG_STREAM_NAMES");
+
+ if(NULL == stream_names)
+ return;
+
+ /* get the first stream */
+ stream = strtok(stream_names, separator);
+
+ /* walk through other streams */
+ while( stream != NULL ) {
+ stream_alloc(wlcontext, stream);
+ stream = strtok(NULL, separator);
+ }
+}
+#endif
+
static void
shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
{
@@ -273,6 +424,30 @@ static struct wl_seat_listener seat_Listener = {
seat_name
};
+#ifdef LIBWESTON_DEBUG_PROTOCOL
+static void
+stream_find(WaylandContextStruct* wlcontext, const char *name, const char *desc)
+{
+ struct debug_stream *stream;
+ wl_list_for_each(stream, &wlcontext->stream_list, link)
+ if (strcmp(stream->name, name) == 0) {
+ stream->should_bind = 1;
+ }
+}
+
+static void
+debug_advertise(void *data, struct weston_debug_v1 *debug, const char *name,
+ const char *desc)
+{
+ WaylandContextStruct* wlcontext = data;
+ stream_find(wlcontext, name, desc);
+}
+
+static const struct weston_debug_v1_listener debug_listener = {
+ debug_advertise
+};
+#endif
+
static void
registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
const char *interface, uint32_t version)
@@ -299,6 +474,21 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
wl_registry_bind(registry, name, &wl_seat_interface, 1);
wl_seat_add_listener(wlcontext->wl_seat, &seat_Listener, data);
}
+#ifdef LIBWESTON_DEBUG_PROTOCOL
+ else if (!strcmp(interface, weston_debug_v1_interface.name)) {
+ uint32_t myver;
+
+ if (wlcontext->debug_iface || wl_list_empty(&wlcontext->stream_list))
+ return;
+
+ myver = MIN(1, version);
+ wlcontext->debug_iface =
+ wl_registry_bind(registry, name,
+ &weston_debug_v1_interface, myver);
+ weston_debug_v1_add_listener(wlcontext->debug_iface, &debug_listener,
+ wlcontext);
+ }
+#endif
}
static void
@@ -338,6 +528,14 @@ int init_wayland_context(WaylandContextStruct* wlcontext)
return -1;
}
+#ifdef LIBWESTON_DEBUG_PROTOCOL
+ if (!wl_list_empty(&wlcontext->stream_list) &&
+ (wlcontext->debug_iface == NULL)) {
+ fprintf(stderr, "WARNING: weston_debug protocol is not available,"
+ " missed enabling --debug option to weston ?\n");
+ }
+#endif
+
return 0;
}
@@ -488,18 +686,148 @@ void destroy_bkgnd_surface(WaylandContextStruct* wlcontext)
wl_surface_destroy(wlcontext->wlBkgndSurface);
}
+#ifdef LIBWESTON_DEBUG_PROTOCOL
+static void *
+weston_dlt_thread_function(void *data)
+{
+ WaylandContextStruct* wlcontext;
+ char apid[DLT_ID_SIZE];
+ char ctid[DLT_ID_SIZE];
+ char *temp;
+ DLT_DECLARE_CONTEXT(weston_dlt_context)
+
+ wlcontext = (WaylandContextStruct*)data;
+
+ /*init dlt*/
+ dlt_set_id(apid, WESTON_DLT_APP);
+ dlt_set_id(ctid, WESTON_DLT_CONTEXT);
+
+ DLT_REGISTER_APP(apid, WESTON_DLT_APP_DESC);
+ DLT_REGISTER_CONTEXT(weston_dlt_context, ctid, WESTON_DLT_CONTEXT_DESC);
+
+ /*make the stdin as read end of the pipe*/
+ dup2(wlcontext->pipefd[0], STDIN_FILENO);
+
+ while (running && wlcontext->thread_running)
+ {
+ char str[MAXSTRLEN] = {0};
+ int i = -1;
+
+ /* read from std-in(read end of pipe) till newline char*/
+ do {
+ i++;
+ read(wlcontext->pipefd[0], &str[i], 1);
+ } while (str[i] != '\n');
+
+ if (strcmp(str,"")!=0)
+ {
+ DLT_LOG(weston_dlt_context, DLT_LOG_INFO, DLT_STRING(str));
+ }
+ }
+
+ DLT_UNREGISTER_CONTEXT(weston_dlt_context);
+ DLT_UNREGISTER_APP();
+ pthread_exit(NULL);
+}
+#endif
+
+static void
+signal_int(int signum)
+{
+ running = 0;
+}
+
+static int
+display_poll(struct wl_display *display, short int events)
+{
+ int ret;
+ struct pollfd pfd[1];
+
+ pfd[0].fd = wl_display_get_fd(display);
+ pfd[0].events = events;
+ do {
+ ret = poll(pfd, 1, -1);
+ } while (ret == -1 && errno == EINTR && running);
+
+ if(0 == running)
+ ret = -1;
+
+ return ret;
+}
+
+/* implemented local API for dispatch the default queue
+ * to handle the Ctrl+C signal properly, with the wl_display_dispatch
+ * the poll is continuing because the generated errno is EINTR,
+ * so added running flag also to decide whether to continue polling or not */
+static int
+display_dispatch(struct wl_display *display)
+{
+ int ret;
+
+ if (wl_display_prepare_read(display) == -1)
+ return wl_display_dispatch_pending(display);
+
+ while (1) {
+ ret = wl_display_flush(display);
+
+ if (ret != -1 || errno != EAGAIN)
+ break;
+
+ if (display_poll(display, POLLOUT) == -1) {
+ wl_display_cancel_read(display);
+ return -1;
+ }
+ }
+
+ /* Don't stop if flushing hits an EPIPE; continue so we can read any
+ * protocol error that may have triggered it. */
+ if (ret < 0 && errno != EPIPE) {
+ wl_display_cancel_read(display);
+ return -1;
+ }
+
+ if (display_poll(display, POLLIN) == -1) {
+ wl_display_cancel_read(display);
+ return -1;
+ }
+
+ if (wl_display_read_events(display) == -1)
+ return -1;
+
+ return wl_display_dispatch_pending(display);
+}
+
int main (int argc, const char * argv[])
{
WaylandContextStruct* wlcontext;
BkGndSettingsStruct* bkgnd_settings;
+
+ struct sigaction sigint;
+ int offset = 0;
int ret = 0;
+ sigint.sa_handler = signal_int;
+ sigemptyset(&sigint.sa_mask);
+ sigaction(SIGINT, &sigint, NULL);
+ sigaction(SIGTERM, &sigint, NULL);
+ sigaction(SIGSEGV, &sigint, NULL);
+
/*get bkgnd settings and create shm-surface*/
bkgnd_settings = get_bkgnd_settings();
/*init wayland context*/
wlcontext = (WaylandContextStruct*)calloc(1, sizeof(WaylandContextStruct));
wlcontext->bkgnd_settings = bkgnd_settings;
+
+#ifdef LIBWESTON_DEBUG_PROTOCOL
+ /*init debug stream list*/
+ wl_list_init(&wlcontext->stream_list);
+ get_debug_streams(wlcontext);
+ wlcontext->debug_fd = STDOUT_FILENO;
+#else
+ fprintf(stderr, "WARNING: weston_debug protocol is not available\n");
+#endif
+
if (init_wayland_context(wlcontext)) {
fprintf(stderr, "init_wayland_context failed\n");
goto ErrorContext;
@@ -512,13 +840,64 @@ int main (int argc, const char * argv[])
wl_display_roundtrip(wlcontext->wl_display);
+#ifdef LIBWESTON_DEBUG_PROTOCOL
+ if (!wl_list_empty(&wlcontext->stream_list) &&
+ wlcontext->debug_iface) {
+ /* create the pipe b/w stdout and stdin
+ * stdout - write end
+ * stdin - read end
+ * weston will write to stdout and the
+ * dlt_ctx_thread will read from stdin */
+ pipe(wlcontext->pipefd);
+ dup2(wlcontext->pipefd[1], STDOUT_FILENO);
+
+ wlcontext->thread_running = 1;
+ pthread_create(&wlcontext->dlt_ctx_thread, NULL,
+ weston_dlt_thread_function, wlcontext);
+ start_streams(wlcontext);
+ }
+#endif
+
/*draw the bkgnd display*/
draw_bkgnd_surface(wlcontext);
- while (ret != -1)
- ret = wl_display_dispatch(wlcontext->wl_display);
+ while (running && (ret != -1))
+ ret = display_dispatch(wlcontext->wl_display);
Error:
+#ifdef LIBWESTON_DEBUG_PROTOCOL
+ weston_debug_v1_destroy(wlcontext->debug_iface);
+
+ while (1) {
+ struct debug_stream *stream;
+ int empty = 1;
+
+ wl_list_for_each(stream, &wlcontext->stream_list, link)
+ if (stream->obj) {
+ empty = 0;
+ break;
+ }
+
+ if (empty)
+ break;
+
+ if (wl_display_dispatch(wlcontext->wl_display) < 0)
+ break;
+ }
+
+ destroy_streams(wlcontext);
+ wl_display_roundtrip(wlcontext->wl_display);
+
+ if(wlcontext->thread_running)
+ {
+ close(wlcontext->pipefd[1]);
+ close(STDOUT_FILENO);
+ wlcontext->thread_running = 0;
+ pthread_join(wlcontext->dlt_ctx_thread, NULL);
+ close(wlcontext->pipefd[0]);
+ }
+#endif
+
destroy_bkgnd_surface(wlcontext);
ErrorContext:
destroy_wayland_context(wlcontext);
diff --git a/weston-ivi-shell/src/ivi-controller.c b/weston-ivi-shell/src/ivi-controller.c
index fd6c7d8..5a5e17c 100644
--- a/weston-ivi-shell/src/ivi-controller.c
+++ b/weston-ivi-shell/src/ivi-controller.c
@@ -42,6 +42,7 @@
#include "wayland-util.h"
#define IVI_CLIENT_SURFACE_ID_ENV_NAME "IVI_CLIENT_SURFACE_ID"
+#define IVI_CLIENT_DEBUG_SCOPES_ENV_NAME "IVI_CLIENT_DEBUG_STREAM_NAMES"
struct ivilayer;
struct iviscreen;
@@ -1976,6 +1977,10 @@ get_config(struct weston_compositor *compositor, struct ivishell *shell)
"bkgnd-surface-id",
&shell->bkgnd_surface_id, -1);
+ weston_config_section_get_string(section,
+ "debug-scopes",
+ &shell->debug_scopes, NULL);
+
weston_config_section_get_color(section,
"bkgnd-color",
&shell->bkgnd_color, 0xFF000000);
@@ -2163,6 +2168,10 @@ launch_client_process(void *data)
sprintf(option, "%d", shell->bkgnd_surface_id);
setenv(IVI_CLIENT_SURFACE_ID_ENV_NAME, option, 0x1);
+ if (shell->debug_scopes) {
+ setenv(IVI_CLIENT_DEBUG_SCOPES_ENV_NAME, shell->debug_scopes, 0x1);
+ free(shell->debug_scopes);
+ }
shell->client = weston_client_start(shell->compositor,
shell->ivi_client_name);
diff --git a/weston-ivi-shell/src/ivi-controller.h b/weston-ivi-shell/src/ivi-controller.h
index fe82597..c279146 100644
--- a/weston-ivi-shell/src/ivi-controller.h
+++ b/weston-ivi-shell/src/ivi-controller.h
@@ -92,6 +92,7 @@ struct ivishell {
struct wl_client *client;
char *ivi_client_name;
+ char *debug_scopes;
};
#endif /* WESTON_IVI_SHELL_SRC_IVI_CONTROLLER_H_ */