Пример #1
0
int _glfwPlatformInit(void)
{
    int error;

    _glfw.mir.connection = mir_connect_sync(NULL, __PRETTY_FUNCTION__);

    if (!mir_connection_is_valid(_glfw.mir.connection))
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Mir: Unable to connect to Server");
        return GL_FALSE;
    }

    _glfw.mir.display =
        mir_connection_get_egl_native_display(_glfw.mir.connection);

    if (!_glfwInitContextAPI())
        return GL_FALSE;

    _glfwInitTimer();
    _glfwInitJoysticks();

    _glfw.mir.event_queue = calloc(1, sizeof(EventQueue));
    _glfwInitEventQueue(_glfw.mir.event_queue);

    error = pthread_mutex_init(&_glfw.mir.event_mutex, NULL);
    if (error)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Mir: Failed to create Event Mutex Error: %i\n", error);
        return GL_FALSE;
    }

    return GL_TRUE;
}
bool uamc::Instance::connect(std::string const& application_name)
{
    auto mir_connection = mir_connect_sync(NULL, application_name.c_str());

    // mir_connect_sync() always returns a connection object, even in case
    // of a failed connection. We need to release this object in all cases.
    con = ConnectionPtr(mir_connection,
        [](MirConnection *c)
        {
            mir_connection_release(c);
        });

    return mir_connection_is_valid(mir_connection);
}
Пример #3
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);
}
Пример #4
0
int _glfwPlatformInit(void)
{
    int error;

    _glfw.mir.connection = mir_connect_sync(NULL, __PRETTY_FUNCTION__);

    if (!mir_connection_is_valid(_glfw.mir.connection))
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Mir: Unable to connect to server: %s",
                        mir_connection_get_error_message(_glfw.mir.connection));

        return GLFW_FALSE;
    }

    _glfw.mir.display =
        mir_connection_get_egl_native_display(_glfw.mir.connection);

    createKeyTables();

    if (!_glfwInitThreadLocalStoragePOSIX())
        return GLFW_FALSE;

    if (!_glfwInitJoysticksLinux())
        return GLFW_FALSE;

    _glfwInitTimerPOSIX();

    // Need the default conf for when we set a NULL cursor
    _glfw.mir.defaultConf  = mir_cursor_configuration_from_name(mir_default_cursor_name);
    _glfw.mir.disabledConf = mir_cursor_configuration_from_name(mir_disabled_cursor_name);

    _glfw.mir.eventQueue = calloc(1, sizeof(EventQueue));
    _glfwInitEventQueueMir(_glfw.mir.eventQueue);

    error = pthread_mutex_init(&_glfw.mir.eventMutex, NULL);
    if (error)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Mir: Failed to create event mutex: %s",
                        strerror(error));
        return GLFW_FALSE;
    }

    _glfwPollMonitorsMir();
    return GLFW_TRUE;
}
// Regression test for LP:#1340669
// Test is not deterministic since we are testing a race, but failure can be
// reproduced easily with repeated runs.
TEST_F(ClientWithCustomDisplayConfiguration,
       does_not_deadlock_server_with_existing_client_when_disconnecting)
{
    auto second_connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);

    auto second_surface = mtf::make_any_surface(connection);
    ASSERT_TRUE(mir_surface_is_valid(second_surface));

    auto configuration = mir_connection_create_display_config(connection);
    mir_wait_for(mir_connection_apply_display_config(connection, configuration));
    EXPECT_STREQ("", mir_connection_get_error_message(connection));
    mir_display_config_destroy(configuration);

    mir_connection_release(second_connection);

    // Server (and therefore the test) will deadlock and won't be able to
    // shut down without the fix. It's not ideal to deadlock on test failure,
    // but it's the best check we have at the moment.
}
Пример #6
0
GdkDisplay *
_gdk_mir_display_open (const gchar *display_name)
{
  MirConnection *connection;
  MirPixelFormat sw_pixel_format, hw_pixel_format;
  GdkMirDisplay *display;

  //g_printerr ("gdk_mir_display_open\n");

  connection = mir_connect_sync (NULL, "GDK-Mir");
  if (!connection)
     return NULL;

  if (!mir_connection_is_valid (connection))
    {
      g_printerr ("Failed to connect to Mir: %s\n", mir_connection_get_error_message (connection));
      mir_connection_release (connection);
      return NULL;
    }

  get_pixel_formats (connection, &sw_pixel_format, &hw_pixel_format);

  if (sw_pixel_format == mir_pixel_format_invalid ||
      hw_pixel_format == mir_pixel_format_invalid)
    {
      g_printerr ("Mir display does not support required pixel formats\n");
      mir_connection_release (connection);
      return NULL;
    }

  display = g_object_new (GDK_TYPE_MIR_DISPLAY, NULL);

  display->connection = connection;
  GDK_DISPLAY (display)->device_manager = _gdk_mir_device_manager_new (GDK_DISPLAY (display));
  display->screen = _gdk_mir_screen_new (GDK_DISPLAY (display));
  display->sw_pixel_format = sw_pixel_format;
  display->hw_pixel_format = hw_pixel_format;

  g_signal_emit_by_name (display, "opened");

  return GDK_DISPLAY (display);
}
Пример #7
0
bool
NativeStateMir::init_display()
{
    struct sigaction sa;
    sa.sa_handler = &NativeStateMir::quit_handler;
    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);

    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGTERM, &sa, NULL);

    mir_connection_ = mir_connect_sync(NULL, "glmark2");

    if (!mir_connection_is_valid(mir_connection_)) {
        Log::error("Couldn't connect to the Mir display server\n");
        return false;
    }

    return true;
}
Пример #8
0
int _glfwPlatformInit(void)
{
    _glfw.mir.connection = mir_connect_sync(NULL, __PRETTY_FUNCTION__);

    if (!mir_connection_is_valid(_glfw.mir.connection))
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "Mir: Unable to connect to Server");
        return GL_FALSE;
    }

    _glfw.mir.display =
        mir_connection_get_egl_native_display(_glfw.mir.connection);

    if (!_glfwInitContextAPI())
        return GL_FALSE;

    _glfwInitTimer();
    _glfwInitJoysticks();

    return GL_TRUE;
}
Пример #9
0
int Mir_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
    this->hidden->connection = mir_connect_sync(NULL, __PRETTY_FUNCTION__);

    if (!mir_connection_is_valid(this->hidden->connection))
    {
        SDL_SetError("Failed to connect to the Mir Server: %s",
                     mir_connection_get_error_message(this->hidden->connection));
        mir_connection_release(this->hidden->connection);
        return -1;
    }

    MirPixelFormat formats[mir_pixel_formats];
    Uint32 n_formats;

    mir_connection_get_available_surface_formats (this->hidden->connection, formats,
                                                  mir_pixel_formats, &n_formats);

    if (n_formats == 0 || formats[0] == mir_pixel_format_invalid)
    {
        SDL_SetError("No valid pixel formats found");
        mir_connection_release(this->hidden->connection);
        return -1;
    }

    this->hidden->pixel_format = formats[0];
    vformat->BitsPerPixel = MIR_BYTES_PER_PIXEL(this->hidden->pixel_format) * 8;

    Mir_InitQueue(this->hidden->buffer_queue);
    Mir_ModeListUpdate(this);
    mir_connection_set_display_config_change_callback(this->hidden->connection,
                                                      Mir_DisplayConfigChanged, this);

    this->info.wm_available = 1;

    return 0;
}
Пример #10
0
void start_session(const char* server, const char* name, MirDemoState* mcd)
{
    // Call mir_connect synchronously
    mcd->connection = mir_connect_sync(server, name);

    // We expect a connection handle;
    // we expect it to be valid; and,
    // we don't expect an error description
    assert(mcd->connection != NULL);
    assert(mir_connection_is_valid(mcd->connection));
    assert(strcmp(mir_connection_get_error_message(mcd->connection), "") == 0);
    printf("%s: Connected\n", name);

    // We can query information about the platform we're running on
    {
        MirPlatformPackage platform_package;
        platform_package.data_items = -1;
        platform_package.fd_items = -1;

        mir_connection_get_platform(mcd->connection, &platform_package);
        assert(0 <= platform_package.data_items);
        assert(0 <= platform_package.fd_items);
    }
}
TEST_F(UnresponsiveClient, does_not_hang_server)
{
    mt::CrossProcessAction server_send_events;
    mt::CrossProcessAction client_connect;
    mt::CrossProcessAction client_release;
    mt::CrossProcessAction server_finish;

    SessionListener sessions;

    init_server([&]
         {
            server.override_the_session_listener([&]
                { return mt::fake_shared(sessions); });
         });

    run_in_server([&]
        {
            mt::AutoJoinThread t{
                [&] {
                    server_send_events.exec([&]
                        {
                            for (int i = 0; i < 1000; ++i)
                            {
                                sessions.for_each(
                                    [i] (std::shared_ptr<ms::Session> const& session)
                                    {
                                        session->default_surface()->resize({i + 1, i + 1});
                                    });
                            }
                        });
                }};

            server_finish.exec([]{});
        });

    auto const client_code = [&]
    {
        MirConnection* connection = nullptr;
        MirSurface* surface = nullptr;

        client_connect.exec([&]
            {
                connection = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);

                surface = mtf::make_any_surface(connection);
            });

        client_release.exec([&]
            {
                // We would normally explicitly release the surface at this
                // point. However, because we have been filling the server
                // send socket buffer, releasing the surface may cause the
                // server to try to write to a full socket buffer when
                // responding, leading the server to believe that the client
                // is blocked, and causing a premature client disconnection.
                mir_connection_release(connection);
            });
    };

    auto client_process = new_client_process(client_code);

    if (is_test_process())
    {
        client_connect();
        kill(client_pid(), SIGSTOP);
        try 
        { 
            server_send_events(std::chrono::seconds{10});
        }
        catch(...)
        { 
            ADD_FAILURE() << "Server blocked while sending events";
        }
        kill(client_pid(), SIGCONT);
        client_release();
        server_finish();

        auto const result = client_process->wait_for_termination();
        EXPECT_THAT(result.exit_code, testing::Eq(EXIT_SUCCESS));
    }
}