Linuxで個々の画面の幅/高さをプログラムで決定する(Xinerama、TwinView、および/またはBigDesktop)
-
08-07-2019 - |
質問
私はGNOMEの下で複数の画面に複数の壁紙を表示するための小さなサイドプロジェクトを開発しています(GNOME自体または他の何かによって明らかにできないこと)。その主な部分を行う方法を見つけました(好奇心for盛な人のためにImageMagickコンポーネントを使用)。構成システムを自動化しようとしています。
それを行うには、個々の画面のサイズを決定する方法が必要です。誰がそれを探すべきかのヒントをくれますか? Xサーバー自体に情報があると思いますが、私のプログラムがどのようにそれを要求できるのかわかりません。
解決
その情報を取得できる libXinerama
APIがあるようです。ただし、詳細な情報はまだ見つかりません。
一般的なX.orgプログラミング情報は、こちらにあります。 a>(PDFファイル)。 libXinerama
が提供する機能に関する情報は、にあります。ここ(マンページの多くの情報ではなく、マンページのオンラインコピー)。
Xineramaにフックされた各モニターの寸法とオフセットを取得するためにこれらの参照からホイップした小さなC ++プログラムです。 nVidia TwinViewでも機能します。現在、BigDesktopシステムでテストするためのATIカードはありませんが、それでも同様に機能すると思われます。
#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);
}
他のヒント
次のようなものを試してください
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);
}
内部的には、libXrandr APIを使用します。 Xineramaは多かれ少なかれ廃止されましたが、まだ機能しています。 RANDRは、Xで複数のモニターを処理する新しい方法です。
これはTwinViewで機能しますが、他はテストしていません:
#!/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])
常に&quot; xdpyinfo&quot;を使用します画面サイズを決定するコマンド。コマンドを実行してから、出力の2ページ目または3ページ目で次のように表示されている箇所を確認します。
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
...
このコマンドを外部で実行し、テキスト処理でディメンションを取得するか、xdpyinfoのコードをすばやくダウンロードして、その出力行を生成するためのC呼び出しをコピーできます。がんばって!