Esempio n. 1
0
MirDisplayConnection::MirDisplayConnection()
    : connection_(nullptr),
      output_id_(-1),
      vertical_resolution_(0),
      horizontal_resolution_(0) {
  auto xdg_runtime_dir = ::getenv("XDG_RUNTIME_DIR");
  if (!xdg_runtime_dir)
    BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find XDG_RUNTIME_DIR"));

  std::string socket_path = xdg_runtime_dir;
  socket_path += "/mir_socket";

  connection_ = mir_connect_sync(socket_path.c_str(), "anbox");
  if (!mir_connection_is_valid(connection_)) {
    std::string msg;
    msg += "Failed to connect with Mir server: ";
    msg += mir_connection_get_error_message(connection_);
    BOOST_THROW_EXCEPTION(std::runtime_error(msg.c_str()));
  }

  mir_connection_set_display_config_change_callback(
      connection_,
      [](MirConnection *connection, void *context) {
        auto thiz = reinterpret_cast<MirDisplayConnection *>(context);
        DEBUG("");
      },
      this);

  MirDisplayConfiguration *display_config =
      mir_connection_create_display_config(connection_);

  const MirDisplayOutput *output = find_active_output(display_config);
  if (!output)
    BOOST_THROW_EXCEPTION(
        std::runtime_error("Failed to find active output display"));

  DEBUG("Selecting output id %d", output->output_id);

  output_id_ = output->output_id;

  const MirDisplayMode *mode = &output->modes[output->current_mode];

  vertical_resolution_ = mode->vertical_resolution;
  horizontal_resolution_ = mode->horizontal_resolution;

  mir_display_config_destroy(display_config);
}
bool
NativeStateMir::create_window(WindowProperties const& properties)
{
    static const char *win_name("glmark2 "GLMARK_VERSION);

    if (!mir_connection_is_valid(mir_connection_)) {
        Log::error("Cannot create a Mir surface without a valid connection "
                   "to the Mir display server!\n");
        return false;
    }

    /* Recreate an existing window only if it has actually been resized */
    if (mir_surface_) {
        if (properties_.fullscreen != properties.fullscreen ||
            (properties.fullscreen == false &&
             (properties_.width != properties.width ||
              properties_.height != properties.height)))
        {
            mir_surface_release_sync(mir_surface_);
            mir_surface_ = 0;
        }
        else
        {
            return true;
        }
    }

    uint32_t output_id = mir_display_output_id_invalid;

    properties_ = properties;

    if (properties_.fullscreen) {
        DisplayConfiguration display_config(mir_connection_);
        if (!display_config.is_valid()) {
            Log::error("Couldn't get display configuration from the Mir display server!\n");
            return false;
        }

        const MirDisplayOutput* active_output = find_active_output(display_config);
        if (active_output == NULL) {
            Log::error("Couldn't find an active output in the Mir display server!\n");
            return false;
        }

        const MirDisplayMode* current_mode =
            &active_output->modes[active_output->current_mode];

        properties_.width = current_mode->horizontal_resolution;
        properties_.height = current_mode->vertical_resolution;
        output_id = active_output->output_id;

        Log::debug("Making Mir surface fullscreen on output %u (%ux%u)\n",
                   output_id, properties_.width, properties_.height);
    }

    MirPixelFormat surface_format = find_best_surface_format(mir_connection_);
    if (surface_format == mir_pixel_format_invalid) {
        Log::error("Couldn't find a pixel format to use for the Mir surface!\n");
        return false;
    }

    Log::debug("Using pixel format %u for the Mir surface\n", surface_format);

    MirSurfaceParameters surface_parameters = {
        win_name,
        properties_.width, properties_.height,
        surface_format,
        mir_buffer_usage_hardware,
        output_id
    };

    mir_surface_ = mir_connection_create_surface_sync(mir_connection_,
                                                      &surface_parameters);

    if (!mir_surface_ || !mir_surface_is_valid(mir_surface_)) {
        Log::error("Failed to create Mir surface!\n");
        return false;
    }

    return true;
}