寫支 C 程式用 XRandr Extension 設定你的螢幕解析度
在 X11 下取得螢幕顯示大小,最快的方式就是得到當前的 Screen ,然後用 DisplayWidth() 和 DisplayHeight() 得到寬高,如果是在高階的圖形介面架構下開發應用程式,如:GTK+,也有相關的 API 可以取得 display 的大小。然而,要是我們想取得更多關於螢幕和顯示晶片所支援的模式,便要引入 XRandr Extension 來達成。
若不了解 XRandr 是什麼,可以開啟終端機(Terminal)程式,接著輸入 xrandr 指令,就會看到顯示器的相關訊息,除了可以得到有幾種螢幕可以用,還分別可以看到支援的模式(解析度和掃描頻率),以下是在筆者 X200t (有外接一台支援 1920x1080 的 24" 顯示器)上執行的結果:
註:Xrandr 除了得到關於當前顯示器的設定之外,也可以設定現在的模式,更多功能可以參考『xrandr --help』的說明。
當然,XRandr Extension 還支援旋轉畫面、多螢幕顯示等控制,不過不在本文討論範疇。這裡,我們要用 C 語言先來實作一支程式,用 XRandr API 得到目前解析度以及列出顯示器支援的所有模式。
listmode.c 完整程式碼:
編譯:
執行結果(在筆者電腦上 1920x1080 60Hz 為當前的解析度模式):
若要更進一步更改和設定模式,可在範例程式碼最後加上 RRSetScreenConfigAndRate():
註:其中 SizeID 型態指的是模式的編號,同列表中最前面的編號,可擇一使用。
若不了解 XRandr 是什麼,可以開啟終端機(Terminal)程式,接著輸入 xrandr 指令,就會看到顯示器的相關訊息,除了可以得到有幾種螢幕可以用,還分別可以看到支援的模式(解析度和掃描頻率),以下是在筆者 X200t (有外接一台支援 1920x1080 的 24" 顯示器)上執行的結果:
$ xrandr Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 8192 x 8192 VGA1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 531mm x 299mm 1920x1080 60.0*+ 60.0 60.0 1440x900 59.9 1280x800 59.8 1152x864 75.0 1024x768 70.1 60.0 800x600 60.3 56.2 640x480 66.7 60.0 720x400 70.1 LVDS1 connected (normal left inverted right x axis y axis) 1280x800 60.0 + 1024x768 60.0 800x600 60.3 56.2 640x480 59.9 HDMI1 disconnected (normal left inverted right x axis y axis) DP1 disconnected (normal left inverted right x axis y axis) HDMI2 disconnected (normal left inverted right x axis y axis) DP2 disconnected (normal left inverted right x axis y axis) DP3 disconnected (normal left inverted right x axis y axis)
當然,XRandr Extension 還支援旋轉畫面、多螢幕顯示等控制,不過不在本文討論範疇。這裡,我們要用 C 語言先來實作一支程式,用 XRandr API 得到目前解析度以及列出顯示器支援的所有模式。
listmode.c 完整程式碼:
#include <stdio.h> #include <X11/X.h> #include <X11/extensions/Xrandr.h> void main() { XRRScreenSize *sizes; XRRScreenConfiguration *sc; int nsize; short rate; Rotation current_rotation; SizeID size_id; int i; Display *dpy = XOpenDisplay(NULL); int screen = DefaultScreen(dpy); Window root = RootWindow(dpy, screen); /* Get XRandr Screen Configuration */ sc = XRRGetScreenInfo(dpy, root); /* Get all Modes of Screen */ sizes = XRRConfigSizes(sc, &nsize); printf("nsize: %d\n", nsize); /* Get Current Rate */ rate = XRRConfigCurrentRate(sc); printf("rate: %d\n", rate); /* Get current mode ID and rotation config */ size_id = XRRConfigCurrentConfiguration(sc, ¤t_rotation); printf("size id: %d\n", size_id); for (i = 0; i < nsize; i++) { if (size_id == i) printf("%d %dx%d *\n", i, sizes[size_id].width, sizes[size_id].height); else printf("%d %dx%d\n", i, sizes[i].width, sizes[i].height); } }
編譯:
gcc -o listmode listmode.c -lX11 -lXrandr
執行結果(在筆者電腦上 1920x1080 60Hz 為當前的解析度模式):
$ ./listmode nsize: 8 rate: 60 size id: 0 0 1920x1080 * 1 1440x900 2 1280x800 3 1152x864 4 1024x768 5 800x600 6 640x480 7 720x400
若要更進一步更改和設定模式,可在範例程式碼最後加上 RRSetScreenConfigAndRate():
XRRSetScreenConfigAndRate(dpy, sc, root, (SizeID)0, current_rotation, rate, CurrentTime);
留言
張貼留言