2012-07-06 5 views
11

Ich würde gerne wissen, wie ich eine Liste aller Xorg-Displays auf meinem System zusammen mit einer Liste von Bildschirmen für jedes Display erhalten kann. Ich habe einige Zeit damit verbracht, die Xlib-Dokumentation durchzusehen, konnte aber keine Funktion finden, die das macht, was ich möchte. Bitte gehen Sie davon aus, dass ich keine anderen Abhängigkeiten als ein POSIX-reklamiertes Betriebssystem und X (z. B. kein GTK) habe. Wenn das, was ich frage, unter Annahme dieser minimalen Abhängigkeiten nicht möglich ist, dann ist eine Lösung, die andere Bibliotheken verwendet, in Ordnung.Erhalte Liste aller Xorg Anzeigen

Vielen Dank für Ihre Hilfe!

Antwort

15

Der einzige Weg, den ich kenne, um eine Liste von Anzeigen zu erhalten, ist das Verzeichnis /tmp/.X11-unix zu überprüfen.

Sobald Sie dies tun, können Sie Xlib verwenden, um jede Anzeige für weitere Informationen abzufragen.

Per Beispiel:

#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; 
} 

die oben Laufen gibt mir diese Ausgabe mit meiner aktuellen Displays/Bildschirme:

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

nie eine bessere Möglichkeit der Auflistung X Anzeigen außer dass gefunden. Ich würde sehr gerne wissen, ob es eine bessere Alternative gibt.

+0

Es sieht aus wie die Display-Steckdosen in sein '/ usr/spool/Buchsen/X11 /' für HP-UX und '/ var/tsol/Türen/.X11-Unix /' für einige Konfigurationen von solaris. Allerdings denke ich, dass diese selten genug sind, dass man sich einfach auf '/ tmp/.X11-unix /' verlassen kann. – Azmisov

4

Wie netcoder schrieb, das Problem hat zwei Teile:

  1. Anschluss an den X-Server

    Der Prozess stellt eine Verbindung zu einem X-Server unter Verwendung von XOpenDisplay(). Die Verbindung wird mit XCloseDisplay() abgebrochen. Netcoder-Code in diesem Thread ist ein gutes Beispiel dafür, wie es richtig gemacht wird.

    Als Netcoder erwähnt, ist das Problem, dass es keinen zuverlässigen Weg gibt herauszufinden, mit welchen X-Servern ein Prozess verbunden werden kann. Sein Code überprüft den typischen Ort, an dem sich die X-Buchsen befinden, /tmp/.X11-unix/. Dieser Ansatz funktioniert nicht funktioniert überhaupt, wenn der Benutzer remote verbunden ist, zum Beispiel über SSH (mit X Forwarding aktiviert). In diesem Fall gibt es wirklich nur die DISPLAY Umgebungsvariable (und vielleicht einige Trickery wrt. ~/.Xauthority Dateien).

    Leider kenne ich auch keine bessere Methode. Ich bevorzuge persönlich eine benutzerspezifische Konfigurationsdatei - sagen wir ~/.application/displays -, in der der Benutzer die Servernamen auflisten kann, die die Anwendung versuchen soll, im gleichen Format wie die Umgebungsvariable DISPLAY zusätzlich zu der Standard-Verbindung herzustellen. Es ist nicht automatisch (netcoders Code ist), aber dieser Ansatz passt mir besser.

  2. , sich über die Bildschirme von einem X-Server bereitgestellt

    XScreenCount() wird die Anzahl der Bildschirme von dem X-Server bereitgestellt kehrt der Prozess derzeit verbunden ist. Wenn Sie nur die Bildschirmabmessungen benötigen, folgen Sie netcoders Beispiel. Verwenden Sie für weitere Informationen XScreenOfDisplay(Display,index), um die Zeiger Screen zu erhalten; 0 < = index < XScreenCount(Display).

    Im C-Code sind die Makros ScreenCount() und ScreenOfDisplay() normalerweise etwas effizienter als die eigentlichen Funktionsaufrufe.