diff options
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_ */ |