|
#include <xcb/xcb.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
|
|
// 将 BGRX 转换为 RGB |
|
static uint8_t* BGRX2RGB(const uint8_t* in, int16_t width, int32_t height) |
|
{ |
|
uint8_t* out = malloc(width * height *3); |
|
for (int16_t y = 0; y < height; y++) |
|
{ |
|
for(int16_t x = 0; x < width; x++) |
|
{ |
|
out[(y*width+x)*3] = in[(y*width+x)*4 + 2]; |
|
out[(y*width+x)*3 + 1] = in[(y*width+x)*4 + 1]; |
|
out[(y*width+x)*3 + 2] = in[(y*width+x)*4]; |
|
} |
|
} |
|
return out; |
|
} |
|
|
|
int main() |
|
{ |
|
// 建立连接 |
|
xcb_connection_t* conn = xcb_connect(NULL, NULL); |
|
|
|
// 获取 screen |
|
const xcb_setup_t* setup = xcb_get_setup(conn); |
|
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); |
|
xcb_screen_t* screen = iter.data; |
|
|
|
// 获取 root 窗口 |
|
xcb_window_t root = screen->root; |
|
|
|
// 获取屏幕的宽高 |
|
int16_t width = 0; |
|
int16_t height = 0; |
|
{ |
|
xcb_get_geometry_cookie_t cookie = xcb_get_geometry(conn, root); |
|
xcb_get_geometry_reply_t* reply = xcb_get_geometry_reply(conn, cookie, NULL); |
|
width = reply->width; |
|
height = reply->height; |
|
free(reply); |
|
} |
|
|
|
// 读取屏幕图像 |
|
uint8_t* data = NULL; |
|
{ |
|
// XCB_IMAGE_FORMAT_Z_PIXMAP 是 BGRX 格式 |
|
// 其中 plane_mask 用于过滤不需要的通道,例如 0x00ff0000 表示只保留红色通道(注意小端) |
|
xcb_get_image_cookie_t cookie = xcb_get_image(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, root, 0, 0, width, height, UINT32_MAX); |
|
xcb_get_image_reply_t* reply = xcb_get_image_reply(conn, cookie, NULL); |
|
data = BGRX2RGB(xcb_get_image_data(reply), width, height); |
|
free(reply); |
|
} |
|
|
|
FILE* fp = fopen("out.ppm", "wb"); |
|
fprintf(fp, "P6\n"); |
|
fprintf(fp, "%d %d 255\n", width, height); |
|
fwrite(data, width*height*3, 1, fp); |
|
fclose(fp); |
|
|
|
free(data); |
|
xcb_disconnect(conn); |
|
|
|
return EXIT_SUCCESS; |
|
} |