我正在尝试编写一个程序,该程序可以检测插入的外部显示器并通过 Xlib 自动启用和配置它们。我知道 XRandr 扩展允许这样做。我的问题是,如何启用我的应用程序接收 XRandr 事件?我应该使用什么事件掩码?我知道 xev 应用程序能够做到这一点。
我写了一个小的shell脚本,用xrandr配置连接的外部显示器.
# cat /home/didi/bin/monitor_autoswitcher.sh
#!/bin/bash
xrandr | grep "HDMI1 connected"
if [[ $? == 0 ]]; then
# is connected
xrandr --output HDMI1 --right-of LVDS1 --auto
else
# not connected
xrandr --output HDMI1 --auto
fi
xrandr | grep "VGA1 connected"
if [[ $? == 0 ]]; then
# is connected
xrandr --output VGA1 --right-of LVDS1 --auto
else
# not connected
xrandr --output VGA1 --auto
fi
Run Code Online (Sandbox Code Playgroud)
这样可行.现在我想让它自动触发,并发现这可以用udev完成.我试过了
udevadm monitor
Run Code Online (Sandbox Code Playgroud)
当插入外部显示输出时
KERNEL[465828.240250] change /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
UDEV [465828.243549] change /devices/pci0000:00/0000:00:02.0/drm/card0 (drm)
Run Code Online (Sandbox Code Playgroud)
插上电源时
KERNEL[465836.844209] …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Xlib 和 OpenGL 来掌握编程图形。我可以创建窗口等,但我坚持改变显示模式。
我可以使用 Xrandr 函数 ( XRRSizes、XRRRates、XRRGetScreenInfo、XRRConfigSizes)列出可用的视频模式,检查当前设置的是哪一种 ( XRRConfigCurrentConfiguration),并更改分辨率 ( XRRSetScreenConfig)。
我可以列出可用的位深度(又名颜色深度,即每像素位数)XListDepths。
我不知道如何更改给定屏幕的位深度。
我在 Xrandr 中找不到任何合适的函数来设置位深度和屏幕尺寸。它似乎对位深度完全一无所知,这真的很奇怪。我在 Xlib 文档中也找不到任何合适的函数。
所以我的问题是:
如何在 Linux 下以编程方式更改分辨率和位深度?
Xlib 库或其他地方是否有任何函数?
我知道有图形,如SDL全面的库,但我并不想使用它们作为一个依赖只是改变显示模式,因为我试图写一个最小的图形库我自己,为了学习目的.
编辑:
我想要实现的目标不一定要特别用 Xlib 或 X 来完成,但它必须与 X 优雅地合作。例如,我不想完全摆脱 X ?它对于在窗口模式下显示图形仍然很有用。但我还需要一些方法来切换到全屏模式,在这种模式下我需要完全控制视频模式:分辨率、颜色深度、刷新率以及直接访问帧缓冲区中的实际像素,而不是某种“模拟”。我认为有是一些方法来做到这一点,因为有视频游戏谁可以做到这在Linux上。
我试图找到所有显示器及其坐标(宽度w、高度h、x origin/top-left-mostx和 y origin/top-left-most y)并使用此代码,它在某些系统上运行良好。但在其他系统上,我得到错误和重复的条目。如果我测试监视器是否是镜像,我是否能够避免这些重复/错误监视器条目?如何测试它是否是镜像?
所以这是我的代码:
// start - get all monitor resolutions
var screen = XRRGetScreenResources(getXOpenDisplay(), getDefaultRootWindow(getXOpenDisplay()));
var noutputs = screen.noutput;
for (var i=noutputs-1; i>=0; i--) {
var info = XRRGetOutputInfo(getXOpenDisplay(), screen, screen.outputs[i]);
if (info.connection == RR_Connected) {
var ncrtcs = info.ncrtc;
for (var j=ncrtcs-1; j>=0; j--) {
var crtc_info = XRRGetCrtcInfo(getXOpenDisplay(), screen, infoCrtcs[j]);
console.info('screen #' + i + ' mon#' + j + ' details:', crtc_info.x, crtc_info.y, crtc_info.width, crtc_info.height);
collMonInfos.push({
x: …Run Code Online (Sandbox Code Playgroud) 我目前正在使用 Cinnamon 运行 Linux Mint 17.2。我有2台显示器。
当我在 Cinnamon 设置中将显示器设置为相邻时,鼠标在显示器之间共享的边界上自由移动,但无法逃离可见区域。
也就是说,如果我将显示器设置为仅共享角落,则鼠标有效地锁定到当前显示器并且只能通过角落逃逸到另一个显示器。
但是,将监视器设置为不相邻允许鼠标在虚拟帧缓冲区中自由漫游,包括不可见区域。
我认为 Cinnamon 设置了一些控制此行为的标志,但使用更改监视器位置xrandr具有相同的效果。
此外,即使没有窗口管理器,当我从Xorg什么都没有开始时也是一样的xterm,并且使用xrandr。
当所有显示器都相邻时,究竟是什么阻止鼠标离开可见区域? 有没有办法覆盖这种行为?
能够控制这可能很有用,例如,每次尝试单击边界附近的东西时阻止鼠标离开监视器,而无需运行一个繁忙的循环来监视鼠标并在需要时将其移回(并且不会通过使监视器相邻而使帧缓冲区大小加倍通过角落)。
有了更多的控制,它可以用来让鼠标“不愿意”离开当前窗口,或者做其他有趣的事情。至少它可以重新实现这个东西,以便它实际上可以将鼠标锁定到诸如 Chrome 浏览器或 OpenGL 游戏之类的应用程序的窗口,而不仅仅是xterm诸如此类。
现在想起来了,我什至可以尝试实现它,如果还没有实现并且我找到了相关代码。
我使用的是联想ideapad 320s。我可以在 xrandr 中看到 HDMI1 已连接,但没有图像。会不会是硬件太新了?我是否应该转向 Debian 测试看看是否有效?在 xfce4 gui 显示应用程序中,我可以看到我的 HDMI 显示器被禁用,但不知道如何启用它。另外“xrandr --output HDMI1 --auto”也没有帮助。
代码:
OS: Debian 9.1 stretch
Kernel: x86_64 Linux 4.9.0-3-amd64
Uptime: 8m
Packages: 1789
Shell: zsh 5.3.1
Resolution: 1920x1080
WM: i3
GTK Theme: Arc-Dark [GTK2/3]
Icon Theme: Tango
Font: Sans 10
CPU: Intel Core i5-7200U CPU @ 3.1GHz
GPU: Mesa DRI Intel(R) HD Graphics 620 (Kabylake GT2)
Run Code Online (Sandbox Code Playgroud) Xrandr 显示两个监视器。我想使用 xsetwacom 将所有设备移至 HDMI-0,但是底部的 xsetwacom 命令无法识别 HDMI-0
输出:
cloz@CLOZ-ELITE:~$ xrandr
Screen 0: minimum 8 x 8, current 3840 x 1080, maximum 32767 x 32767
DVI-D-0 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 477mm x 268mm
1920x1080 60.00*+
1680x1050 59.95
1280x1024 75.02 60.02
1152x864 75.00
1024x768 75.03 60.00
800x600 75.00 60.32
640x480 75.00 59.94
HDMI-0 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 530mm x 300mm
1920x1080 60.00 + 74.99* 59.94 50.00 60.00 50.04 …Run Code Online (Sandbox Code Playgroud) 我正在开发一个已经在使用xcb的项目,需要获得单个输出的分辨率而不是组合屏幕的分辨率.我可以用xcb的RandR扩展吗?如果是这样,我如何使用我的xcb_connection_t对象来执行此操作.
我试图从Qt应用程序中读取屏幕分辨率,但不使用GUI模块.
所以我尝试过使用:
xrandr |grep \* |awk '{print $1}'
Run Code Online (Sandbox Code Playgroud)
通过QProcess命令,但它显示警告并且不提供任何输出:
unknown escape sequence:'\\*'
重写它\\\*没有帮助,因为它会导致以下错误:
/usr/bin/xrandr: unrecognized option '|grep'\nTry '/usr/bin/xrandr --help' for more information.\n
我怎么解决这个问题?