XCB получает все мониторы и их координаты x, y

Пока у меня есть все мониторы. Монитор — это экран. Итак, что я сделал:

xcb_connection_t *conn;

conn = xcb_connect(NULL, NULL);

if (xcb_connection_has_error(conn)) {
  printf("Error opening display.\n");
  exit(1);
}

const xcb_setup_t* setup;
xcb_screen_t* screen;

setup = xcb_get_setup(conn);
screen = xcb_setup_roots_iterator(setup).data;
printf("Screen dimensions: %d, %d\n", screen->width_in_pixels, screen->height_in_pixels);

Это дает мне ширину и высоту. Однако очень важно, чтобы я получил x и y. Является ли выполнение xcb_get_window_attributes_cookie_t на screen->root способом получить x и y?

Я читал здесь — http://www.linuxhowtos.org/manpages/3/xcb_get_window_attributes_unchecked.htm - но координаты x/y не указаны.


xcb
person Noitidart    schedule 01.05.2016    source источник


Ответы (1)


Я предполагаю, что вас интересует геометрия мониторов, то есть реальных физических устройств, а не X-экрана.

В этом случае корневое окно — это не то, что вас интересует. Здесь нужно учитывать два основных момента:

  • Старое устаревшее расширение Xinerama.
  • Новое расширение RandR.

Чтобы узнать, как запрашивать всевозможные детали, я бы порекомендовал посмотреть программы, которые это делают. Каноническим предложением был бы оконный менеджер, который поддерживает настройки с несколькими головками, такой как оконный менеджер i3, который фактически поддерживает как Xinerama, так и RandR, поэтому вы можете посмотреть его исходный код для обоих.

Информацию, которую вы ищете, можно найти в src/randr.c и src/xinerama.c. Необходимые вызовы RandR API:

  • xcb_randr_get_screen_resources_current
  • xcb_randr_get_screen_resources_current_outputs
  • xcb_randr_get_output_info
  • xcb_randr_get_crtc_info

Последний из них предоставит вам информацию CRTC о выходе, которая включает положение и размер вывода.

Другим источником для реализации RandR может быть xedgewarp:src/randr.c*. Я включу сюда сильно сокращенный отрывок из этого исходного кода:

xcb_randr_get_screen_resources_current_reply_t *reply = xcb_randr_get_screen_resources_current_reply(
        connection, xcb_randr_get_screen_resources_current(connection, root), NULL);

xcb_timestamp_t timestamp = reply->config_timestamp;
int len = xcb_randr_get_screen_resources_current_outputs_length(reply);
xcb_randr_output_t *randr_outputs = xcb_randr_get_screen_resources_current_outputs(reply);
for (int i = 0; i < len; i++) {
    xcb_randr_get_output_info_reply_t *output = xcb_randr_get_output_info_reply(
            connection, xcb_randr_get_output_info(connection, randr_outputs[i], timestamp), NULL);
    if (output == NULL)
        continue;

    if (output->crtc == XCB_NONE || output->connection == XCB_RANDR_CONNECTION_DISCONNECTED)
        continue;

    xcb_randr_get_crtc_info_reply_t *crtc = xcb_randr_get_crtc_info_reply(connection,
            xcb_randr_get_crtc_info(connection, output->crtc, timestamp), NULL);
    fprintf(stderr, "x = %d | y = %d | w = %d | h = %d\n",
            crtc->x, crtc->y, crtc->width, crtc->height);
    FREE(crtc);
    FREE(output);
}

FREE(reply);

*) Отказ от ответственности: я являюсь автором этого инструмента.

Редактировать: обратите внимание, что вам также необходимо прослушивать события смены экрана, а затем снова запрашивать выходные данные, если вы заинтересованы в обновлении информации.

person Ingo Bürk    schedule 03.05.2016
comment
Да, xcb не очень хорошо задокументирован во многих областях, к сожалению. В большинстве случаев совершенно нормально просматривать документы для эквивалента Xlib, передача информации в xcb обычно тривиальна. Рад, что смог помочь! - person Ingo Bürk; 04.05.2016
comment
@IngoBürk Работает ли RandR с проприетарными драйверами NVIDIA и AMD в наши дни? (Производители наиболее популярных и распространенных драйверов с закрытым исходным кодом, nVidia и AMD/ATI, отказываются от поддержки RandR. Вместо этого они предпочитают предлагать свои решения, несовместимые с RandR.) linux-magazine.com/Issues/2009/106/Multi-heading-with-RandR - person ahcox; 20.01.2020
comment
Да, RandR является стандартом де-факто. - person Ingo Bürk; 20.01.2020