/** * Get the geometry of the screen. * @param screen The screen (Unused). * @param x The X coordinate of the screen. * @param y The Y coordinate of the screen * @param width The width of the screen * @param height The height of the screen * @return 1 on success, 0 otherwise. * * Get the geometry of the screen whose number is @p screen. The * returned values are stored in @p x, @p y, @p width and @p height. * * To use this function, you must call before, and in order, * ecore_x_xinerama_query_screens_prefetch(), which sends the XineramaQueryScreens request, * then ecore_x_xinerama_query_screens_fetch(), which gets the reply. * @ingroup Ecore_X_Xinerama_Group */ EAPI int ecore_x_xinerama_screen_geometry_get(int screen, int *x, int *y, int *width, int *height) { #ifdef ECORE_XCB_XINERAMA xcb_xinerama_screen_info_iterator_t iter; xcb_xinerama_query_screens_reply_t *reply; reply = _ecore_xcb_reply_get(); if (!reply) { if (x) *x = 0; if (y) *y = 0; if (width) *width = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; if (height) *height = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels; return 0; } iter = xcb_xinerama_query_screens_screen_info_iterator(reply); for (; iter.rem; screen--, xcb_xinerama_screen_info_next(&iter)) { if (screen == 0) { if (x) *x = iter.data->x_org; if (y) *y = iter.data->y_org; if (width) *width = iter.data->width; if (height) *height = iter.data->height; return 1; } } #endif /* ECORE_XCB_XINERAMA */ if (x) *x = 0; if (y) *y = 0; if (width) *width = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; if (height) *height = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels; return 0; }
bool ScreenManager::scanXinerama(xcb_connection_t *conn) { xcb_generic_error_t *err; xcb_xinerama_screen_info_t *screen; xcb_xinerama_query_screens_cookie_t cookie = xcb_xinerama_query_screens(conn); const xcb_xinerama_query_screens_reply_t *reply = xcb_xinerama_query_screens_reply(conn, cookie, &err); if (err) { LOG_ERROR("Error %d while querying xinerama.", err->error_code); return false; } int length = xcb_xinerama_query_screens_screen_info_length(reply); xcb_xinerama_screen_info_iterator_t iter = xcb_xinerama_query_screens_screen_info_iterator(reply); int id = 0; char idbuf[5]; if (!length) { LOG_ERROR("No screen found using xinerama."); return false; } else { while (length--) { screen = iter.data; Screen s; sprintf(idbuf, "%d", id); s.setName(std::string("Xinerama-") + idbuf); s.setX(screen->x_org); s.setY(screen->y_org); s.setWidth(screen->width); s.setHeight(screen->height); updateScreen(s); xcb_xinerama_screen_info_next(&iter); } } return true; }
/* @brief Attempts to find secondary displays and updates settings.screen_* data * with the dimensions of the found screens. * * Note: failure is somewhat expected and is handled by simply using the default * xcb screen's dimension parameters. * * @param connection A connection to the Xorg server. * @param screen A screen created by xcb's xcb_setup_roots function. * @return 0 on success and 1 on failure. */ static int32_t get_multiscreen_settings(xcb_connection_t *connection, xcb_screen_t *screen) { /* First check randr. */ const xcb_query_extension_reply_t *extension_reply = xcb_get_extension_data(connection, &xcb_randr_id); if (extension_reply && extension_reply->present) { debug("Found randr support, searching for displays.\n"); /* Find x, y and width, height. */ xcb_randr_get_screen_resources_current_reply_t *randr_reply = xcb_randr_get_screen_resources_current_reply(connection, xcb_randr_get_screen_resources_current(connection, screen->root), NULL); if (!randr_reply) { fprintf(stderr, "Failed to get randr set up.\n"); } else { int32_t num_outputs = xcb_randr_get_screen_resources_current_outputs_length(randr_reply); if (num_outputs < settings.screen) { fprintf(stderr, "Screen selected not found.\n"); /* Default back to the first screen. */ settings.screen = 0; } xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_current_outputs(randr_reply); uint32_t output_index = settings.screen; xcb_randr_get_output_info_reply_t *randr_output = NULL; do { if (randr_output) { free(randr_output); } randr_output = xcb_randr_get_output_info_reply(connection, xcb_randr_get_output_info(connection, outputs[output_index], XCB_CURRENT_TIME), NULL); output_index++; } while ((randr_output->connection != XCB_RANDR_CONNECTION_CONNECTED) && (output_index < num_outputs)); if (randr_output) { xcb_randr_get_crtc_info_reply_t *randr_crtc = xcb_randr_get_crtc_info_reply(connection, xcb_randr_get_crtc_info(connection, randr_output->crtc, XCB_CURRENT_TIME), NULL); if (!randr_crtc) { fprintf(stderr, "Unable to connect to randr crtc\n"); free(randr_output); free(randr_reply); goto xinerama; } settings.screen_width = randr_crtc->width; settings.screen_height = randr_crtc->height; settings.screen_x = randr_crtc->x; settings.screen_y = randr_crtc->y; debug("randr screen initialization successful, x: %u y: %u w: %u h: %u.\n", settings.screen_x, settings.screen_y, settings.screen_width, settings.screen_height); free(randr_crtc); free(randr_output); free(randr_reply); return 0; } free(randr_output); free(randr_reply); } } xinerama: debug("Did not find randr support, attempting xinerama\n"); /* Still here? Let's try xinerama! */ extension_reply = xcb_get_extension_data(connection, &xcb_xinerama_id); if (extension_reply && extension_reply->present) { debug("Found xinerama support, searching for displays.\n"); xcb_xinerama_is_active_reply_t *xinerama_is_active_reply = xcb_xinerama_is_active_reply(connection, xcb_xinerama_is_active(connection), NULL); if (xinerama_is_active_reply && xinerama_is_active_reply->state) { free(xinerama_is_active_reply); /* Find x, y and width, height. */ xcb_xinerama_query_screens_reply_t *screen_reply = xcb_xinerama_query_screens_reply(connection, xcb_xinerama_query_screens_unchecked(connection), NULL); xcb_xinerama_screen_info_iterator_t iter = xcb_xinerama_query_screens_screen_info_iterator(screen_reply); free(screen_reply); if (iter.rem < settings.screen) { fprintf(stderr, "Screen selected not found.\n"); /* Default back to the first screen. */ settings.screen = 0; } /* Jump to the appropriate screen. */ int32_t i = 0; while (i < settings.screen) { xcb_xinerama_screen_info_next(&iter); i++; } settings.screen_width = iter.data->width; settings.screen_height = iter.data->height; settings.screen_x = iter.data->x_org; settings.screen_y = iter.data->y_org; debug("xinerama screen initialization successful, x: %u y: %u w: %u h: %u.\n", settings.screen_x, settings.screen_y, settings.screen_width, settings.screen_height); return 0; } } debug("Multiscreen search failed.\n"); return 1; }