综合了两篇博客中的例程并做一定修改,得到了基于X11 Xlib的截屏代码。
两篇博客链接分别如下:
X11 截图与鼠标事件-SkyMei777-ChinaUnix博客
xlib实现截图报错-编程语言-CSDN问答
C代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
int main(int argc, char *argv[])
{
Display *display = XOpenDisplay(NULL);
if(!display)
{
printf("XOpenDisplay failed\n");
return -1;
}
int screen_num = DefaultScreen(display);
printf("default screen_num is: %d\n", screen_num);
int screen_width = DisplayWidth(display, screen_num);
int screen_height = DisplayHeight(display, screen_num);
printf("screen_width: %d, screen_height: %d\n", screen_width, screen_height);
Window root_win = RootWindow(display, screen_num);
if(!root_win)
{
printf("can not get root window\n");
return -1;
}
Window disp_win = XCreateSimpleWindow(display, root_win, 0, 0, screen_width, screen_height, 1, 0, 0) ;
if(!disp_win)
{
printf("can not get snapshot display window\n");
return -1;
}
XMapWindow(display, disp_win);
XImage *img = XGetImage(display, root_win, 0, 0, screen_width, screen_height, ~0, ZPixmap);
XPutImage(display, disp_win, DefaultGC(display, screen_num), img, 0, 0, 0, 0, screen_width, screen_height);
char c = getchar();
//XDestroyImage(img);
XCloseDisplay(display);
printf("screen_snapshot finished\n");
return 0;
}
Makefile:
all:
gcc ./screen_snapshot.c -o screen_snapshot -lX11
第一次编译出现以下警告:
$ make
gcc ./screen_snapshot.c -o screen_snapshot -lX11
./screen_snapshot.c: In function ‘main’:
./screen_snapshot.c:41:9: warning: implicit declaration of function ‘XDestroyImage’; did you mean ‘XDestroyIC’? [-Wimplicit-function-declaration]
41 | XDestroyImage(img);
| ^~~~~~~~~~~~~
| XDestroyIC
查看/usr/include/X11/Xlib.h文件,确实并未发现有XDestroyImage相关的定义,可能是以前版本有此函数,后来被废弃了。在代码中注释掉这一句,再次编译,这次可以正常编译通过了。
编译通过后运行生成的screen_snapshot程序,如下所示:
$ ./screen_snapshot
default screen_num is: 0
screen_width: 1920, screen_height: 1080
X Error of failed request: BadMatch (invalid parameter attributes)
Major opcode of failed request: 73 (X_GetImage)
Serial number of failed request: 9
Current serial number in output stream: 9
可以看到出现了错误。实际上这个错误就是上边第2篇参考文章链接中博主“编程小海浪”遇到的问题,截图如下:
在网上搜索解决方法,发现并不只是这个代码遇到的问题,许多人说xrandr也会报这个错。解法也提了还不少,如:手动修改分辨率、修改显卡设置等。关于这些方法,我没有一一测试,只说一下我这里的情况。
我的电脑中安装的是Ubuntu 22.04,运行程序出现的问题。将同样的程序放到另外一台基于LFS的电脑系统中,运行则并没有问题,至少不报以上错误还能截屏(屏幕内容有时不正确是另外的问题)。
在此给出个人的初步分析和判断,希望哪位遇到过此问题、有经验的同仁予以关注、回复,也可以大家一起讨论:
- 可能与桌面是XOrg和wayland有关
Ubuntu下的桌面环境是wayland,如下所示:
$ echo $XDG_SESSION_TYPE
wayland
正常电脑的桌面环境是x11,如下所示:
$ echo $XDG_SESSION_TYPE
x11
- 可能与分辨率及显卡设置有关
- 可能与xorg设置有关
- 可能与内核驱动有关
具体是哪里的问题,只能随着进一步的实验测试再进行详细分析了。