/** 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 */ }
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); }
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; }
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); }