Programmgesteuertes Bestimmung einzelne Rasterweiten / Höhen in Linux (w / Xinerama, Twinview, und / oder BigDesktop)

StackOverflow https://stackoverflow.com/questions/836086

Frage

Ich entwickle ein kleines Nebenprojekt mehrere Hintergrundbilder auf mehreren Bildschirmen unter GNOME angezeigt werden (etwas, das offenbar nicht von GNOME selbst oder irgendetwas anderes getan werden). Ich habe herausgefunden, wie der Hauptteil, es zu tun (die ImageMagick Komponenten, für Neugierige); Ich versuche, das Konfigurationssystem zu automatisieren.

Um das zu tun, ich eine Möglichkeit brauchen, sind die Abmessungen der einzelnen Bildschirme zu bestimmen. Kann mir jemand einen Tipp geben, wo für das aussehen? Ich nehme an dem X-Server selbst die Informationen hat, aber ich bin nicht sicher, wie mein Programm kann danach fragen.

War es hilfreich?

Lösung

Es sieht aus wie ein libXinerama API ist, dass diese Informationen abrufen können. Ich habe keine detaillierten Informationen über sie noch, obwohl gefunden.

Allgemeine X.org-Programmierung Informationen zu finden sind hier (PDF-Datei). Informationen über die von libXinerama bereitgestellten Funktionen können hier (online finden Kopie eines manpage, nicht viele Informationen drin).

Hier ist ein kleines C ++ Programm, das ich aus diesen Referenzen gepeitscht bis zu den Abmessungen und Versetzungen von jedem der Monitore in Xinerama verhakt abzurufen. Es funktioniert auch für nVidia Twinview; Ich derzeit keine ATI-Karte habe es auf ihrem BigDesktop System zu testen, aber ich vermute, es würde auch daran arbeiten.

#include <cstdlib>
#include <iostream>

#include <X11/extensions/Xinerama.h>

using std::cout;
using std::endl;

int main(int argc, char *argv[]) {
    bool success=false;
    Display *d=XOpenDisplay(NULL);
    if (d) {
        int dummy1, dummy2;
        if (XineramaQueryExtension(d, &dummy1, &dummy2)) {
            if (XineramaIsActive(d)) {
                int heads=0;
                XineramaScreenInfo *p=XineramaQueryScreens(d, &heads);
                if (heads>0) {
                    for (int x=0; x<heads; ++x)
                        cout << "Head " << x+1 << " of " << heads << ": " <<
                            p[x].width << "x" << p[x].height << " at " <<
                            p[x].x_org << "," << p[x].y_org << endl;
                    success=true;
                } else cout << "XineramaQueryScreens says there aren't any" << endl;
                XFree(p);
            } else cout << "Xinerama not active" << endl;
        } else cout << "No Xinerama extension" << endl;
        XCloseDisplay(d);
    } else cout << "Can't open display" << endl;

    return (success ? EXIT_SUCCESS : EXIT_FAILURE);
}

Andere Tipps

Versuchen Sie so etwas wie

GdkScreen *screen;
int num_monitors;
int i;

screen = gdk_screen_get_default ();
num_monitors = gdk_screen_get_n_monitors ();

for (i = 0; i < num_monitors; i++) {
    GdkRectangle rect;

    gdk_screen_get_monitor_geometry (screen, i, &rect);
    printf ("monitor %d: offsets (%d, %d), size (%d, %d)\n",
        i,
        rect.x, rect.y,
        rect.width, rect.height);
}

Intern diese verwendet die libxrandr API. Xinerama ist mehr oder weniger veraltet, aber immer noch funktioniert; RANDR ist die neue Art und Weise mehrere Monitore in X zu behandeln.

Dies funktioniert für Twinview, ich habe die andere nicht getestet:

#!/usr/bin/python
# Print some information about the X environment, the monitor setup, currently active window and cursor position
import gtk.gdk

screen = gtk.gdk.screen_get_default()
print "X default screen size: %d x %d" % (screen.get_width(), screen.get_height())
print "xid of root window: %d" % screen.get_root_window().xid

monitors = int(screen.get_n_monitors())
print "== %d monitors ==" % monitors
for m in range(0, monitors):
    print " - geometry of monitor %d: %s" % (m, screen.get_monitor_geometry(m))

window = screen.get_active_window()
win_x, win_y, win_w, win_h, win_bit_depth = window.get_geometry()
print "active window on monitor: %d" % screen.get_monitor_at_point((win_x+(win_w/2)),(win_y+(win_h/2)))
print "window geometry (x,y,w,h): %d, %d, %d, %d" % (win_x,win_y,win_w,win_h)

display = gtk.gdk.display_get_default()
pointer = display.get_pointer()
print "cursor position (x, y): %d, %d" % (pointer[1], pointer[2])
print "cursor on monitor: %d" % screen.get_monitor_at_point(pointer[1],pointer[2])

Ich benutze immer den „xdpyinfo“ Befehl, um die Bildschirmgröße zu bestimmen; Führen Sie den Befehl, dann sehen Sie die zweite oder dritte Seite der Ausgabe für sagt, wo es so etwas wie:

screen #0:
  dimensions:    1280x800 pixels (339x212 millimeters)
  resolution:    96x96 dots per inch
  depths (7):    24, 1, 4, 8, 15, 16, 32
  root window id:    0xac
  depth of root window:    24 planes
  ...

Sie können entweder diesen Befehl von außen und die Abmessungen über Textverarbeitung greifen, oder Sie könnten schnell xdpyinfo Code herunterladen und kopieren Sie die C-Aufrufe, dass sie diese Zeile der Ausgabe zu produzieren macht. Viel Glück!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top