تحديد برمجيا الفردية الشاشة بعرض / المرتفعات في لينكس (ث / زينيراما، TwinView، و / أو BigDesktop)
-
08-07-2019 - |
سؤال
وأنا وضع قليلا الجانبية مشروع لعرضه خلفيات متعددة على شاشات متعددة تحت GNOME (وهو ما يبدو لا يمكن أن تقوم به GNOME نفسه أو أي شيء آخر). لقد برزت كيفية القيام الجزء الرئيسي منه (باستخدام مكونات يماغيماغيك، لافتة)؛ أنا أحاول أن أتمتة نظام التكوين.
لفعل ذلك، وأنا بحاجة إلى وسيلة لتحديد أبعاد شاشات الفردية. يمكن لأي شخص أن تعطيني تلميحا أن ننظر فيها لذلك؟ أفترض خادم X نفسها لديه من المعلومات، ولكن لست متأكدا كيف برنامجي يمكن أن نطلب لذلك.
المحلول
<الإضراب> يبدو ان هناك API libXinerama
التي يمكن استرداد تلك المعلومات. لم أجد أي معلومات مفصلة عن ذلك على الرغم من بعد. إضراب>
هنا و> (ملف PDF). ويمكن الاطلاع على معلومات عن الوظائف التي توفرها libXinerama
هنا (الانترنت نسخة من manpage، ليس هناك الكثير من المعلومات في ذلك).
وهنا برنامج صغير C ++ أنني جلد حتى من هذه المراجع لاسترداد أبعاد وإزاحة كل من المراقبين التوصيل إلى زينيراما. كما أنها تعمل لنفيديا TwinView. ليس لدي حاليا بطاقة ATI لاختباره على النظام BigDesktop، ولكن أظن انها ستعمل على أنها كذلك.
#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);
}
وعلى الصعيد الداخلي هذا يستخدم API libXrandr. زينيراما هو أكثر أو أقل إهمال، ولكن لا يزال يعمل. 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])
وأنا دائما استخدام "xdpyinfo" الأمر لتحديد حجم الشاشة؛ قم بتشغيل الأمر، ثم ننظر في الصفحة الثانية أو الثالثة من الانتاج لحيث تقول شيئا مثل:
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 يدعو أن يجعل لإنتاج هذا الخط من الإنتاج. حظا سعيدا!