Получение списка всех дисплеев Xorg

Я хотел бы знать, как я могу получить список всех дисплеев Xorg в моей системе, а также список экранов, связанных с каждым дисплеем. Я потратил некоторое время на просмотр документации Xlib, но не смог найти функцию, которая делает то, что я хочу. Пожалуйста, предположим, что у меня нет других зависимостей, кроме POSIX-совместимой ОС и X (например, без GTK). Если то, что я прошу, невозможно при этих минимальных зависимостях, то решение с использованием других библиотек подойдет.

Большое спасибо за Вашу помощь!


person void-pointer    schedule 06.07.2012    source источник


Ответы (2)


Единственный известный мне способ получить список дисплеев — проверить каталог /tmp/.X11-unix.

Как только вы это сделаете, вы можете использовать Xlib для запроса дополнительной информации по каждому дисплею.

Например:

#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <X11/Xlib.h>

int main(void) {
    DIR* d = opendir("/tmp/.X11-unix");

    if (d != NULL) {
        struct dirent *dr;
        while ((dr = readdir(d)) != NULL) {
            if (dr->d_name[0] != 'X')
                continue;

            char display_name[64] = ":";
            strcat(display_name, dr->d_name + 1);

            Display *disp = XOpenDisplay(display_name);
            if (disp != NULL) {
                int count = XScreenCount(disp);
                printf("Display %s has %d screens\n",
                    display_name, count);

                int i;
                for (i=0; i<count; i++)
                    printf(" %d: %dx%d\n",
                        i, XDisplayWidth(disp, i), XDisplayHeight(disp, i));

                XCloseDisplay(disp);
            }
        }
        closedir(d);
    }

    return 0;
}

Выполнение приведенного выше дает мне этот вывод с моими текущими дисплеями/экранами:

Display :0 has 1 screens
 0: 3046x1050
Display :1 has 2 screens
 0: 1366x768
 1: 1680x1050

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

person netcoder    schedule 06.07.2012
comment
Похоже, сокеты дисплея могут быть в /usr/spool/sockets/X11/ для hpux и /var/tsol/doors/.X11-unix/ для некоторых конфигураций Solaris. Хотя я думаю, что они достаточно редки, чтобы вы могли просто положиться на /tmp/.X11-unix/. - person Azmisov; 19.02.2015
comment
С помощью libx11-dev запустите gcc -o screen screen.c -L/usr/X11/lib -lX11. - person schemacs; 31.05.2021

Как писал netcoder, проблема состоит из двух отдельных частей:

  1. Подключение к X-серверу

    Процесс устанавливает соединение с X-сервером, используя XOpenDisplay(). Соединение разрывается с помощью XCloseDisplay(). Код netcoders в этой ветке — хороший пример того, как это сделать правильно.

    Как упомянул netcoder, проблема в том, что нет надежного способа узнать, к каким X-серверам может подключаться процесс. Его код проверяет типичное место, где находятся сокеты X, /tmp/.X11-unix/. Этот подход не вообще не работает, если пользователь подключен удаленно, например, через SSH (с включенной переадресацией X). В этом случае на самом деле есть только переменная окружения DISPLAY (и, возможно, некоторые хитрости с файлами ~/.Xauthority).

    К сожалению, лучшего метода я тоже не знаю. Лично я предпочитаю использовать файл конфигурации для каждого пользователя, скажем, ~/.application/displays, где пользователь может перечислить имена серверов, к которым приложение должно попытаться подключиться, в том же формате, что и переменная среды DISPLAY, в дополнение к используемому по умолчанию. Он не автоматический (код неткодера есть), но мне такой подход больше подходит.

  2. Изучение экранов, предоставляемых X-сервером

    XScreenCount() вернет количество экранов, предоставленных X-сервером, к которому в данный момент подключен процесс. Если вам нужны только размеры экрана, следуйте примеру netcoders. Для получения более подробной информации используйте XScreenOfDisplay(Display,index) для получения указателей Screen; 0 ‹= indexXScreenCount(Display).

    В коде C макросы ScreenCount() и ScreenOfDisplay() обычно немного более эффективны, чем фактические вызовы функций.

person Nominal Animal    schedule 06.07.2012