Получение списка всех дисплеев Xorg
Я хотел бы знать, как я могу получить список всех дисплеев Xorg в моей системе, а также список экранов, связанных с каждым дисплеем. Я потратил некоторое время на просмотр документации Xlib, но не смог найти функцию, которая делает то, что я хочу. Предположим, что у меня нет других зависимостей, кроме ОС POSIX-жалобы и X (например, без GTK). Если то, что я прошу, невозможно предположить, что эти минимальные зависимости, то решение с использованием других библиотек в порядке.
Большое спасибо за вашу помощь!
Ответы
Ответ 1
Единственный способ узнать список дисплеев - проверить каталог /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-дисплеев, кроме этого. Я очень хотел бы знать, существует ли какая-либо лучшая альтернатива.
Ответ 2
Как и netcoder, проблема состоит из двух отдельных частей:
-
Подключение к серверу X
Процесс устанавливает соединение с сервером X с помощью XOpenDisplay()
. Соединение сбрасывается с помощью XCloseDisplay()
. Код netcoders в этом потоке - хороший пример того, как это сделать правильно.
Как упоминалось в netcoder, проблема в том, что нет надежного способа узнать, к каким X-серверам может подключиться процесс. Его код проверяет типичное место, где расположены гнезда X, /tmp/.X11-unix/
. Этот подход не работает вообще, если пользователь удаленно подключен, например, через SSH (при включенной пересылке X). В этом случае на самом деле существует только переменная среды DISPLAY
(и, возможно, некоторые файлы обмана) ~/.Xauthority
).
К сожалению, я не знаю ни одного лучшего метода. Я лично предпочитаю использовать файл конфигурации для каждого пользователя - скажем ~/.application/displays
-, где пользователь может отображать имена серверов, которые приложение должно пытаться подключить в том же формате, что и переменная среды DISPLAY
, в дополнение к по умолчанию один. Это не автоматический (код netcoder), но этот подход мне подходит лучше.
-
Поиск экранов, предоставляемых сервером X
XScreenCount()
вернет количество экранов, предоставленных сервером X, к которому в данный момент подключен процесс. Если вам нужны только размеры экрана, следуйте примеру netcoders. Для получения более подробной информации используйте XScreenOfDisplay(Display,index)
для получения указателей Screen
; 0
<= index
< XScreenCount(Display)
.
В коде C макросы ScreenCount()
и ScreenOfDisplay()
обычно более эффективны, чем фактические вызовы функций.