2

これまでのところ、私はすべてのモニターを持っています。モニターはスクリーンです。だから私がしたことは:

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 を取得することが重要です。xとyを取得する途中ですかxcb_get_window_attributes_cookie_tscreen->root

私はここを読んでいました - http://www.linuxhowtos.org/manpages/3/xcb_get_window_attributes_unchecked.htm - しかし、与えられたx/y座標はありませんでした。

4

1 に答える 1

6

X スクリーンではなく、モニター、つまり実際の物理デバイスのジオメトリに関心があると思います。

In that case, the root window is not what you are interested in. ここでは、基本的に 2 つの異なる点を考慮する必要があります。

  • 古いレガシーXinerama拡張機能。
  • 新しいRandR拡張機能。

あらゆる種類の詳細を照会する方法を学ぶには、これを行うプログラムを調べることをお勧めします。標準的な提案は、実際には Xinerama と RandR の両方をサポートする i3 ウィンドウ マネージャーなど、マルチヘッド セットアップをサポートするウィンドウ マネージャーであるため、両方のソース コードを確認できます。

お探しの情報は、 および に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);

*) 免責事項: 私はそのツールの作成者です。

編集:情報を最新の状態に保つことに関心がある場合は、画面変更イベントをリッスンしてから出力を再度クエリする必要があることに注意してください。

于 2016-05-03T17:50:28.840 に答える