X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fmain.c;h=164b45b87315c64c28aa47afa55a096a160468d3;hb=991714fc7f92aea3d07c7225247a821e3461027e;hp=74e97d0834e8998451e7b7336c59fa4553f5cbf3;hpb=191dc29c7d05d8af9aa2c659275436ec4c4495c0;p=src%2Fagl-compositor.git diff --git a/src/main.c b/src/main.c index 74e97d0..164b45b 100644 --- a/src/main.c +++ b/src/main.c @@ -24,6 +24,7 @@ */ #include "ivi-compositor.h" +#include "policy.h" #include #include @@ -36,17 +37,29 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#ifdef HAVE_BACKEND_X11 +#include +#endif +#include +#include +#include +#include +#include #include "shared/os-compatibility.h" +#include "shared/helpers.h" #include "agl-shell-server-protocol.h" +#ifdef HAVE_REMOTING +#include "remote.h" +#endif + +static int cached_tm_mday = -1; +static struct weston_log_scope *log_scope; + struct ivi_compositor * to_ivi_compositor(struct weston_compositor *ec) { @@ -77,6 +90,26 @@ to_ivi_output(struct weston_output *o) return output; } +static void +ivi_output_configure_app_id(struct ivi_output *ivi_output) +{ + if (ivi_output->config) { + if (ivi_output->app_id != NULL) + return; + + weston_config_section_get_string(ivi_output->config, + "agl-shell-app-id", + &ivi_output->app_id, + NULL); + + if (ivi_output->app_id == NULL) + return; + + weston_log("Will place app_id %s on output %s\n", + ivi_output->app_id, ivi_output->name); + } +} + static struct ivi_output * ivi_ensure_output(struct ivi_compositor *ivi, char *name, struct weston_config_section *config) @@ -111,6 +144,7 @@ ivi_ensure_output(struct ivi_compositor *ivi, char *name, &output->output_destroy); wl_list_insert(&ivi->outputs, &output->link); + ivi_output_configure_app_id(output); return output; } @@ -524,6 +558,204 @@ heads_changed(struct wl_listener *listener, void *arg) } } +#ifdef HAVE_REMOTING +static int +drm_backend_remoted_output_configure(struct weston_output *output, + struct weston_config_section *section, + char *modeline, + const struct weston_remoting_api *api) +{ + char *gbm_format = NULL; + char *seat = NULL; + char *host = NULL; + char *pipeline = NULL; + int port, ret; + int32_t scale = 1; + uint32_t transform = WL_OUTPUT_TRANSFORM_NORMAL; + char *trans; + + ret = api->set_mode(output, modeline); + if (ret < 0) { + weston_log("Cannot configure an output \"%s\" using " + "weston_remoting_api. Invalid mode\n", + output->name); + return -1; + } + + weston_config_section_get_int(section, "scale", &scale, 1); + weston_output_set_scale(output, scale); + + weston_config_section_get_string(section, "transform", &trans, "normal"); + if (parse_transform(trans, &transform) < 0) { + weston_log("Invalid transform \"%s\" for output %s\n", + trans, output->name); + } + weston_output_set_transform(output, transform); + + weston_config_section_get_string(section, "gbm-format", + &gbm_format, NULL); + api->set_gbm_format(output, gbm_format); + free(gbm_format); + + weston_config_section_get_string(section, "seat", &seat, ""); + + api->set_seat(output, seat); + free(seat); + + weston_config_section_get_string(section, "gst-pipeline", &pipeline, + NULL); + if (pipeline) { + api->set_gst_pipeline(output, pipeline); + free(pipeline); + return 0; + } + + weston_config_section_get_string(section, "host", &host, NULL); + weston_config_section_get_int(section, "port", &port, 0); + if (!host || port <= 0 || 65533 < port) { + weston_log("Cannot configure an output \"%s\". " + "Need to specify gst-pipeline or " + "host and port (1-65533).\n", output->name); + } + api->set_host(output, host); + free(host); + api->set_port(output, port); + + return 0; +} + + +static int +remote_output_init(struct ivi_output *ivi_output, + struct weston_compositor *compositor, + struct weston_config_section *section, + const struct weston_remoting_api *api) +{ + char *output_name, *modeline = NULL; + int ret = -1; + + weston_config_section_get_string(section, "name", &output_name, NULL); + if (!output_name) + return ret; + + weston_config_section_get_string(section, "mode", &modeline, "off"); + if (strcmp(modeline, "off") == 0) + goto err; + + ivi_output->output = api->create_output(compositor, output_name); + if (!ivi_output->output) { + weston_log("Cannot create remoted output \"%s\".\n", + output_name); + goto err; + } + + ret = drm_backend_remoted_output_configure(ivi_output->output, section, + modeline, api); + if (ret < 0) { + weston_log("Cannot configure remoted output \"%s\".\n", + output_name); + goto err; + } + + if (weston_output_enable(ivi_output->output) < 0) { + weston_log("Enabling remoted output \"%s\" failed.\n", + output_name); + goto err; + } + + free(modeline); + free(output_name); + weston_log("remoted output '%s' enabled\n", ivi_output->output->name); + + return 0; + +err: + free(modeline); + free(output_name); + if (ivi_output->output) + weston_output_destroy(ivi_output->output); + + return ret; +} + +static void +ivi_enable_remote_outputs(struct ivi_compositor *ivi) +{ + struct weston_config_section *remote_section = NULL; + const char *section_name; + struct weston_config *config = ivi->config; + + while (weston_config_next_section(config, &remote_section, §ion_name)) { + if (strcmp(section_name, "remote-output")) + continue; + + struct ivi_output *ivi_output = NULL; + bool output_found = false; + char *_name = NULL; + + weston_config_section_get_string(remote_section, + "name", &_name, NULL); + wl_list_for_each(ivi_output, &ivi->outputs, link) { + if (!strcmp(ivi_output->name, _name)) { + output_found = true; + break; + } + } + + if (output_found) { + free(_name); + continue; + } + + ivi_output = zalloc(sizeof(*ivi_output)); + + ivi_output->ivi = ivi; + ivi_output->name = _name; + ivi_output->config = remote_section; + + if (remote_output_init(ivi_output, ivi->compositor, + remote_section, ivi->remoting_api)) { + free(ivi_output->name); + free(ivi_output); + continue; + } + + ivi_output->output_destroy.notify = handle_output_destroy; + weston_output_add_destroy_listener(ivi_output->output, + &ivi_output->output_destroy); + + wl_list_insert(&ivi->outputs, &ivi_output->link); + ivi_output_configure_app_id(ivi_output); + } +} + +static int +load_remoting_plugin(struct ivi_compositor *ivi, struct weston_config *config) +{ + struct weston_compositor *compositor = ivi->compositor; + int (*module_init)(struct weston_compositor *wc); + + module_init = weston_load_module("remoting-plugin.so", + "weston_module_init"); + if (!module_init) + return -1; + + if (module_init(compositor) < 0) + return -1; + + ivi->remoting_api = weston_remoting_get_api(compositor); + if (!ivi->remoting_api) + return -1; + return 0; +} +#else +static int +load_remoting_plugin(struct weston_compositor *compositor, struct weston_config *config) +{ + return -1; +} +#endif + static int load_drm_backend(struct ivi_compositor *ivi, int *argc, char *argv[]) { @@ -536,7 +768,7 @@ load_drm_backend(struct ivi_compositor *ivi, int *argc, char *argv[]) struct weston_config_section *section; int use_current_mode = 0; int use_pixman = 0; - int use_shadow; + bool use_shadow; int ret; const struct weston_option options[] = { @@ -571,6 +803,8 @@ load_drm_backend(struct ivi_compositor *ivi, int *argc, char *argv[]) goto error; } + load_remoting_plugin(ivi, ivi->config); + error: free(config.gbm_format); free(config.seat_id); @@ -582,7 +816,7 @@ windowed_parse_common_options(struct ivi_compositor *ivi, int *argc, char *argv[ bool *use_pixman, bool *fullscreen, int *output_count) { struct weston_config_section *section; - int pixman; + bool pixman; int fs = 0; const struct weston_option options[] = { @@ -709,6 +943,7 @@ load_wayland_backend(struct ivi_compositor *ivi, int *argc, char *argv[]) return windowed_create_outputs(ivi, output_count, "WL", "wayland"); } +#ifdef HAVE_BACKEND_X11 static int load_x11_backend(struct ivi_compositor *ivi, int *argc, char *argv[]) { @@ -746,6 +981,13 @@ load_x11_backend(struct ivi_compositor *ivi, int *argc, char *argv[]) return windowed_create_outputs(ivi, output_count, "X", "screen"); } +#else +static int +load_x11_backend(struct ivi_compositor *ivi, int *argc, char *argv[]) +{ + return -1; +} +#endif static int load_backend(struct ivi_compositor *ivi, const char *backend, @@ -785,8 +1027,8 @@ compositor_init_config(struct weston_compositor *compositor, struct xkb_rule_names xkb_names; struct weston_config_section *section; int repaint_msec; - int vt_switching; - int require_input; + bool vt_switching; + bool require_input; /* agl-compositor.ini [keyboard] */ section = weston_config_get_section(config, "keyboard", NULL, NULL); @@ -967,39 +1209,46 @@ load_config(struct weston_config **config, bool no_config, } static FILE *logfile; -//static struct weston_log_scope *log_scope; -//static struct weston_log_scope *protocol_scope; -static int -log_timestamp(void) +static char * +log_timestamp(char *buf, size_t len) { - static int cached_tm_mday = -1; - struct timespec ts; - struct tm brokendown_time; - char buf[128]; + struct timeval tv; + struct tm *brokendown_time; + char datestr[128]; + char timestr[128]; - clock_gettime(CLOCK_REALTIME, &ts); - if (!localtime_r(&ts.tv_sec, &brokendown_time)) - return fprintf(logfile, "[(NULL)localtime] "); + gettimeofday(&tv, NULL); - if (brokendown_time.tm_mday != cached_tm_mday) { - strftime(buf, sizeof buf, "%Y-%m-%d %Z", &brokendown_time); - fprintf(logfile, "Date: %s\n", buf); + brokendown_time = localtime(&tv.tv_sec); + if (brokendown_time == NULL) { + snprintf(buf, len, "%s", "[(NULL)localtime] "); + return buf; + } - cached_tm_mday = brokendown_time.tm_mday; + memset(datestr, 0, sizeof(datestr)); + if (brokendown_time->tm_mday != cached_tm_mday) { + strftime(datestr, sizeof(datestr), "Date: %Y-%m-%d %Z\n", + brokendown_time); + cached_tm_mday = brokendown_time->tm_mday; } - strftime(buf, sizeof buf, "%H:%M:%S", &brokendown_time); + strftime(timestr, sizeof(timestr), "%H:%M:%S", brokendown_time); + /* if datestr is empty it prints only timestr*/ + snprintf(buf, len, "%s[%s.%03li]", datestr, + timestr, (tv.tv_usec / 1000)); - return fprintf(logfile, "[%s.%03ld] ", buf, ts.tv_nsec / 1000000); + return buf; } static void custom_handler(const char *fmt, va_list arg) { - log_timestamp(); - fprintf(logfile, "libwayland: "); - vfprintf(logfile, fmt, arg); + char timestr[512]; + + weston_log_scope_printf(log_scope, "%s libwayland: ", + log_timestamp(timestr, sizeof(timestr))); + weston_log_scope_vprintf(log_scope, fmt, arg); } static void @@ -1029,18 +1278,33 @@ log_file_close(void) static int vlog(const char *fmt, va_list ap) { - int l; - - l = log_timestamp(); - l += vfprintf(logfile, fmt, ap); + const char *oom = "Out of memory"; + char timestr[128]; + int len = 0; + char *str; + + if (weston_log_scope_is_enabled(log_scope)) { + int len_va; + char *xlog_timestamp = log_timestamp(timestr, sizeof(timestr)); + len_va = vasprintf(&str, fmt, ap); + if (len_va >= 0) { + len = weston_log_scope_printf(log_scope, "%s %s", + xlog_timestamp, str); + free(str); + } else { + len = weston_log_scope_printf(log_scope, "%s %s", + xlog_timestamp, oom); + } + } - return l; + return len; } + static int vlog_continue(const char *fmt, va_list ap) { - return vfprintf(logfile, fmt, ap); + return weston_log_scope_vprintf(log_scope, fmt, ap); } static int @@ -1088,20 +1352,6 @@ usage(int error_code) exit(error_code); } -static void -ivi_compositor_get_quirks(struct ivi_compositor *ivi) -{ - struct weston_config_section *section; - - if (!ivi->config) - return; - - section = weston_config_get_section(ivi->config, "shell", NULL, NULL); - weston_config_section_get_bool(section, "activate-by-default", - &ivi->quirks.activate_apps_by_default, 0); - -} - int main(int argc, char *argv[]) { struct ivi_compositor ivi = { 0 }; @@ -1117,7 +1367,9 @@ int main(int argc, char *argv[]) int version = 0; int no_config = 0; char *config_file = NULL; - int debug_protocol = 0; + struct weston_log_context *log_ctx = NULL; + struct weston_log_subscriber *logger; + int ret = EXIT_FAILURE; const struct weston_option core_options[] = { { WESTON_OPTION_STRING, "backend", 'B', &backend }, @@ -1127,12 +1379,16 @@ int main(int argc, char *argv[]) { WESTON_OPTION_BOOLEAN, "version", 0, &version }, { WESTON_OPTION_BOOLEAN, "no-config", 0, &no_config }, { WESTON_OPTION_STRING, "config", 'c', &config_file }, - { WESTON_OPTION_BOOLEAN, "debug", 0, &debug_protocol }, }; wl_list_init(&ivi.outputs); wl_list_init(&ivi.surfaces); wl_list_init(&ivi.pending_surfaces); + wl_list_init(&ivi.popup_pending_apps); + wl_list_init(&ivi.fullscreen_pending_apps); + wl_list_init(&ivi.split_pending_apps); + wl_list_init(&ivi.remote_pending_apps); + wl_list_init(&ivi.desktop_clients); /* Prevent any clients we spawn getting our stdin */ os_fd_set_cloexec(STDIN_FILENO); @@ -1147,9 +1403,22 @@ int main(int argc, char *argv[]) return EXIT_SUCCESS; } + log_ctx = weston_log_ctx_compositor_create(); + if (!log_ctx) { + fprintf(stderr, "Failed to initialize weston debug framework.\n"); + return ret; + } + + log_scope = weston_compositor_add_log_scope(log_ctx, "log", + "agl-compositor log\n", + NULL, NULL, NULL); + log_file_open(log); weston_log_set_handler(vlog, vlog_continue); + logger = weston_log_subscriber_create_log(logfile); + weston_log_subscribe(log_ctx, logger, "log"); + if (load_config(&ivi.config, no_config, config_file) < 0) goto error_signals; section = weston_config_get_section(ivi.config, "core", NULL, NULL); @@ -1160,8 +1429,6 @@ int main(int argc, char *argv[]) backend = choose_default_backend(); } - ivi_compositor_get_quirks(&ivi); - display = wl_display_create(); loop = wl_display_get_event_loop(display); @@ -1181,7 +1448,7 @@ int main(int argc, char *argv[]) if (!signals[i]) goto error_signals; - ivi.compositor = weston_compositor_create(display, &ivi); + ivi.compositor = weston_compositor_create(display, log_ctx, &ivi); if (!ivi.compositor) { weston_log("fatal: failed to create compositor.\n"); goto error_signals; @@ -1202,6 +1469,9 @@ int main(int argc, char *argv[]) if (ivi_desktop_init(&ivi) < 0) goto error_compositor; + if (ivi_policy_init(&ivi) < 0) + goto error_compositor; + if (ivi_shell_init(&ivi) < 0) goto error_compositor; @@ -1209,6 +1479,9 @@ int main(int argc, char *argv[]) weston_compositor_flush_heads_changed(ivi.compositor); + if (ivi.remoting_api) + ivi_enable_remote_outputs(&ivi); + ivi_shell_init_black_fs(&ivi); if (create_listening_socket(display, socket_name) < 0) @@ -1220,15 +1493,28 @@ int main(int argc, char *argv[]) ivi_shell_create_global(&ivi); ivi_launch_shell_client(&ivi); + ivi_screenshooter_create(&ivi); ivi_agl_systemd_notify(&ivi); wl_display_run(display); + ret = ivi.compositor->exit_code; + wl_display_destroy_clients(display); error_compositor: + weston_compositor_tear_down(ivi.compositor); + + weston_compositor_log_scope_destroy(log_scope); + log_scope = NULL; + + weston_log_ctx_compositor_destroy(ivi.compositor); weston_compositor_destroy(ivi.compositor); + weston_log_subscriber_destroy_log(logger); + + ivi_policy_destroy(ivi.policy); + error_signals: for (size_t i = 0; i < ARRAY_LENGTH(signals); ++i) if (signals[i]) @@ -1239,4 +1525,6 @@ error_signals: log_file_close(); if (ivi.config) weston_config_destroy(ivi.config); + + return ret; }