blob: 2314b1e0f17f535dd5a1052bf76a0f1720e98b9b [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <assert.h>
#include <fcntl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/io.h>
#include <lib/fdio/spawn.h>
#include <lib/fdio/watcher.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/service/llcpp/service.h>
#include <lib/svc/dir.h>
#include <lib/svc/outgoing.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/channel.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <zircon/device/vfs.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/log.h>
#include <zircon/syscalls/object.h>
#include <iterator>
#include <memory>
#include <utility>
#include <fbl/algorithm.h>
#include <fbl/unique_fd.h>
#include <src/storage/deprecated-fs-fidl-handler/fidl-handler.h>
#include "args.h"
#include "keyboard.h"
#include "session-manager.h"
#include "src/lib/listnode/listnode.h"
#include "src/lib/storage/vfs/cpp/service.h"
#include "src/sys/lib/stdout-to-debuglog/cpp/stdout-to-debuglog.h"
#include "vc.h"
int main(int argc, char** argv) {
zx_status_t status = StdoutToDebuglog::Init();
if (status != ZX_OK) {
FX_LOGS(ERROR)
<< "Failed to redirect stdout to debuglog, assuming test environment and continuing";
}
fidl::WireSyncClient<fuchsia_boot::Arguments> boot_args;
{
auto client = service::Connect<fuchsia_boot::Arguments>();
if (client.is_error()) {
fprintf(stderr, "vc: failed to connect to fuchsia.boot.Arguments\n");
return 1;
}
boot_args = fidl::BindSyncClient(std::move(*client));
}
Arguments args;
status = ParseArgs(boot_args, &args);
if (status != ZX_OK) {
printf("vc: failed to get boot arguments\n");
return -1;
}
if (args.disable) {
printf("vc: virtcon disabled\n");
return 0;
}
vc_device_init(args.font, args.keymap);
async::Loop loop = async::Loop(&kAsyncLoopConfigNeverAttachToThread);
virtcon::SessionManager virtcon_server =
virtcon::SessionManager(loop.dispatcher(), args.keep_log_visible, args.color_scheme);
svc::Outgoing outgoing(loop.dispatcher());
status = outgoing.ServeFromStartupInfo();
if (status != ZX_OK) {
printf("vc: outgoing.ServeFromStartupInfo() = %s\n", zx_status_get_string(status));
return -1;
}
status = outgoing.svc_dir()->AddEntry(
fidl::DiscoverableProtocolName<fuchsia_virtualconsole::SessionManager>,
fbl::MakeRefCounted<fs::Service>(
[&virtcon_server](
fidl::ServerEnd<fuchsia_virtualconsole::SessionManager> request) mutable {
virtcon_server.Bind(std::move(request));
return ZX_OK;
}));
{
auto local = service::Connect<fuchsia_boot::ReadOnlyLog>();
if (local.is_error()) {
fprintf(stderr, "vc: unable to connect to fuchsia.boot.ReadOnlyLog %d\n", status);
return -1;
}
auto result = BindSyncClient(std::move(*local)).Get();
if (!result.ok()) {
fprintf(stderr, "vc: unable to get read only debulog\n");
return -1;
}
if (log_start(loop.dispatcher(), std::move(result->log), args.color_scheme) < 0) {
fprintf(stderr, "vc: log_start failed\n");
return -1;
}
}
if (!args.repeat_keys) {
printf("vc: Key repeat disabled\n");
}
status = setup_keyboard_watcher(loop.dispatcher(), handle_key_press, args.repeat_keys);
if (status != ZX_OK) {
printf("vc: setup_keyboard_watcher failed with %d\n", status);
}
if (!vc_sysmem_connect()) {
fprintf(stderr, "vc: failed to connect to sysmem\n");
return -1;
}
if (!vc_display_init(loop.dispatcher(), args.hide_on_boot)) {
fprintf(stderr, "vc: failed to initialize display\n");
return -1;
}
printf("vc: started\n");
status = loop.Run();
printf("vc: loop stopped: %d\n", status);
return -1;
}