2016-05-01 1 views
0

Пока у меня есть все мониторы. Монитор - это экран. Так что я сделал: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 - но не было заданных х/у координаты.

ответ

1

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

В этом случае окно корня не то, что вы заинтересованы в Есть в основном две разных вещи, чтобы рассмотреть здесь:.

  • Старого наследие Xinerama расширения.
  • Новее RandR расширение.

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

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

  • 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); 

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

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

+0

О, черт возьми, спасибо! Вот как я это делал сейчас, я использовал Xrandr из потока, но я слышал, что он не является потокобезопасным, поэтому я хотел переключить все на xcb. Это поможет мне больше, чем вам! https://github.com/Noitidart/NativeShot/blob/master/modules/screenshot/ScreenshotWorker.js#L1505-L1530 документы на этом материале xcb, который я не смог найти, спасибо очень много за это! – Noitidart

+1

Да, xcb, к сожалению, плохо документирован во многих областях. В большинстве случаев отлично смотреть на документы для эквивалента Xlib, поэтому передача информации в xcb обычно тривиальна. Рад, что смог помочь! –