代码之家  ›  专栏  ›  技术社区  ›  Head Geek

在Linux中以编程方式确定单个屏幕的宽度/高度(w/xinerama、twinview和/或bigdesktop)

  •  4
  • Head Geek  · 技术社区  · 16 年前

    我正在开发一个小的侧面项目,在gnome下的多个屏幕上显示多个壁纸(很明显,gnome本身或其他任何东西都无法完成)。我已经了解了如何完成它的主要部分(出于好奇,使用ImageMagick组件);我正在尝试自动化配置系统。

    为此,我需要一种方法来确定各个屏幕的尺寸。有人能给我个提示在哪里找吗?我假设X服务器本身就有这些信息,但我不确定我的程序如何请求这些信息。

    4 回复  |  直到 11 年前
        1
  •  6
  •   Head Geek    16 年前

    看起来有一个 libXinerama 可以检索该信息的API。不过,我还没有找到关于它的任何详细信息。

    可以找到一般的x.org编程信息 here (PDF文件)。提供的功能信息 利比尼拉马 可以找到 here (一个网页的在线副本,其中没有很多信息)。

    这里是一个小型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);
    }
    
        2
  •  5
  •   Head Geek    16 年前

    尝试一下

    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中多个监视器的新方法。

        3
  •  2
  •   detrate    15 年前

    这对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])
    
        4
  •  1
  •   Brandon Rhodes    16 年前

    我总是使用“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调用。祝你好运!

    推荐文章