Exemple #1
0
/** Set the screen refresh rate, necessary to calculate the interval
 *  between painting
 */
void
display_set_screen_refresh_rate(xcb_randr_get_screen_info_cookie_t cookie)
{
  assert(cookie.sequence);

  xcb_randr_get_screen_info_reply_t *reply =
    xcb_randr_get_screen_info_reply(globalconf.connection, cookie, NULL);

  if(reply && reply->rate)
    {
      float rate = 1 / (float) reply->rate;

      if(rate < MINIMUM_REPAINT_INTERVAL)
        {
          warn("Got refresh rate > 200Hz, set it to 200Hz");
          rate = (float) MINIMUM_REPAINT_INTERVAL;
        }

      globalconf.refresh_rate_interval = rate;
    }
  else
    {
      warn("Could not get screen refresh rate, set it to 50Hz");
      globalconf.refresh_rate_interval = (float) DEFAULT_REPAINT_INTERVAL;
    }

  free(reply);
}
/**
 * Gets the reply of the GetScreenInfo request sent by ecore_x_randr_get_screen_info_prefetch().
 * @ingroup Ecore_X_RandR_Group
 */
EAPI void
ecore_x_randr_get_screen_info_fetch(void)
{
#ifdef ECORE_XCB_RANDR
   xcb_randr_get_screen_info_cookie_t cookie;
   xcb_randr_get_screen_info_reply_t *reply;

   cookie.sequence = _ecore_xcb_cookie_get();
   reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
   _ecore_xcb_reply_cache(reply);
#endif /* ECORE_XCB_RANDR */
}
Exemple #3
0
void QXcbScreen::updateRefreshRate()
{
    if (!connection()->hasXRandr())
        return;

    int rate = m_refreshRate;

    xcb_randr_get_screen_info_reply_t *screenInfoReply =
        xcb_randr_get_screen_info_reply(xcb_connection(), xcb_randr_get_screen_info_unchecked(xcb_connection(), m_screen->root), 0);

    if (screenInfoReply) {
        rate = screenInfoReply->rate;
        free(screenInfoReply);
    }

    if (rate == m_refreshRate)
        return;

    m_refreshRate = rate;

    QWindowSystemInterface::handleScreenRefreshRateChange(QPlatformScreen::screen(), rate);
}
Exemple #4
0
std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
{
    std::vector<VideoMode> modes;

    // Open a connection with the X server
    xcb_connection_t* connection = OpenConnection();

    // Retrieve the default screen
    xcb_screen_t* screen = XCBDefaultScreen(connection);

    ScopedXcbPtr<xcb_generic_error_t> error(NULL);

    const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id);

    if (!randrExt || !randrExt->present)
    {
        // Randr extension is not supported: we cannot get the video modes
        err() << "Failed to use the RandR extension while trying to get the supported video modes" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return modes;
    }

    // Load RandR and check its version
    ScopedXcbPtr<xcb_randr_query_version_reply_t> randrVersion(xcb_randr_query_version_reply(
        connection,
        xcb_randr_query_version(
            connection,
            1,
            1
        ),
        &error
    ));

    if (error)
    {
        err() << "Failed to load the RandR extension while trying to get the supported video modes" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return modes;
    }

    // Get the current configuration
    ScopedXcbPtr<xcb_randr_get_screen_info_reply_t> config(xcb_randr_get_screen_info_reply(
        connection,
        xcb_randr_get_screen_info(
            connection,
            screen->root
        ),
        &error
    ));

    if (error)
    {
        // Failed to get the screen configuration
        err() << "Failed to retrieve the screen configuration while trying to get the supported video modes" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return modes;
    }

    // Get the available screen sizes
    xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get());
    if (sizes && (config->nSizes > 0))
    {
        // Get the list of supported depths
        xcb_depth_iterator_t iter = xcb_screen_allowed_depths_iterator(screen);
        // Combine depths and sizes to fill the array of supported modes
        for (; iter.rem; xcb_depth_next(&iter))
        {
            for (int j = 0; j < config->nSizes; ++j)
            {
                // Convert to VideoMode
                VideoMode mode(sizes[j].width, sizes[j].height, iter.data->depth);

                if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 ||
                    config->rotation == XCB_RANDR_ROTATION_ROTATE_270)
                    std::swap(mode.width, mode.height);

                // Add it only if it is not already in the array
                if (std::find(modes.begin(), modes.end(), mode) == modes.end())
                    modes.push_back(mode);
            }
        }
    }

    // Close the connection with the X server
    CloseConnection(connection);

    return modes;
}
Exemple #5
0
VideoMode VideoModeImpl::getDesktopMode()
{
    VideoMode desktopMode;

    // Open a connection with the X server
    xcb_connection_t* connection = OpenConnection();

    // Retrieve the default screen
    xcb_screen_t* screen = XCBDefaultScreen(connection);

    ScopedXcbPtr<xcb_generic_error_t> error(NULL);

    // Check if the RandR extension is present
    const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id);

    if (!randrExt || !randrExt->present)
    {
        // Randr extension is not supported: we cannot get the video modes
        err() << "Failed to use the RandR extension while trying to get the desktop video mode" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return desktopMode;
    }

    // Load RandR and check its version
    ScopedXcbPtr<xcb_randr_query_version_reply_t> randrVersion(xcb_randr_query_version_reply(
        connection,
        xcb_randr_query_version(
            connection,
            1,
            1
        ),
        &error
    ));

    if (error)
    {
        err() << "Failed to load the RandR extension while trying to get the desktop video mode" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return desktopMode;
    }

    // Get the current configuration
    ScopedXcbPtr<xcb_randr_get_screen_info_reply_t> config(xcb_randr_get_screen_info_reply(
        connection,
        xcb_randr_get_screen_info(
            connection,
            screen->root
        ),
        &error
    ));

    if (error)
    {
        // Failed to get the screen configuration
        err() << "Failed to retrieve the screen configuration while trying to get the desktop video mode" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return desktopMode;
    }

    // Get the current video mode
    xcb_randr_mode_t currentMode = config->sizeID;

    // Get the available screen sizes
    int nbSizes = xcb_randr_get_screen_info_sizes_length(config.get());
    xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get());
    if (sizes && (nbSizes > 0))
    {
        desktopMode = VideoMode(sizes[currentMode].width, sizes[currentMode].height, screen->root_depth);

        if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 ||
            config->rotation == XCB_RANDR_ROTATION_ROTATE_270)
            std::swap(desktopMode.width, desktopMode.height);
    }
    else
    {
        err() << "Failed to retrieve any screen sizes while trying to get the desktop video mode" << std::endl;
    }

    // Close the connection with the X server
    CloseConnection(connection);

    return desktopMode;
}
static void init_xcb()
{
    const xcb_query_extension_reply_t *qer;
    const xcb_setup_t *setup;
    xcb_screen_t *screen;
    xcb_screen_iterator_t screen_iter;
    xcb_drawable_t win;
    guint num_screens;
    guint i;
    xcb_generic_error_t *err = NULL;

    /* Open xcb connection */
    conn = xcb_connect(gdk_get_display_arg_name(), NULL);
    if (xcb_connection_has_error(conn)) {
        g_error("Failed to connect to display\n");
        exit(EXIT_FAILURE);
    }

    /* query the version to prevent error 16 when setting config */
    xcb_randr_query_version_unchecked(conn, 1, 5);

    qer = xcb_get_extension_data(conn, &xcb_randr_id);
    if (!qer || !qer->present) {
        g_error("RandR extension missing\n");
        exit(EXIT_FAILURE);
    }
    randr_base = qer->first_event;

    xcb_source = g_xcb_source_new_for_connection(NULL, conn);
    g_xcb_source_set_event_callback(xcb_source, on_xcb_event, NULL);

    /* get the screens */
    setup = xcb_get_setup(conn);
    screen_iter = xcb_setup_roots_iterator(setup);

    num_screens = setup->roots_len;

    /* Set up space for cookies */
    xcb_randr_get_screen_info_cookie_t get_screen_info_cookies[num_screens];

    for (i = 0; i < num_screens; i++) {
        /* Get root window */
        screen = screen_iter.data;
        win = screen->root;

        /* Register for screen change events */
        xcb_randr_select_input(conn, win, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);

        /* Get screen info */
        get_screen_info_cookies[i] =
            xcb_randr_get_screen_info_unchecked(conn, win);

        xcb_screen_next(&screen_iter);
    }
    /* TODO: detect adding and removal of screens */

    xcb_flush(conn);

    /* Get screen info replies */
    for (i = 0; i < num_screens; i++) {
        xcb_randr_get_screen_info_reply_t *reply =
            xcb_randr_get_screen_info_reply(conn,
                    get_screen_info_cookies[i], &err);
        if (err) {
            g_warning("Error getting info for screen %u\n", i);
            err = NULL;
            continue;
        }

        add_screen(reply);
        free(reply);
    }
    xcb_flush(conn);
}